Method calls failing.....
I am having a huge problem with method calls working sometimes and crashing the code other times.· Below are the Objects I am using and the Variables I am using.· I have put in precations to prevent going outside my array values so i know that is not the case.· Sometimes if i change a method from public to private it will work.· But some other method will fail.· I can get the loop to work perfectly one time and then the second time around a method will fail and the software will crash.
I am using...
·········LED···· : "uOLED_Small"
········ GPS····: "GPS_IO_mini_PNAV"
········ Debug : "FullduplexSerial"·
········ Comm· : "FullduplexSerial"
········ FS····· : "Floatstring"
········ FP···· ·:· "Float32Full"
········ num··· :· "Numbers"
Variables
·long TMN
long TMCNTd
long TMCNTs
long TMS
Long TMCNTn
long TMD
long Count·
long Heading
byte buttons[noparse][[/noparse]1]
long stat911
byte BFTMode[noparse][[/noparse]1]··· 'N for Navigation , S for standard(Sleep)· E for emergency
byte Separation[noparse][[/noparse]1]
byte latitude[noparse][[/noparse]35]
byte longitude[noparse][[/noparse]35]·
byte lat[noparse][[/noparse]35]
byte lng[noparse][[/noparse]35]
byte answer[noparse][[/noparse]4]
byte Serial[noparse][[/noparse]10]
long lats
long lngs
long wlngs
long wlats
long TmCnt911
Long Tm911
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
I am using...
·········LED···· : "uOLED_Small"
········ GPS····: "GPS_IO_mini_PNAV"
········ Debug : "FullduplexSerial"·
········ Comm· : "FullduplexSerial"
········ FS····· : "Floatstring"
········ FP···· ·:· "Float32Full"
········ num··· :· "Numbers"
Variables
·long TMN
long TMCNTd
long TMCNTs
long TMS
Long TMCNTn
long TMD
long Count·
long Heading
byte buttons[noparse][[/noparse]1]
long stat911
byte BFTMode[noparse][[/noparse]1]··· 'N for Navigation , S for standard(Sleep)· E for emergency
byte Separation[noparse][[/noparse]1]
byte latitude[noparse][[/noparse]35]
byte longitude[noparse][[/noparse]35]·
byte lat[noparse][[/noparse]35]
byte lng[noparse][[/noparse]35]
byte answer[noparse][[/noparse]4]
byte Serial[noparse][[/noparse]10]
long lats
long lngs
long wlngs
long wlats
long TmCnt911
Long Tm911
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle

