I'm having some odd behavior here. My program includes a library (which I'm writing/debugging) which processes incoming NMEA data from a GPS module. Part of it involves copying the Talker and Message ID into a couple char arrays inside a struct which will be returned to the caller. During one of these memcpy() operations, the CPU jumps to the Hwi exception handler and the RTOS crashes.
Software versions:
TI-RTOS 2.20.0.06 for CC13xx
TI ARM compiler v15.12.3.LTS
Here's the C code around the portion of the crash:
outs = &parsedSentencePool[i]; if (cinsent[0] != '$') { mtkgps_parse_errno = NMEA_PARSE_ERR_INVALID_STARTCHAR; return NULL; } if (cinsent[slen-1] == '\n') { slen--; } if (cinsent[slen-1] == '\r') { slen--; } if (!strncmp(cinsent+1, "GP", 2)) { memcpy(outs->Talker, cinsent+1, 2); outs->Talker[2] = '\0'; pst = 3; // First byte after "$GP" } if (!strncmp(cinsent+1, "PMTK", 4)) { System_printf("Matched\n"); System_flush(); memcpy(outs->Talker, cinsent+1, 4); outs->Talker[4] = '\0'; System_printf("Copy complete\n"); System_flush(); pst = 5; // First byte after "$PMTK" }
It is that memcpy(outs->Talker, cinsent+1, 4) which crashes. Disassembly of this code:
It looks as if the memcpy() was optimized into a 32-bit load & store operation, which is pretty clever on the compiler's part. Doing assembly step-into, we see R1 eventually becomes 0x2000128D (0x2000128C is the start of the nmea buffer, which contains the $, but we want the next 4 chars after that):
Note R1 is now 0x2000128D. Here's the memory at that location:
Looks correct. That's the NMEA message for MTK3339 GPS's indicating that it has powered on.
But when I step one more, the "ldr r1, [r1]" crashes:
Actual crash (just hit 'run' after this):
I am not an assembly language expert, so I don't know why that happened or if it's normal behavior. I have seen references to the LDR instruction having restrictions that the Rt, Rn registers must differ but it indicated under one of the addressing schemes that doesn't appear to be present here. Any expert advice? I can use strncpy which I have validated does work, I'm just puzzled why memcpy() doesn't work here.