2015-04-13 10:57 AM
Noticed an ''interesting'' issue that I was unable to trackdown.
If I compile the example LwIP_UDPTCP_Echo_Server_Netconn_RTOS using IAR 7.40 everything works fine YET when I compile the same code using IAR 6.50 I get an HardFault.Tried to track down the cause but in vail...I need to use 6.50 as thats the license we have, I use size limit with 7.40 (removed TCP to squeeze it in :))Do you have any idea how to attack this issue?Starting with Ethernet cable unplugged:
TaskUDP_ExeStart() tcpip_init(NULL, NULL); Netif_Config(); ... Enters ethernetif_input - once low_level_input ... (netif_is_link_up(&gnetif)) is false ... (... working fine, LED blinks ...) Plugging in the Ethernet cable: ... ethernetif_notify_conn_changed() (netif_is_link_up(netif)) is True netif_set_addr(...) netif_set_up(...) Enters ethernetif_input - many times low_level_input, 2x244 bytes 2x187 2x92 244, 243, ... HardFault_Handler while (1)...2015-04-13 04:11 PM
Consider implementing a handler that does more than loop. Joseph Yiu has published some good examples, start there, and identify what's actually faulting, and what the registers tell you about the problem.
2015-04-14 11:33 AM
Thank you Clive,
Thats a nice reference, I will look into it.2015-04-17 01:28 PM
I found some nice (and very old) links and I implemented their suggested code.
With optimization set to Medium or Low it ~didn't work (it cleared some of the registers, but still shows it's a BUS fault).When optimization was set to High-Speed I was able to receive full data, yet I can't conclude the reason for the fault..As suggested I also added static to the relevant variables.What can you learn from this?[Hard fault handler]
R0 = 20012f3cR1 = 20011ea2R2 = 20011e6cR3 = 20011e8aR12 = 20011e7cLR = 20013004 -> Link registerPC = 20013008 -> Program counter -> gnetifPSR = 8008534 -> N (GE-84) (ISR-134)BFAR = bc01b51b -> Bus fault address (4.4.12, p223) -> ????? there is nothing there!CFSR = 8200 -> Usage fault status register (4.4.11, p222): Bus Fault Address Register-> BFAR holds a valid fault address.HFSR = 40000000 -> Hard fault status register (4.4.14, p225): Forced hard faultDFSR = b -> ???AFSR = 0 -> Auxiliary fault status register2015-04-17 01:31 PM
The images as links.. Should I delete them from the post?
https://www.dropbox.com/s/kc15q186pz71qrj/hardfault.PNG?dl=0
2015-04-17 03:43 PM
Yeah, I'm not sure that's working, your code's in RAM?
The stack data isn't at a fixed address, and the LR code to get the right stack register in R0 needs to be outside the C code. ie assembler code at the Hard_Fault_Handler, then calling your C code. In Keil something like this...; in startup.s
HardFault_Handler PROC
EXPORT HardFault_Handler
IMPORT HardFault_Handler_C
TST LR, #4
ITE EQ
MRSEQ R0, MSP
MRSNE R0, PSP
B HardFault_Handler_C
ENDP ; HardFault_Handler
// in main.c
void HardFault_Handler_C(unsigned int* hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);
stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
printf(''
[Hard fault handler - all numbers in hex]
'');
printf(''R0 = %x
'', stacked_r0);
printf(''R1 = %x
'', stacked_r1);
printf(''R2 = %x
'', stacked_r2);
printf(''R3 = %x
'', stacked_r3);
printf(''R12 = %x
'', stacked_r12);
printf(''LR [R14] = %x subroutine call return address
'', stacked_lr);
printf(''PC [R15] = %x program counter
'', stacked_pc);
printf(''PSR = %x
'', stacked_psr);
printf(''BFAR = %x
'', (*((volatile unsigned long *)(0xE000ED38))));
printf(''CFSR = %x
'', (*((volatile unsigned long *)(0xE000ED28))));
printf(''HFSR = %x
'', (*((volatile unsigned long *)(0xE000ED2C))));
printf(''DFSR = %x
'', (*((volatile unsigned long *)(0xE000ED30))));
printf(''AFSR = %x
'', (*((volatile unsigned long *)(0xE000ED3C))));
printf(''SCB_SHCSR = %x
'', SCB->SHCSR);
while(1);
}
You'll have to adapt for your IAR chains
2015-04-23 02:47 AM
Thank you again for your hints!
Using LR I've been able to track down the problem to a macro in FreeRTOS\tasks.c (which seems to run from memory, hence the address).Since I can put a breakpoint I added a debug variable to find the problematic line.If I try to debug further (adding more debug code) the location of the hard-fault changes..Can't figure out how to track it down, in the vast RTOS/LwIp code..taskSELECT_HIGHEST_PRIORITY_TASK()
... \ df=5; \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) );\ df=6; \ ...