Comments
This is the second thread you've begun on the selfsame topic in as many days. It would be helpful if you could respond to comments/suggestions in yesterday's thread rather than starting over. For example, did you check out any stack allocation issues that might exist? Did it help?
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
Nothing that you've said is very helpful in sorting this kind of thing out. This is the sort of thing that only painstaking tracing and debugging output will help narrow it down to the area of the program involved and the state of the program when the problem occurs.
Although things are never "impossible", it is very unlikely that the problem has anything to do with the compiler or the interpreter or the library objects. You may have checks for subscripts out of range or invalid pointers, but it's very difficult to separate out what you intended for the program to do vs. what you actually coded.
Post Edited (Mike Green) : 9/19/2008 9:14:25 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
it's true what Mike says:
if you want to narrow down the problem you have to check EVERY single line which uses OR changes an array-value and other lines of code
looking through the code guessing "- no there it isn't " - makes you run over the interessting point a thousand times until you decide to check it too
to make it faster to find the place make lines of code that check array-boundaries and if the boundaries are broken send a debugstring with information of
which method which line of code inside the method
As you refuse to send your complete code you have to do most of the work yourself
Did you increase stackspace always for one object and then test again ?
then increase stackspace for the next object and test again ?
did you check every parameter is treated as long
every result given back from methods is a long
all local variables are longs
another way of narrow it down is to comment out one object
if results processed by this object is needed many times in other objects
make a constant dummyresult instead
this all is NOT "just add three lines of code and we will find it"
but as complex as yor project is the effort to find the fault has its size
In general for developing software in the long run a strictly modular style of programming pays off
by much lesser time spend on debugging.
This means: every method does ONE senseful thing
use parameters instead of global variables whereever possible
Be careful about changing global variables
especially if more than one cog changes tis variable
then the order of the setting of a variable can vary a lot
if YOU think this method in cog 1 will be always finished before cog 2
is doing something with it I bet this is NOT true in the long run.
there will be crossover changing the value
You can avoid this be using semaphores and locks
In my former company i was coding in delphi for maschinecontrols
We used a strictly sequential way of code-execution for critical sections to make 100% sure
that things will be executed in the order we wanted it to
this makes it much easier to track on errors
We coded so called statemachines to realize that
test every method of this style on it's own
test the behaviour if it with VERY strange parameters
test it with zero, test it with 254, 255, 65535, 65536 with 2^32 2^32-1 test it with -100
etc. etc. if an error occurs and you have done all this testing you can be 99.9% sure
the error is caused in your actual new tested method (and not in previuos tested methods
best regards
Stefan
CON CR = 13 ' ASCII <CR> LF = 10 ' ASCII <LF> VAR long gps_stack[noparse][[/noparse]18] byte GPRMCb[noparse][[/noparse]120] long GPRMCa[noparse][[/noparse]120] byte gps_buff[noparse][[/noparse]120],Rx',cksum long cog,cptr,ptr,arg,j long Null[noparse][[/noparse]1] OBJ uart : "fullduplexserial_mini" PUB start(serRecv,serXmit) : okay '' Starts uart object (at baud specified) in a cog '' -- returns false if no cog available okay := uart.start(serRecv,serXmit,0,4800) ' for USGlobeSat model 408 mode is 0 ' for serial PC simulator mode is 1 return cog := cognew(readNEMA,@gps_stack) + 1 PUB stop '' Stop serial driver - frees a cog if cog cogstop(cog~ - 1) PUB readNEMA Null[noparse][[/noparse]0] := 0 repeat bytefill(@gps_buff,0,79) ' zeroes the memory space repeat while Rx <>= "$" ' wait for the $ to insure we are starting with Rx := uart.rx ' a complete NMEA sentence cptr := 0 repeat while Rx <>= CR ' continue to collect data until the end of the NMEA sentence Rx := uart.rx ' get character from Rx Buffer if Rx == "," gps_buff[noparse][[/noparse]cptr++] := 0 ' If "," replace the character with 0 else gps_buff[noparse][[/noparse]cptr++] := Rx ' else save the character if gps_buff[noparse][[/noparse]2] == "R" if gps_buff[noparse][[/noparse]3] == "M" if gps_buff[noparse][[/noparse]4] == "C" copy_buffer(@GPRMCb, @GPRMCa) pub copy_buffer ( buffer,args) bytemove(buffer,@gps_buff,cptr) ' copy received data to buffer ptr := buffer arg := 0 repeat j from 0 to 78 ' build array of pointers if byte[noparse][[/noparse]ptr] == 0 ' to each if byte[noparse][[/noparse]ptr+1] == 0 ' record long[noparse][[/noparse]args][noparse][[/noparse]arg] := Null ' in else ' the long[noparse][[/noparse]args][noparse][[/noparse]arg] := ptr+1 ' data buffer arg++ ptr++ ' now we just need to return the pointer to the desired record pub valid return GPRMCa[noparse][[/noparse]1] pub speed return GPRMCa[noparse][[/noparse]6] pub heading return GPRMCa[noparse][[/noparse]7] pub date return GPRMCa[noparse][[/noparse]8] pub latitude return GPRMCa[noparse][[/noparse]2] pub N_S return GPRMCa[noparse][[/noparse]3] pub longitude return GPRMCa[noparse][[/noparse]4] pub E_W return GPRMCa[noparse][[/noparse]5] pub noGPSData GPRMCa.long[noparse][[/noparse]1] := string("X") PUB crc8bitwise(pBuf, buflen, poly, initial): crc | i,k 'pBuf is the string to be CRCs 'buflen is thelength of th ebuffer to be CRCd 'poly is the ? 'initial is the inital value of CRC crc := initial repeat i from 0 to buflen - 1 crc ^= (BYTE[noparse][[/noparse]pBuf][noparse][[/noparse]i] >< 8) repeat k from 0 to 7 if crc & $80 crc := (crc << 1) ^ poly else crc <<= 1 crc &= $ff crc ><= 8··· This is creating an array of strings that can be read by calling each method.· The stack portion I am not sure about.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
Can we also have a look at that? Since the name has been changed from fullduplexserial to fullduplexserial_mini I'm ***UMING you have made modifications to that object. This is necessary so we can see what your code is ACTUALLY doing. Since this object was renamed we would like to know if, if anything was changed, so we don't have to waste time running a 'diff' on the code.
·
Also since it was not included can we see what:
Are set for?
It would be a whole lot easier if you would post an 'archive' of code that exhibits the problem so those that are willing to look, and help, would have all of the resources available to debug.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mike
Post Edited (Mike Cook) : 9/19/2008 11:14:28 PM GMT
VAR long cog 'cog flag/id long rx_head '9 contiguous longs long rx_tail long tx_head long tx_tail long rx_pin long tx_pin long rxtx_mode long bit_ticks long buffer_ptr ' buffers need to be a power of 2 byte rx_buffer[noparse][[/noparse]128] 'transmit and receive buffers ' byte tx_buffer[noparse][[/noparse]16] PUB start(rxpin, txpin, mode, baudrate) : okay '' Start serial driver - starts a cog '' returns false if no cog available '' '' mode bit 0 = invert rx '' mode bit 1 = invert tx '' mode bit 2 = open-drain/source tx '' mode bit 3 = ignore tx echo on rx ' stop longfill(@rx_head, 0, 4) longmove(@rx_pin, @rxpin, 3) bit_ticks := clkfreq / baudrate buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 'PUB stop '' Stop serial driver - frees a cog ' if cog ' cogstop(cog~ - 1) ' longfill(@rx_head, 0, 9) 'PUB rxflush '' Flush receive buffer ' repeat while rxcheck => 0 PUB rxcheck : rxbyte '' Check if byte received (never waits) '' returns -1 if no byte received, $00..$FF if byte rxbyte-- if rx_tail <> rx_head rxbyte := rx_buffer[noparse][[/noparse]rx_tail] rx_tail := (rx_tail + 1) & $F 'PUB rxtime(ms) : rxbyte | t '' Wait ms milliseconds for a byte to be received '' returns -1 if no byte received, $00..$FF if byte ' t := cnt ' repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms PUB rx : rxbyte '' Receive byte (may wait for byte) '' returns $00..$FF repeat while (rxbyte := rxcheck) < 0 'PUB tx(txbyte) '' Send byte (may wait for room in buffer) ' repeat until (tx_tail <> (tx_head + 1) & $F) ' tx_buffer[noparse][[/noparse]tx_head] := txbyte ' tx_head := (tx_head + 1) & $F ' if rxtx_mode & %1000 ' rx DAT '*********************************** '* Assembly language serial driver * '*********************************** org ' ' ' Entry ' entry mov t1,par 'get structure address add t1,#4 << 2 'skip past heads and tails rdlong t2,t1 'get rx_pin mov rxmask,#1 shl rxmask,t2 add t1,#4 'get tx_pin rdlong t2,t1 mov txmask,#1 shl txmask,t2 add t1,#4 'get rxtx_mode rdlong rxtxmode,t1 add t1,#4 'get bit_ticks rdlong bitticks,t1 add t1,#4 'get buffer_ptr rdlong rxbuff,t1 mov txbuff,rxbuff add txbuff,#128 test rxtxmode,#%100 wz 'init tx pin according to mode test rxtxmode,#%010 wc if_z_ne_c or outa,txmask if_z or dira,txmask mov txcode,#transmit 'initialize ping-pong multitasking ' ' ' Receive ' receive jmpret rxcode,txcode 'run a chunk of transmit code, then return test rxtxmode,#%001 wz 'wait for start bit on rx pin test rxmask,ina wc if_z_eq_c jmp #receive mov rxbits,#9 'ready to receive byte mov rxcnt,bitticks shr rxcnt,#1 add rxcnt,cnt :bit add rxcnt,bitticks 'ready next bit period :wait jmpret rxcode,txcode 'run a chuck of transmit code, then return mov t1,rxcnt 'check if bit receive period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait test rxmask,ina wc 'receive bit on rx pin rcr rxdata,#1 djnz rxbits,#:bit shr rxdata,#32-9 'justify and trim received byte and rxdata,#$FF test rxtxmode,#%001 wz 'if rx inverted, invert byte if_nz xor rxdata,#$FF rdlong t2,par 'save received byte and inc head add t2,rxbuff wrbyte rxdata,t2 sub t2,rxbuff add t2,#1 and t2,#$0F wrlong t2,par jmp #receive 'byte done, receive next byte ' ' ' Transmit ' transmit jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,par 'check for head <> tail add t1,#2 << 2 rdlong t2,t1 add t1,#1 << 2 rdlong t3,t1 cmp t2,t3 wz if_z jmp #transmit add t3,txbuff 'get byte and inc tail rdbyte txdata,t3 sub t3,txbuff add t3,#1 and t3,#$0F wrlong t3,t1 or txdata,#$100 'ready byte to transmit shl txdata,#2 or txdata,#1 mov txbits,#11 mov txcnt,cnt :bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode test rxtxmode,#%010 wc if_z_and_c xor txdata,#1 shr txdata,#1 wc if_z muxc outa,txmask if_nz muxnc dira,txmask add txcnt,bitticks 'ready next cnt :wait jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,txcnt 'check if bit transmit period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait djnz txbits,#:bit 'another bit to transmit? jmp #transmit 'byte done, transmit next byte ' ' ' Uninitialized data ' t1 res 1 t2 res 1 t3 res 1 rxtxmode res 1 bitticks res 1 rxmask res 1 rxbuff res 1 rxdata res 1 rxbits res 1 rxcnt res 1 rxcode res 1 txmask res 1 txbuff res 1 txdata res 1 txbits res 1 txcnt res 1 txcode res 1▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·- Ouch, thats not suppose to be hot!··
Michael King
Application Engineer
R&D
Check out Project: PSAV Persistent Sailing Autonomous Vehicle