Tool/software: TI-RTOS
Hello,
I am using the ProjectZero example with my own BLE characteristics (total of 4) with the SDI from the SPP example.
The UART seems to work for awhile until the app crashes and I get the exception:
Hard Fault: FORCED: BUSFAULT: PRECISERR.Data Access Error. Address = 0x8
I was getting an IMPRECISERR error but the developer guide said to disable buffered writes.
Below is a screenshot of the exception and disassembly. Also, note the HEAPMGR_SIZE.
To recreate this exception I repeatedly send characters out the UART with SDITask_Printf (Similar to SDITask_sendToUART)
Posted below is the SDITask_Printf function. I tried to mimic SDITask_sendToUART as closely as possible but it seems I have a memory leak somewhere.
Is it possible ICall is not freeing the last pSDIMsg structure? For everything else I've found an ICall_free and it seems to crash when It first calls that structure after its run out of available memory.
The devil must be in the details of this function somewhere and how I'm handling the ICall_malloc, ICall_free, and possibly the ICall Critical Section.
void SDITask_Printf(char *format, ...) { ICall_CSState key; char* buffer = (char *)ICall_malloc(128); SDIMSG_msg_t *pSDIMsg = (SDIMSG_msg_t *)ICall_malloc( sizeof(SDIMSG_msg_t)); SDI_QueueRec *recPtr; int i,j; va_list args; // count number of LF's in format string i = 0; j = 0; while (format[i] != 0) { if (format[i++] == '\n' ) j++; } va_start(args, format); vsnprintf(&buffer[j],128, format, args); // format output, skipping j characters // shift characters to the left, inserting CR's as needed i=0; while (buffer[j]) { if (buffer[j]=='\n') { buffer[i++]='\r'; } buffer[i++] = buffer[j++]; } buffer[i] = 0; // null-terminate the buffer uint16 length = strlen(buffer); key = ICall_enterCriticalSection(); va_end(args); if(pSDIMsg) { pSDIMsg->msgType = SDIMSG_Type_ASYNC; pSDIMsg->pBuf = (uint8 *)ICall_allocMsg(length); pSDIMsg->pBufSize = length; if(pSDIMsg->pBuf) { // Payload memcpy(pSDIMsg->pBuf, (uint8_t *)buffer, length); } recPtr = ICall_malloc(sizeof(SDI_QueueRec)); recPtr->sdiMsg = pSDIMsg; } switch (pSDIMsg->msgType) { case SDIMSG_Type_ASYNC: { Queue_enqueue(sdiTxQueue, &recPtr->_elem); Event_post(hUartEvent, SDITASK_TX_READY_EVENT); break; } default: { //error break; } } //ICall_free(pSDIMsg); ICall_leaveCriticalSection(key); //delay_ms(15); ICall_free(buffer); }
Thanks for your time,,
Brett