This simple code fragment crashes and restarts MCU!
Hello.
I have a small code for GPS, which works correctly, however, I've noticed the following:
IF GPS is physically disconnected from the input, or I disable the "serin 2" line, main loop crashes after the first execution and MCU restarts from the beginning. This happens also on other physical boards, so it is not issue of this particular MCU. Other power supplies, other ways of output, like LCD screen instead of serout were tried, as well as hardware serial inputs and outputs - no changes. I also tried same code on 16F1939, 18F45K22 - same result.
Code:
;----[16F886 Hardware Configuration]--------------------------------------------
#CONFIG
cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
cfg1&= _WDT_ON ; WDT enabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOR_OFF ; BOR disabled
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming
cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
__CONFIG _CONFIG1, cfg1
cfg2 = _BOR40V ; Brown-out Reset set to 4.0V
cfg2&= _WRT_OFF ; Write protection off
__CONFIG _CONFIG2, cfg2
#ENDCONFIG
TRISA=%00000001 'SET A TO OUTPUT 1=input
TRISC=%00001000 'set C3 for gps
TRISB=%00011000 'set PortB to output
ANSELH=%00000000 ' ADC OFF B
ANSEL=%000000000 'configure PortA as digital except first 2
ADCON1=%10000000 'adc justify
OSCCON=%01110101 'SET FREQUENCY TO 8MHZ
WPUB=%00000000 'turn off Pullups
CM1CON0=0 'DISABLE COMPARATORS
CM2CON0=0 'SAME HERE
'CCP1CON=%01000000 ' configure pwm
'PSTRCON=%00010110 'disable C pwm
DEFINE OSC 8
DEFINE ADC_BITS 12
DEFINE ADC_CLOCK 5
DEFINE ADC_SAMPLEUS 5
gps_data VAR BYTE[80] ' Buffer to store GPS data
gps_char VAR BYTE ' Character received from GPS
time_data VAR BYTE[6] ' Array to store the extracted time
i VAR BYTE ' Loop variable
start_found VAR BIT ' Flag to indicate start of time data
' Define the serial pins
GPS_RX var PORTC.7 ' RX pin for GPS (Adjust according to your setup)
GPS_TX var PORTC.5 ' TX pin for GPS (Adjust according to your setup)
' Initialize variables
start_found = 0
i = 0
serout2 portc.5,84, ["Start ok", 10, 13]
toggle portc.3 'test led
pause 100
mainx:
' Wait for data from GPS
serin2 GPS_RX,85,[gps_char] 'If I remove this line or disconnect the GPS, MCU will crash!
' Store data in buffer
gps_data[i] = gps_char
i = i + 1
' Check if we have a complete line of data
IF gps_char = 10 THEN
' Look for the $GPRMC sentence
IF (gps_data[1] = "G") AND (gps_data[2] = "P") AND (gps_data[3] = "R") AND (gps_data[4] = "M") AND (gps_data[5] = "C") THEN
' Extract time from the sentence
start_found = 1
FOR i = 7 TO 12
time_data[i-7] = gps_data[i]
NEXT i
ENDIF
' Reset buffer
i = 0
ENDIF
' Display time data
IF start_found = 1 THEN
serout2 portc.5,84, ["Time: ", time_data[0], time_data[1], ":", time_data[2], time_data[3], ":", time_data[4], time_data[5], 13, 10]
start_found = 0
ENDIF
GOTO mainx
high portc.3 'check if code comes to here
stop
Any ideas?
Re: This simple code fragment crashes and restarts MCU!
Also it will crash randomly even when GPS is connected. Here's how output looks:
Time: 15:41:00
Time: 15:41:01
Time: 15:41:02
Time: 15:41:03
Time: 15:41:04
Time: 15:41:05
Time: 15:41:06
Time: 15:41:07
Start ok <------- it crashed and restarted here
Time: 15:41:10
Time: 15:41:11
Time: 15:41:12
Time: 15:41:13
Time: 15:41:14
So I think this is issue with arrays?
Re: This simple code fragment crashes and restarts MCU!
Could be, easy to verify
Code:
' Wait for data from GPS
serin2 GPS_RX,85,[gps_char] 'If I remove this line or disconnect the GPS, MCU will crash!
' Store data in buffer
gps_data[i] = gps_char
i = i + 1
If i >= 80 'or whatever size you set the array to
serout2 portc.5,84, ["Next char will overrun buffer"]
ENDIF
Re: This simple code fragment crashes and restarts MCU!
not sure but first use of i and i+1 might overrun.
Re: This simple code fragment crashes and restarts MCU!
I am not currentl with PBP, so, please refer the manual where necessary.
It is most likely you are overrunning the specified receive buffer gps_data of 80 bytes as you are not doing any bounds checking to keep the data within that 80 bytes region. That is trashing the variables declared beyond the 80 bytes boundary.
Ideally, you should receive characters until a terminating character is received like a CR or a $00 character (whichever method is used by the module) or the buffer limit is reached (i = 80 as per your code)
edit:looks like I posted together with Henrik and amgen.
Re: This simple code fragment crashes and restarts MCU!
Yes you're correct, i is overrun.
This is AI generated code, by the way :)
I added this:
Code:
if i>=80 then
serout2 portc.5,84, ["Oops!", 10, 13]
i=0
endif
And now output looks like this with GPS connected:
Oops!
Oops!
Oops!
Time: 16:36:37
Time: 16:36:38
Time: 16:36:39
Time: 16:36:40
Oops!
Time: 16:36:42
Oops!
And only "Oops!" with GPS disconnected, but there are no more resets...
Re: This simple code fragment crashes and restarts MCU!
If you're gettings false data when GPS is disconnected, perhaps you have left the RX pin floating. Maybe you could see if adding a pull-up resistor eliminates that problem for you.