Hey All,
Insight: I have a RTOS code written on LPC1788. The code has one task to receive data from the uart. Depending upon the data received from the uart, a reply is sent back. To send the reply from a buffer, a pointer to buffer is passed via mail box.
Problem: Things were good, but now i have started getting a PRECISERR. The Buffer fault address is 0xE8BA0ED (which is not a valid memory location). From the stack data, (read when a hardfault is generated), PC points to 0x0001BE1C.
The following is the piece of code that i found at the memory location, but dont know what the code (looks like a library function code)
rt_get_first: 0x0001BE18 4601 MOV r1,r0 0x0001BE1A 6840 LDR r0,[r0,#0x04] 0x0001BE1C 6842 LDR r2,[r0,#0x04] 0x0001BE1E 604A STR r2,[r1,#0x04] 0x0001BE20 780B LDRB r3,[r1,#0x00] 0x0001BE22 2200 MOVS r2,#0x00 0x0001BE24 2B02 CMP r3,#0x02 0x0001BE26 D005 BEQ 0x0001BE34 0x0001BE28 2B01 CMP r3,#0x01 0x0001BE2A D003 BEQ 0x0001BE34 0x0001BE2C 2B03 CMP r3,#0x03 0x0001BE2E D001 BEQ 0x0001BE34 0x0001BE30 6042 STR r2,[r0,#0x04] 0x0001BE32 4770 BX lr 0x0001BE34 6843 LDR r3,[r0,#0x04] 0x0001BE36 B10B CBZ r3,0x0001BE3C 0x0001BE38 6099 STR r1,[r3,#0x08] 0x0001BE3A 6042 STR r2,[r0,#0x04] 0x0001BE3C 6082 STR r2,[r0,#0x08] 0x0001BE3E 4770 BX lr
Can anyone tell me what the above code is all about? what is actual cause of the hardfault? What steps to take, to solve the issue?
Assuming you use your own RTOS (do you?), you may want to check your context switch code.
p_task = rt_get_first (&os_rdy); os_tsk.run->ret_val = OS_R_OK;
Going to assume based on how it's called that os_rdy is at a fixed address, and pointer within it is invalid.
I'd probably look for heap corruption, buffers being overrun in your service routine, and to a lesser extent the stack.
P_TCB rt_get_first (P_XCB p_CB); typedef struct OS_XCB { U8 cb_type; /* Control Block Type */ struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ struct OS_TCB *p_dlnk; /* Link pointer for delay list */ struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ U16 delta_time; /* Time until time out */ } *P_XCB; typedef struct OS_TCB { /* General part: identical for all implementations. */ U8 cb_type; /* Control Block Type */ U8 state; /* Task state */ U8 prio; /* Execution priority */ U8 task_id; /* Task ID value for optimized TCB access */ struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ struct OS_TCB *p_dlnk; /* Link pointer for delay list */ struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ U16 delta_time; /* Time until time out */ U16 interval_time; /* Time interval for periodic waits */ U16 events; /* Event flags */ U16 waits; /* Wait flags */ void **msg; /* Direct message passing when task waits */ U8 ret_val; /* Return value upon completion of a wait */ /* Hardware dependant part: specific for CM processor */ U8 ret_upd; /* Updated return value */ U16 priv_stack; /* Private stack size, 0= system assigned */ U32 tsk_stack; /* Current task Stack pointer (R13) */ U32 *stack; /* Pointer to Task Stack memory block */ /* Task entry point used for uVision debugger */ FUNCP ptask; /* Task entry address */ } *P_TCB;
p_lnk, chaining thereof ?
Do i increase the heap and stack size. The size of my uart buffer is 800 bytes. (thats too big i know, and would prefer to reduce it by implementing some good technique, which i have not come across yet, and you may suggest one)
Assuming you use your own RTOS (do you?) I use Keil RTOS.
hence, i cant check the context switching code.
The size of my uart buffer is 800 bytes. I apologize for negligence, but the buffer is a global buffer.
os_rdy looks to be global, which is why you might want to focus on what's corrupting the memory arena. ie errant pointers, exceeding buffers, etc.
You'd want to look at os_rdy's memory location, and those around it, observe if/when it is over written, what the data looks like (stuff you're receiving via serial, or whatever) and if you can better determine when that's occurring. Use a debug "Memory View", and try to see the scope of the memory being modified.
The bogus pointer causing the fault didn't appear to be ASCII characters.