STM32H743 variable not updating in interrupt handler
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 7:09 AM
Hello,
i have a strange situation happening and I really can't catch the reasons; in my project I set up an SPI transfer and set a global volatile variable that keeps trace of status state:
//Transmit Data
if(spi == AMPLI_SPI4) SPI4_TransferState = TRANSFER_ONGOING;
ret = HAL_SPI_Transmit_IT(&SpiHandle[spi], pData, Size);
Then in my interrupt handler I want to reset SPI4_TransferState:
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI4)
{
SPI4_TransferState = READY_FOR_TRANSFER;
SPI_ReleaseCSPin(AMPLI_SPI4);
}
}
TRANSFER_ONGOING and READY_FOR_TRANSFER are 2 defines that stands for 1 and 0.
If i debug the code I can see that the interrupt is fired and that the instruction
SPI4_TransferState = READY_FOR_TRANSFER;
is executed; anyway the value of SPI4_TransferState does not change from 1 to 0, as if the instruction is doing nothing.
I have done some tests if, anyway, I change the interrupt handler like this:
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI4)
{
SPI_Test = TRANSFER_ONGOING;
SPI4_TransferState = READY_FOR_TRANSFER;
SPI_Test = READY_FOR_TRANSFER;
SPI_ReleaseCSPin(AMPLI_SPI4);
}
}
where SPI_Test is a variable declared exactly like SPI4_TransferState, both SPI_Test and SPI_TransferState are updated correctly, but obviously this is an unreliable solution which doesn't make much sense.
To give a complete picture:
- All variables are mapped in DTCM RAM, by linker script
- Interrupt handler is in a file called interrupts.c which is mapped in ITCM RAM by linker script
- function to transmit SPI data (HAL_SPI_Transmit_IT) is in a file called SPI.c that executes from FLASH
- My project uses FreeRTOS, but the problem arises in early stage of application when tasks are not even created yet and scheduler hasn't started
MIght it be a cache-coherency problem? I am really clueless, can somebody please help ?
Thanks in advance
Solved! Go to Solution.
- Labels:
-
SPI
-
STM32Cube MCU Packages
-
STM32H7 series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 9:09 AM
Suspect you need to determine why the BKPT is there, likely overlying the opcodes that should be there.
Perhaps use a different variable for Rx vs Tx callbacks to eliminate possible race/ordering issues there.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 7:21 AM
Variable volatile?​
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 7:24 AM
Hello,
yes the SPI4_TransferState variale is declared as "volatile uint32_t", but this doesn't help unluckily..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 8:10 AM
>>MIght it be a cache-coherency problem?
This is unlikely to be the case in a single core, software implementation. Cache coherency would be a potential issue when using DMA, which accesses memory directly, and where the CPU holds dirty cache lines it hasn't flushed.
Using pro-tools like Keil or IAR, or something else? Behaviour changes with/without optimization? Review code listings (disassembly) to see what the compiler generated and the CPU is executing.
Avoid opening a "Peripheral View" of the SPI device in the debugger, it tends to be invasive. Instrument the code, output telemetry via UART or SWV
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 8:58 AM
I am using VisualGDB, optimization is disabled (O0).
I have tried to place SPI.c file in ITCM Ram and declared inside it a variable called "volatile uint32_t SPI_TransferState[NUM_DEFINED_SPIs];"; looking at the assembly produced I have noticed this strange situation:
I have defined the callback function like this:
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI4)
{
SPI_TransferState[AMPLI_SPI4] = READY_FOR_TRANSFER;
SPI_ReleaseCSPin(AMPLI_SPI4);
}
}
Here is the assembly code:
199: void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
200: {
0x00000448 push {r7, lr}
0x0000044a sub sp, #8
0x0000044c add r7, sp, #0
0x0000044e str r0, [r7, #4]
201:
202: if (hspi->Instance == SPI4)
0x00000450 ldr r3, [r7, #4]
0x00000452 ldr r3, [r3, #0]
0x00000454 ldr r2, [pc, #24] ; (0x470 <HAL_SPI_TxCpltCallback+40>)
0x00000456 cmp r3, r2
0x00000458 bne.n 0x466 <HAL_SPI_TxCpltCallback+30>
203: {
204: SPI_TransferState[AMPLI_SPI4] = READY_FOR_TRANSFER;
0x0000045a ldr r3, [pc, #24] ; (0x474 <HAL_SPI_TxCpltCallback+44>)
0x0000045c movs r2, #0
0x0000045e str r2, [r3, #0]
205: SPI_ReleaseCSPin(AMPLI_SPI4);
0x00000460 movs r0, #0
0x00000462 bl 0x42ec <SPI_ReleaseCSPin>
206: }
207: }
The interesting part is from row 16 on; r3 is loaded correctly with SPI_TransferState address (0x200072c4) , which is zeroed out in subsequent instrusctions; the callback works correctly.
But now I am stuck in the Rx callback which is defined like this:
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI4)
{
SPI_TransferState[AMPLI_SPI4] = READY_FOR_TRANSFER;
SPI_ReleaseCSPin(AMPLI_SPI4);
}
}
In this case the assembly code is:
218: void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
219: {
0x00000478 push {r7, lr}
0x0000047a sub sp, #8
0x0000047c add r7, sp, #0
0x0000047e str r0, [r7, #4]
220: if (hspi->Instance == SPI4)
0x00000480 ldr r3, [r7, #4]
0x00000482 ldr r3, [r3, #0]
0x00000484 ldr r2, [pc, #24] ; (0x4a0 <HAL_SPI_RxCpltCallback+40>)
0x00000486 cmp r3, r2
0x00000488 bne.n 0x496 <HAL_SPI_RxCpltCallback+30>
221: {
222: SPI_TransferState[AMPLI_SPI4] = READY_FOR_TRANSFER;
0x0000048a bkpt 0x0011
0x0000048c movs r2, #0
0x0000048e str r2, [r3, #0]
223: SPI_ReleaseCSPin(AMPLI_SPI4);
0x00000490 movs r0, #0
0x00000492 bl 0x42ec <SPI_ReleaseCSPin>
224: }
225: }
In this case the function isn't working and i can guess the reason: it seems to me that r3 isn't loaded with SPI_TransferState address :(
Am I guessing right ?
How could that be ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-04 9:09 AM
Suspect you need to determine why the BKPT is there, likely overlying the opcodes that should be there.
Perhaps use a different variable for Rx vs Tx callbacks to eliminate possible race/ordering issues there.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-11-05 5:13 AM
BKPT instruction is there because i had a software breakpoint set and so the instruction on which I wanted to break was temporarily replaced with the BKPT op code, then it is up to the debugger to execute the original code.
Anyway, as you suggested, I used different variables for Rx and Tx calls and everything now seems to be working perfectly, so thank you for your suggestion.
Now I am going to test deeply to try and find the reasons of this misbehaviour, but the important thing is that now the firmware is doing its job well.
Thank you again for your help.
