anonymous wrote on Wednesday, July 25, 2012:
Hi all,
I’ve inherited a project (I’m an ME, not CS/EE) running FreeRTOS and have been tasked with eliminating a few bugs.
Most have been simple, but never having used any RTOS before, some problems are more troubling. There’s one thing in particular that I keep coming back to: data abort.
I had a function to stream a file over UART. The data transmitted fine, but at the end of every file when it came back to the “root” of the task, I got a stack overflow (checking was enabled). I couldn’t figure out why, so I added a lot of debug prints.
Ok, that’s interesting… it reinitializes all (already running) tasks and then overflows. But why would it reset? It turns out, all the exception handlers cascaded into the reset handler. I tried SUBS R15,R14,#8 to go back two instructions and resume, but it stays stuck. I guess printing R14 - 8 might tell me the value of the memory location that was accessed improperly, but I had no debugger and I’m no good with inline ASM. If someone can suggest how to read that to C, I can do a UART_puts or putc to see what it contains.
If I send a short string manually, it works fine. It’s sort of an arbitrary cut off length. This runs in a task called Upload, and I have tried everything from portSAVE/RESTORE, task_ENTER_CRITICAL, vTaskSuspendAll, disabling interrupts… it still happens. Yes, FS_SHARE is enabled, but FS_REENTRANT is not as this is accessed from a single task. I have also tried declaring the file locally as well as globally.
The offending code is below, called within task ‘Upload’:
int SendFile(char* filetosend) {
taskDISABLE_INTERRUPTS();
vTaskSuspendAll();
FRESULT res;
FIL SD_File_Handle_2; // Can I use the same handle from SD_file_handle to reduce RAM use?
BYTE buffer[512]; //BYTE buffer[SD_BLOCK_SIZE];
uint32_t br;
int i;
int hadExtension;
hadExtension = 0;
if (strcmp(filetosend,"ACTIVE") == 0) { filetosend = filename; }
for (i = 0; i < 15; i ++) {
if (filetosend[i] == '.') { hadExtension = 1; }
if (filetosend[i] == '\r' || filetosend['i'] == '\n') { filetosend[i] = '\0'; break; } // remove extra characters
}
if (hadExtension == 0 && i <= 11) { // Automagically add .TXT for things that have no extension
filetosend[i] = '.';
filetosend[i+1] = 'T';
filetosend[i+2] = 'X';
filetosend[i+3] = 'T';
// This does not null-terminate, assuming that any /r/n would be overwritten by the first ".T"
}
gm862_upload("SENDING ",8); gm862_upload(filetosend,strlen(filetosend)); gm862_upload("...\r\n",5);
res = f_open(&SD_File_Handle_2, filetosend, FA_READ);
if (res != FR_OK) {
gm862_upload("OPEN FAILED\r\n",13);
taskENABLE_INTERRUPTS();
xTaskResumeAll();
return res;
}
else {
gm862_upload("\r\n***START***\r\n",15);
while (1) {
res = f_read(&SD_File_Handle_2, buffer, sizeof(buffer),(UINT *) &br);
if (res || br == 0) { gm862_upload("\r\n***END***\r\n",13); break; } // Error or EOF
int j;
for (j = 0; j < sizeof(buffer); j++) { gm862_addchar(buffer[j]); }
//if (br % 512 == 0) { debug_printf("\nSector edge\n"); }
}
f_close(&SD_File_Handle_2);
taskENABLE_INTERRUPTS();
xTaskResumeAll();
return res;
}
}
Frankly, I don’t care a whole heck of a lot of this is blocking (I’d rather it not be) - I just want it to send a file and keep on trucking! It does something similar for f_write, but I imagine solving this will solve that…
Thanks!