I'm trying to use the HAL (os-less) mode for a PoC project (STM32L0, NUCLEO64_L053R8 and NUCLEO32_L011K4).
I've enabled one serial port (SD2) for debugging traces, one timer (TIM2), and a couple of GPIO.
STM32 uses HSI16 as the main clock source. I can observe the (scaled) clock on a GPIO (using MCO)
I'm running TIM2 with HAL_GPT in continuous mode, with a callback (4MHz, ARR: 0xFFFF).
The callback is configured to toggle a GPIO on each call.
I can observe that the callback never gets called when the main() function is running a busy loop (something like for(;;) {}).
If I add some call to osalThreadSleepMilliseconds() in this loop, the callback is called.
I would have expected that the "main" (unique) thread would get preempted by the TIM2 ISR, but it seems it is not, so I guess I missed an important point somewhere (configuration)? I'm pretty sure it is not related to TIM2, as I can observe that the SD2 traces do not get output if a busy loop is called right after chprintf() has been called - I guess same symptom, ISR is not executed.
There is something critical I did not get about ChibiOS & OS-less mode it seems. I would have expected the ISR to execute even if the main() function was running a busy loop.
Any clue?
I tried to locate some demo about os-less environments, but I failed to find a matching example.
I've read that osalThreadSleepMilliseconds() uses a virtual timer, which seems to be documented as a part of the RT subsystem, so I got even more confused
Unrelated question: is the IRQ priority level (order, boundaries, ..) documented somewhere?
Thanks
HAL os-less & ISR execution issue Topic is solved
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: HAL os-less & ISR execution issue
Hi,
Do you enable interrupts in your main() ? the main function is entered with interrupts disabled.
Giovanni
Do you enable interrupts in your main() ? the main function is entered with interrupts disabled.
Giovanni
Re: HAL os-less & ISR execution issue
I call
osalSysEnable();
once HW configuration in complete (before the busy loop), which call __enable_irq() if I'm not mistaken.
I just give a tried and force OSAL_ST_MODE == OSAL_ST_MODE_NONE and it seems the ISR handler is called as expected. I'm not sure why.
As this setting is not part of the osalconf.h, I never tried to changed it up to now - and I may be on the wrong way here.
I guess that w/o it, I will not be able to call functions such as osalThreadSleepMilliseconds() as there is no tick to wake the thread up.
osalSysEnable();
once HW configuration in complete (before the busy loop), which call __enable_irq() if I'm not mistaken.
I just give a tried and force OSAL_ST_MODE == OSAL_ST_MODE_NONE and it seems the ISR handler is called as expected. I'm not sure why.
As this setting is not part of the osalconf.h, I never tried to changed it up to now - and I may be on the wrong way here.
I guess that w/o it, I will not be able to call functions such as osalThreadSleepMilliseconds() as there is no tick to wake the thread up.
Re: HAL os-less & ISR execution issue
If I use the following kludge in the busy loop:
the TIM2 ISR handler runs.
If I only move the IRQ enablement before the loop:
the TIM2 ISR does not get called anymore.
I guess that "something" fails to restore the IRQ, but I do not know (yet) what.
The only callback I used is dedicated to TIM2 and is rather simple:
Code: Select all
for(;;) {
__enable_irq();
__disable_irq();
}
the TIM2 ISR handler runs.
If I only move the IRQ enablement before the loop:
Code: Select all
__enable_irq();
for(;;) {
}
the TIM2 ISR does not get called anymore.
I guess that "something" fails to restore the IRQ, but I do not know (yet) what.
The only callback I used is dedicated to TIM2 and is rather simple:
Code: Select all
static void
_ow_gpt_cb(GPTDriver * gptp) {
(void)gptp;
_ow_ge.ge_ticks += 1;
palTogglePad(LED1_GPIO_PORT, LED1_GPIO_PIN);
}
static const GPTConfig _GPT2_CONFIG = {
.frequency = STM32_HSI16CLK >> 2U,
.callback = _ow_gpt_cb,
};
struct ow_gpt_engine {
volatile uint32_t ge_ticks;
};
struct ow_gpt_engine _ow_ge;
Re: HAL os-less & ISR execution issue
From ChibiOS_18.2.1/os/hal/osal/os-less/ARMCMx/osal.h
I would have expected to be symetrical with and call
Is it on purpose?
Code: Select all
/**
* @brief Enters a critical zone from ISR context.
* @note This function cannot be used for reentrant critical zones.
*
* @special
*/
static inline void osalSysLockFromISR(void) {
#if CORTEX_MODEL == 0
__disable_irq();
#else
__set_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY);
#endif
}
/**
* @brief Leaves a critical zone from ISR context.
* @note This function cannot be used for reentrant critical zones.
*
* @special
*/
static inline void osalSysUnlockFromISR(void) {
// ?
}
I would have expected
Code: Select all
osalSysUnlockFromISR()
Code: Select all
osalSysLockFromISR()
Code: Select all
__enable_irq()
Is it on purpose?
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: HAL os-less & ISR execution issue
Hi,
It is the error I think, modify as follow:
Moving this topic in bug reports, it will be fixed in next release.
Giovanni
It is the error I think, modify as follow:
Code: Select all
static inline void osalSysUnlockFromISR(void) {
#if CORTEX_MODEL == 0
__enable_irq();
#else
__set_BASEPRI(0);
#endif
}
Moving this topic in bug reports, it will be fixed in next release.
Giovanni
Re: HAL os-less & ISR execution issue
Hi Giovanni,
I changed the function with this code (when I posted the question actually), and it indeed fixed the problem, but I was not sure it was the root cause.
Thanks for your help,
Manu.
While seeking the code, I noticed a couple of typos in the comments, unrelated to this issue.
I'm not sure to report this (pull request?), sorry for this off-topic add-on:
* os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c@248:
-> free running counter may be different than TIM2
* os/common/ext/ST/STM32L0xx/stm32*.h
-> divider value comment is not accurate.
I changed the function with this code (when I posted the question actually), and it indeed fixed the problem, but I was not sure it was the root cause.
Thanks for your help,
Manu.
While seeking the code, I noticed a couple of typos in the comments, unrelated to this issue.
I'm not sure to report this (pull request?), sorry for this off-topic add-on:
* os/hal/ports/STM32/LLD/TIMv1/hal_st_lld.c@248:
Code: Select all
* @brief TIM2 interrupt handler.
-> free running counter may be different than TIM2
* os/common/ext/ST/STM32L0xx/stm32*.h
Code: Select all
#define RCC_CFGR_MCO_PRE_2 RCC_CFGR_MCOPRE_DIV2 /*!< MCO is divided by 1 */
#define RCC_CFGR_MCO_PRE_4 RCC_CFGR_MCOPRE_DIV4 /*!< MCO is divided by 1 */
#define RCC_CFGR_MCO_PRE_8 RCC_CFGR_MCOPRE_DIV8 /*!< MCO is divided by 1 */
#define RCC_CFGR_MCO_PRE_16 RCC_CFGR_MCOPRE_DIV16 /*!< MCO is divided by 1 */
-> divider value comment is not accurate.
- Giovanni
- Site Admin
- Posts: 14455
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Who is online
Users browsing this forum: No registered users and 18 guests