2020-10-22 05:38 PM
What would cause the LR register to be misaligned?
I occasionally get an UNALIGNED exception running Ethernet (lwIP). I suspect the DMA but I implemented as it is in the example and the
https://community.st.com/s/article/FAQ-Ethernet-not-working-on-STM32H7x3
post.
From IAR:
An unaligned access error has occurred (CFSR.UNALIGNED).
Exception occured at PC = 0x804ed9e, LR = 0x804ecf1
The Program Counter is in the FreeRTOS function: prvCheckTasksWaitingTermination()
2020-10-22 05:47 PM
Thumb code is always at an ODD address
The CM7 will get alignment faults on misaligned LDRD/STRD
Look at what's actually faulting
2020-10-22 06:07 PM
Thanks for the quick response clive.
The PC and LR are different each time, but always in the FreeRTOS scheduler.
I have yet to see an odd address in the assembly code. I'm using IAR.
Here is some disassembly for this exception:
Exception occured at PC = 0x804f66a, LR = 0x804d58f
Disassembly around the PC:
0x804'f668: 0xe7fe B.N 0x804'f668
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
0x804'f66a: 0xf7ff 0xfc5b BL xTaskGetSchedulerState ; 0x804'ef24
0x804'f66e: 0x2800 CMP R0, #0
Disassembly around the LR:
osStatus osMutexRelease (osMutexId mutex_id)
{
...
else if (xSemaphoreGive(mutex_id) != pdTRUE)
0x804'd582: 0x2300 MOVS R3, #0
0x804'd584: 0x2200 MOVS R2, #0
0x804'd586: 0x2100 MOVS R1, #0
0x804'd588: 0x0020 MOVS R0, R4
0x804'd58a: 0xf002 0xf830 BL xQueueGenericSend ; 0x804'f5ee
0x804'd58e: 0x2801 CMP R0, #1
0x804'd590: 0xd001 BEQ.N 0x804'd596
result = osErrorOS;
2020-10-22 06:48 PM
>>I have yet to see an odd address in the assembly code.
It is a processor level functionality, you should look it up, should be in the architectural documentation.
If LR is even, and moved to PC, it will fault.
If the issue revolves around the scheduler should should perhaps review the alignment and integrity of the stack, and the contexts which are being swapped in.
Beyond bounding issues of the stack, watch for overly broad Invalidate Cache operations, as these can result in pending data not getting into the stack frame properly. In the ByAddr variants of Clean/Invalidate watch for buffers which are not on 32-byte boundaries, or not multiples of 32-bytes.
2020-10-23 06:42 AM
Thanks.
I think my observance of it always happening in the scheduler was a red herring. This time it is happening in the lwip stack.
Supposedly the exception occured on the CMP instruction. Or is it really happening somewhere else?
I think you are right about being the cache. Could you explain that a bit further? This problem only started happening when I enabled Ethernet in my code so perhaps it is an issue with the lwip buffers.
Did you mean 32-byte or 32-bit boundaries?
Exception occured at PC = 0x8041796, LR = 0x8040f51
last_unsent->len += extendlen;
0x804'178c: 0x8922 LDRH R2, [R4, #0x8]
0x804'178e: 0xf8bd 0x0014 LDRH.W R0, [SP, #0x14]
0x804'1792: 0x1882 ADDS R2, R0, R2
0x804'1794: 0x8122 STRH R2, [R4, #0x8]
if (last_unsent == NULL) {
0x804'1796: 0x2c00 CMP R4, #0
0x804'1798: 0xd102 BNE.N 0x804'17a0
Call Stack:
prvGetRegistersFromStack
<Exception frame>
tcp_write
send_data
passthrough_recv
tcp_input
ip4_input
ethernet_input
tcpip_thread_handle_msg
tcpip_thread
prvTaskExitError
2020-10-23 06:45 AM
Right when I sent that last post it happened again:
0x804'd4c8: 0xb57c PUSH {R2-R6, LR}
R2 0x00000003
R6 0x24005db4
I had Cache disabled. Does that eliminate the cache as the culprit?
2020-10-23 02:10 PM
>>Did you mean 32-byte or 32-bit boundaries?
Said and meant 32-byte boundaries, and scope..
https://www.keil.com/pack/doc/CMSIS/Core/html/group__Dcache__functions__m7.html
InvalidateDCache has some VERY nasty side-effects, use very cautiously, and double check any cache-coherency code you have with respect to DMA buffers.
Should check value in R4, but late to NULL check after you've used the pointer.
A write will typically induce a "differed" fault, as the writes are buffered.
I use a hard Fault handler that unpacks the registers at the fault, makes it easier to run the issues to ground with the output in one go
2020-10-23 02:12 PM
The SP is the thing to inspect rather than R2 thru R6 and LR
Check that SP is 32-bit, or preferable 64-bit (B-byte) aligned
Watch for ST's .LD examples where they do dumb things like estack = 0x2001FFFF
2020-10-24 02:36 PM
Clive, Thank you for the help.
The issue has gone away after reconnecting the JTAG GND signal.
Very strange behaviour without that.
I hope that was the issue.
Does that make sense to you? Could it cause unaligned exceptions?
Thanks again. Some useful links I will use here.