cancel
Showing results for 
Search instead for 
Did you mean: 

inline assembly macro inconsistent

RBack.1
Senior

I am using the STM32F746VET6. I am aware that assembly instructions do not have a guaranteed in execution time, however I am surprised how consistently inconsistent my inline assembly macro is behaving. I'm really hoping there is just a mistake in the macro that I can fix. My IVT is in ITCM (memory address 0x0) and the ISR is also in ITCM (memory address 0x200). The 1st, 2nd, 4th, 5th, and 6th pin states show very close to the same delay every time. The 3rd and 7th pin states are always ~1.7x the others, however.

This is the macro:

 

 

#define nop_delay_def(delay_var) __asm volatile (".Lloop%=:               \n\t" \
                                                 "     subs  %[delay], #1 \n\t" \
                                                 "     bne.n .Lloop%=         " \
                                                 :                              \
                                                 : [delay] "r" (delay_var))

 

 

And this is the ISR:

 

 

void __attribute__((optimize("O0"), section(".itcm_text"))) TIM1_TRG_COM_TIM11_IRQHandler(void) {

    PULSER1_GPIO_Port->ODR |= PULSER1_IN1_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR |= PULSER1_IN2_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR &= ~PULSER1_IN1_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR &= ~PULSER1_IN2_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR |= PULSER1_IN1_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR |= PULSER1_IN2_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR &= ~PULSER1_IN1_POS_Pin;
    nop_delay_def(60);
    PULSER1_GPIO_Port->ODR &= ~PULSER1_IN2_POS_Pin;
    HAL_IWDG_Refresh(&hiwdg); // kick the watch dog since FreeRTOS is suspended

    TIM11->SR = 0;
}// TIM1_TRG_COM_TIM11_IRQHandler

 

 

 I have attached a scope shot at the bottom. There is no jitter or variation in the pulses. They show that the macro is inconsistent consistently.

14 REPLIES 14

> Also DWT and SysTick are located in the CPU, therefore accesses to these shouldn't have any delays.

Reading system areas may have timing consequences, such as they may behave as barriers. I am lazy to look up the details now.

But it reminded me of one more question to @RBack.1 : is the irregular timing observed also when running without debugger attached?

JW

Heh...you are correct that this is a problem I've been battling since taking over this code/PCB almost two years ago. It does show the problems when using the debugger or programming.

However, yesterday a young engineer in my company figured out the problem! He looked at the disassembly between the pulses that were regular and were irregular and the addresses that they occupied. By inserting nops to align them to 8byte boundaries he was able to make them all regular. Using a function instead of a macro (which we switched to from a function in hopes of making our problems better) he ensured that the code would always be aligned on the boundaries correctly, however calling the function with a parameter of 1 resulted in irregularity in the subsequent pulses. Now that we ensure that a minimum value of 2 is used for the function, our pulses are all regular again!

This is the same young engineer that is close to solving how to drive our 15pins in 7 states with timers/dma btw. I can't say enough good things about him. I also have great things to say about several people on these forums as some of you have come through for me several times now. @Tesla DeLorean @TDK are names in addition to yours that I remember having helped me before. I'll tag them in case what the young engineer learned is interesting to them.

And boy-oh-boy is this processor an overcomplicated beast...

> align

I thought this is something like that, that's why I wrote above that the function has bigger chance to be consistent as it's always on the same address and always uses the same registers (I mean in one particular binary).

But now I realize that you've mentioned this problem already from a different angle. The picture there got lost during the transition to Khoros; if you still have it, could you please restore it. I gave it a thought back then, but you know, the pressure of family to feed and bills to pay... 🙂

> drive our 15pins in 7 states with timers/dma

DMA-controlled TIMs? That would probably work, although 15 pins (i.e. at least 4 timers) might be just at the boundary of possible. I definitively wouldn't pursue TIM-triggered-DMA-transfer-to-GPIO at this point, as that is probably prone to too much jitter. For regular waveforms on multiple pins, also LTDC comes into mind, although I'm not sure about the maximum clock.

JW

I looked at couldn't find the picture again. I passed your info about jitter onto the young engineer taking this on as a personal project and he says he did encounter that issue. I'm not sure what approach he's using now as a way to work around that issue.

It's not the DWT that has jitter but the instructions in the loop to check it. You can't ensure that the DWT will hit the correct value on the instruction that checks it instead of the loop.

A young engineer here did end up figuring out the problem, however. It was due to boundary alignment of the loop. I do very much appreciate the help that I received in this forum, however.