2012-08-25 02:19 AM
hello eveyone,
I am currently using USB FS library and also systick interrupt to time some operations in the program. USB library works fine when used, and systick also works fine (used basically to mae some delay Functions or time exexution between code. my systick interrupt is set at 200khz (5us step increments) with the following code :#define SYSTICK_FREQUENCY 200000SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY);
What I can observe is that when I send a big amount of of data over the usb taking about 7.5 seconds, I get a number of increments of about 450000, which would make 2 seconds timing. I therefore suspected that it was an interrupt priority problem. I checked into the USB FS library code that I was using and what I can see in terms of interrupt configurations is : NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
I have seen that the systick_config code was setting interrupt priority to lowest priority, So I have tried to set systick interrupt to highest priority using :NVIC_SetPriority(SysTick_IRQn, 0);
I have also tried to lower the USB priority values to 5,5 (NVIC_IRQChannelPreemptionPriority, NVIC_IRQChannelSubPriority ), but the problem still remains the same. How can I make sure that teh systick interrupt will still be higher priority and evntually preempt any other interrupt so that my time measurement interrupt still gives reliable values ? Thanks in advance. LongChair.
2012-08-25 05:53 AM
Having a 72 MHz processor interrupt every 360 cycles is probably not a great plan.
How many cycles does the SysTick service routine consume? The 32-bit core cycle counter on the trace unit should be able to measure around a minute, at a granularity of about 13.889 ns2012-08-25 06:29 AM
Hi Clive,
You are probably right that this plan is not optimal :) Systick routine is currently only incrementing a 32 bits integer so that I can measure time between some other ISR which are toggled on GPIO IOs. I didn't know there was already an internal counter which would allow me to do basically the same thing. Which counter are you talking about ? I basically need to measure some signal timings (couple usecs resolution is good enough). then I want to time some operation execution time but they are mainly below a minute. Though even if toggling systick service routine quite often at this rate, how come settings it's priority to 0 as done above, will not allow it to fully count the time when having heavy USB transfer ongoing ? Even if it's not the best way to do it i'd still like to understand what is the source of this behaviour :) Thanks in advance :) Thanks2012-08-25 07:56 AM
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/DispForm.aspx?ID=20293&RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Run code in SRAM in ASM
You still appear to have a few hundred cycles to play with, assuming a 72 MHz core, still the wait states on the flash may eat into that, and arbitration with other bus activity. At some point the processor saturates, but I'd agree you do seem to be missing a lot of interrupts.2012-08-25 09:22 AM
Thanks for the link !
I have tried it and it seems to work very well for most of my application. I get a 6.3 seconds measurement which seems close to clockwatch, where I was getting 2.3 seconds with the systick interrupt. I guess I'll stick with this counter then. I'll probably have to implement a mechanism for longer durations than 59 seconds (DWT_CYCCNT rollover). not sure yet, but maybe I could use systick at lower frequency to come and pump out core cycles into maybe µSecs or Milisecs. Maybe something like this in systick handler set to 1ms: void SysTick_Handler(void) { (*DWT_CYCCNT) -= (SystemCoreClock / 1000); // this should be a constant. MSecCounter++; } This way the cycle counter would not rollover and I could have much longer measurement durations (49 days :P) . But I would definitely need to compensate for the cycles used to compute the operation on DWT_CYCCNT; Would modifying the DWT_CYCCNT on the fly have any known side effect ? Thanks.