cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743: misaligned LR register

rammit
Senior

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()

8 REPLIES 8

Thumb code is always at an ODD address

The CM7 will get alignment faults on misaligned LDRD/STRD

Look at what's actually faulting

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rammit
Senior

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;

>>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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rammit
Senior

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

rammit
Senior

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?

>>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

https://community.st.com/s/question/0D50X0000Az372YSQQ/stm32l412-hardfault-while-using-minimal-cubeide-example

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rammit
Senior

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.