flexBASIC COG(cpu) crash
in Propeller 2
I am having a problem with my sub data_log COG(cpu), when I run the program it seems to be crashing the program, I think.
I am not sure what is creating the program crash, is it something in the data_log cpu or is it somewhere else. Not even sure as to how to setup a debug to check this out. Maybe somebody can spot the problem, that I am missing.
Thanks
Ray
' solsta5.bas ' ' Oct 11, 2021 dim rpi as class using "spin/SmartSerial.spin" dim adc_ez as class using "jm_analog_in.spin2" '' Comms ''Connect to the Raspberry Pi 4 rpi.startx(1,0,0,115200) Open SendRecvDevice(@rpi.tx,@rpi.rx) as #2 const HEAPSIZE = 8192 '' Filesystem mount "/host", _vfs_open_host() '' Variables dim inBuff as string dim shared dlc% dim shared val1#,val2#,val3#,val4# dim shared test#,test1#,test2#,test3#,test4# ' Time dim as ubyte hours, mins, secs ' Date dim shared as ubyte MM, DD dim shared as integer YYYY dim s$ dim shared date as string dim shared timeit as string dim shared time as string dim shared startt as string dim shared datet as string dim shared a%, b%, c% dlc% = 0 '' Stack dim stack_dl(512) dim stack_external_sensors(256) dim td_stack(10) '' Main var a = cpu(data_log(),@stack_dl(1)) var b = cpu(external_sensors(),@stack_external_sensors(1)) do print #2, "> "; input #2, inBuff if inBuff = "startlog" then dlc% = 1 else if inBuff = "stoplog" then dlc% = 0 else if inBuff = "setclock" then input #2, "Enter year month day as YYYY-MM-DD ", s$ YYYY = val(left$(s$, 4)) MM = val(mid$(s$, 6, 2)) DD = val(right$(s$, 2)) input #2, "Enter time as hh:mm:ss ", s$ hours = val(left$(s$, 2)) mins = val(mid$(s$, 4, 2)) secs = val(right$(s$, 2)) pausems 250 var x = cpu(updateClock, @td_stack(1)) else if inBuff = "date" then print #2, "New Date (y)"; input #2, inBuff if inBuff = "y" then input #2, "Enter year month day as YYYY-MM-DD ", s$ YYYY = val(left$(s$, 4)) MM = val(mid$(s$, 6, 2)) DD = val(right$(s$, 2)) else print #2, using "%%/%%/####"; MM; DD; YYYY end if else if inBuff = "time" then print #2, "New Time (y)"; input #2, inBuff if inBuff = "y" then input #2, "Enter time as hh:mm:ss ", s$ hours = val(left$(s$, 2)) mins = val(mid$(s$, 4, 2)) secs = val(right$(s$, 2)) else print #2, using "##:%%:%%"; hours, mins, secs end if else print #2, "??" end if loop print #2, "program Ended!" close #2 close #3 end '''''''''''''''''''' sub data_log() do ' Check to see if dlc% is on=1 or off=0 if dlc% = 1 then open "/host/solsta.csv" for append as #3 print #3, using "%%/%%/####,"; MM, DD, YYYY; print #3, using "##:%%:%%,"; hours, mins, secs; print #3, "BA, "; print #3, val1# close #3 open "/host/solsta.csv" for append as #3 print #3, using "%%/%%/####,"; MM, DD, YYYY; print #3, using "##:%%:%%,"; hours, mins, secs; print #3, "P1, "; print #3, val3# close #3 pausems 1000 end if pausems 1000 loop end sub '''''''''''''''''''' sub external_sensors() 'a% = 1 do 'b% = a%+b% 'pausems 1000 ' Battery array adc_ez.start(8, 0, 100) '' This uses P9 pausems 250 test# = (adc_ez.readit()/1) test1# = ((test# * 3.3)/100) val1# = (test1# * 5.04597) ' DC power adc_ez.start(9, 0, 100) '' This uses P9 pausems 250 test3# = (adc_ez.readit()/1) test2# = ((test3# * 3.3)/100) val3# = (test2# * 5.25291) loop end sub '''''''''''''''''''' '' Helper subroutine; return number of days in month. '' function daysInMonth() as uinteger ' february special case if MM = 2 then if (YYYY mod 4 = 0) then if (YYYY mod 100 <> 0) or (YYYY mod 1000 = 0) then return 29 endif endif return 28 endif if (MM = 4) or (MM=6) or (MM=9) or (MM=11) return 30 return 31 end function '''''''''''''''''''' ' cpu (COG) '' Routine to keep the clock up to date. '' sub updateClock dim nextSecond dim FREQUENCY FREQUENCY = clkfreq nextSecond = getcnt() + FREQUENCY do waitcnt(nextSecond) nextSecond = nextSecond + FREQUENCY secs = secs + 1 if (secs >= 60) then secs = 0 mins = mins + 1 if (mins >= 60) then mins = 0 hours = hours + 1 if (hours >= 24) then hours = 0 DD = DD + 1 endif endif endif if (DD > daysInMonth()) then DD = 1 MM = MM + 1 if (MM > 12) then MM = 1 YYYY = YYYY + 1 endif endif loop end sub ''''''''''''''''''''
solsta.csv
10/11/2021, 9:23:07,BA, 13.155 10/11/2021, 9:23:07,P1, 13.348 10/11/2021, 9:23:09,BA, 13.155 10/11/2021, 9:23:09,P1, 13.348 10/11/2021, 9:23:11,BA, 13.155 10/11/2021, 9:23:11,P1, 13.348 10/11/2021, 9:23:13,BA, 13.155 10/11/2021, 9:23:13,P1, 13.348 10/11/2021, 9:23:16,BA, 13.155 10/11/2021, 9:23:16,P1, 13.521 10/11/2021, 9:23:18,BA, 13.155 10/11/2021, 9:23:18,P1, 13.521 10/11/2021, 9:23:20,BA, 13.155 10/11/2021, 9:23:20,P1, 13.348 10/11/2021, 9:23:22,BA, 13.155 10/11/2021, 9:23:22,P1, 13.348 10/11/2021, 9:23:24,BA, 13.155 10/11/2021, 9:23:24,P1, 13.521 10/11/2021, 9:23:26,BA, 13.155 10/11/2021, 9:23:26,P1, 13.348
Comments
As a quick and dirty test, bump all of the stacks up to 2048 and see if that changes the crash behavior. Remember that there is no protection whatsoever for any variables at runtime. If you fall off the end of an array, stack, etc, you’ll be tromping on your neighboring code/data… with predictably unpredictable results.
Also: make sure that you are compiling with optimization set to “Default” initially. I see odd things happening in large programs using calls to CPU() sometimes unless “Default” is selected.
You are running out of cogs.
You periodically start UpdateClock() in a new cog but that sub never terminates. Its stuck in a DO:LOOP forever. Thats one of the problems.
I get this feeling that something changed with flexBASIC.
Back on Feb 01, 2021 I wrote solsta2.bas, which ran flawlessly on whatever version of flexBASIC was at that time. Today, for the heck of it, I compiled and ran solsta2.bas on the latest version of flexBASIC, the program crashed as soon as I typed in setclock. So something is going on, which I cannot get a handle on.
I will try to isolate the problem somehow, but I am at loss as to how that will be.
Ray
Just printout what the CPU(Setclock()) returns for starters.
You might work on coding style too. Consistency is really key. Have a standard format and stick to it. Some ideas:
Declare variables in one syntax style only, and put everything together at the top of the file (unless the vars are local to a function/sub), Eg
Dim a,b,c as ulong
Dim w,x,y as byte
Dim s as string
Use OPTION EXPLICIT at the top to force you to formally declare variables.
Use an overall template for your programs that will help you to enforce organized code. This is how I do it, in order:
Compiler stuff first (HEAPSIZE, clkfreq, etc)
CONSTants
INCLUDEd files
Class definitions (structs)
Class assignments
Module-level variables
Main body
FUNCTIONs/SUBs
Also, dont use SHARED where you dont need it. Anything declared in the top-level can be seen by all of the SUBs/FUNCTIONs in that module unless you override them.
Adopt naming conventions. I use caps to identify constants, all lower case to show a local variable, etc. Whatever works for you, just make a standard and stick to it. Ideally, anyone should be able to pickup hour code and run with it. See some of JonnyMac’s spincode for good examples of disciplined coding.
EDIT: Would you post the smartpin and ADC libs you are using? I'm going to play with this a bit and see what I can break.![:) :)](https://forums.parallax.com/resources/emoji/smile.png)
I am not making any serious headway on this. I attached the ADC file that I am using, not sure what happened to the DHT file.
Ray
I've got your code up and and am looking at it.
Is there any reason why sub external_sensors() and sub data_log() are running in a different cog? These should be easily called in-line in the same cog everything else is running in. What was the logic of putting them in a different cog?
EDIT: Too many questions to ask here. PM sent. Call me!
EDIT2: And... after some mischief and restructuring, it seems to work.
As an aside, I have to ask: why do you input the date in ISO 8601 format, but then mangle it into North American format for logging and display?
I echo the suggestion of consistency, even in the date format.
@Rsadeika I don't have a Raspberry PI, or anything connected as an analog signal source, so some mischief has been necessary to debug your code. (I totally mangled your code into something that is now driven by the command line). The BAS file is attached. It works. And it knows about a few commands:
Boot this up and play a bit.
The logging doesn't get its own cog. No need really. I have it so that it logs the analog inputs every second if logging is enabled. Season to taste. I re-directed logging to the console for debugging ease. Easy to change this to a disk file. I also redirected the "command line" input from the RPI to the console as well, so we can "talk" to it over the console. Again, easy to change
I'm putting this out there mostly as a demonstration program for you. I have no doubt that it doesn't do what you wanted, but I never really understood what this critter was attached to or was designed to do, and I cant replicate your dev environment. All I can see is that your original program logs data to a disk file... and I went from there. All of the basics are here for logging data, changing date/time, turning logging on/off. You can probably fill-in the rest.
Have fun!
Thanks jRoark, I will have a look at what you came up with, later today.
As for the date format, the csv file that is created is used by my SQLite program. My date format works well with SQLite, although I might have to look into a possible change. I usually go with what works for me.
Thanks
Ray
JRoark, I had a quick look at your program, it looks really good, like a finalized product. I picked up on a couple things that you were doing, which I did not think of. Good work.
My brain works way differently, I start out with a prototyping mind set, I try to create a general functioning program idea, where I have tested all the necessary parts to make sure that everything works, then I go through a gradual finalization process.
My general setup, I have the P2 Edge connected to my Raspberry Pi 4, I log into the RPi remotely too program the P2, using flexBASIC.
This session is being held up with to many "wait" interuwill have to finish later.
Thanks for the kind words, @Rsadeika It was fun to tweak on this code for a bit. You were pretty well along the path to having this fixed... I just made a few organizational tweaks and cleaned-up the user input side of things.
So is the RPi is basically acting as a terminal interface for you? In other words, can you eliminate the RPi temporarily until you get the P2 bits working (ie, talk directly to the P2 for dev purposes), and then bring the RPi back into the loop?
I noticed that shared is still listed as a keyword, but I do not see any explanation for what it is or does.
Since I will be running data_log() and external_sensors() in separate cogs, for now, I tested out my idea of using dlc% variable as a global to activate/deactivate a procedure in another cog. It seems that this is my problem, it is freezing up my program when I do this. Not sure of what shared is doing to a variable.
Ray
Below is my latest idea, I have it set for Full Optimization. The program below runs for about 20 seconds, then I get a crash, as shown below in the propflex terminal window.
This one is a new one on me.
Ray
flexprop terminal
@Rsadeika You probably noticed that I put external_sensors() into its own cog, and that it calls data_log() as a SUB. IMHO, this is the way it should be. Data_log() shouldn't be in it's own cog. The only time data_log() runs is when it is triggered by external_sensors(), and there isn't any reason to spend a cog on this. Nothing here is happening quickly or trying to track a fast external event. So I'd seriously consider rolling data_log() inline right into external_sensors() since they are so tightly coupled. Just make it simple, linear code. Decoupling these two SUBs just invites error.
In the code I posted there are only three cogs total running, and even this is fairly wasteful:
- cog0: main body code
- cog1: external_sensors()
- cog2: updateClock()
You could save a cog by rolling updateClock() into the external_sensors() sub without much trouble. Just fire it off the same timer tick (from GetSec()) that triggers the ADC operations and Bob's yer uncle. If you really wanted to flatten it down to a single cog, you could do it as long as you got away from using INPUT and build a buffer manually using rapid calls to _rxraw() from the C library.
As to SHARED, take a hard look at the FlexBASIC docs. The explanation you seek starts at the bottom of page 11, and continues onto page 12. There is even some example code to play with. But all that being said, there isn't any reason to use SHARED in your solsta5.bas code. Normal member variables can do it all.
I sure am missing an index, as the FlexBASIC Language Reference starts to get bigger and bigger.
I guess I will have to see what I can come up by placing the data_log() into external_sensors(). This will probably change my vision of the program somewhat.
Ray
I use the pdf version and do a word search, but you can also just click on the items in the table of contents.
See my code. It calls data_log() as a sub. Just delete that one line and copy-paste the contents of data_log() right to there. Note this is really just semantics. The compiler will produce mostly the same code anyway, albeit there is a small overhead in any call to a sub/function that will be eliminated by in-lining.
@Rsadeika I cut-and-pasted your code from #15 and modified it just enough so I can get feedback to see that it is running. It has been running for two hours here. All of the cogs are doing their thing. This is all on the RPi end. Since I don't have any way to debug that, I'm sorta out of help options.
Parting thought: If you want to put the logged data on the P2 you can do that just by changing the MOUNT and OPEN arguments to use the P2 SD card.
Edited to add: Your code doesn't do any error checking during the MOUNT, OPENs or PRINTs, which means if anything gets broken in the file system, the code will crash. You might take a peek at CATCH/TRY to cure this issue and allow errors to be handled gracefully.
I think I narrowed down the problem. It looks like flexBASIC is having problems with jm_analog_in.spin2. Everything compiles, without errors, so I cannot be sure about my assumption.
When I run jm_analog_in.spin2, as a simple sub, it hangs, meaning it is waiting for some input of a value, which it is not receiving. Because this particular program uses the smart pin functionality. I guess Eric will have to verify this.
Ray
Are you using the current compiler version?
Yes, version 5.9.3. I believe I just did an update, last week, I believe.
Ray
I think I am starting to have hardware problems, not sure if it is my P2 Edge, or something else.
Has anybody created a diagnostic program for checking the functionality of the P2 Edge card? Is that even possible.
Ray
You might do a quick little program that wiggles each output pin in the 0-59 range every second so you can see (grossly) if anything is stuck. Most everything else gets "proven" by the fact the program runs. Something like:
Anybody know what this means:
The program stops, and this message appears. Does this have something to do with 'mount "/host", _vfs_open_host()' function.
Ray
That means that there was a communication problem between the program and loadp2 while doing some kind of file operation. Could there be a problem with the serial connection to your board?
I have a connection to a Raspberry Pi, I get the feeling that maybe there is a problem with the RPi not handling the 'mount "/host", _vfs_open_host()' correctly.
Ray
@Rsadeika Can you temporarily dump the RPi for a full-blown Win or Unix-type box just for troubleshooting?
It would not be an apples to apples comparison.
My setup right now, form the P2 Edge I have a connection to the RPi USB, and I have a connection to the GPIO Tx and Rx pins. There might be something going on with the 'mount "/host", _vfs_open_host()' to the RPi GPIO Tx,Rx. Not sure about that, do not know how to debug that part.
I was hoping maybe to eliminate the Rpi and have the WiFi module plugged into the P2 Edge, and then be able the have flexBASIC using an ftp style to move a file from the P2 Edge to my Linux server box, or any other machine. Now that would be a very good use of flexBASIC and the P2 Edge.
Ray
I understand that you have a connection, but the bug seems to indicate that the connection isn't reliable, that some data is being lost between the P2 and the RPi. Can you try a lower baud rate? It could be that the RPi can't keep up.
True, but you could at least validate the codebase on the P2 and eliminate it as a problem.
I personally think the RPi needs to go. Its sorta in the way.
You and I may learn the nuances of wireless adapters about the same time since I'm about to start playing with one of these too. I'm hoping to do it all in FlexBASIC.