STM32F401RE, FreeRTOS: osErrorISR returned by osKernelInitialize(), osThreadNew(), osKernelStart()

Each OS function call returns osErrorISR. What is more, IS_IRQ() function returns value: 32 decimal. It should not happen, because any of the IRQ is not defined.

osStatus_t osKernelInitialize (void) {
  osStatus_t stat;

  if (IS_IRQ()) {
    stat = osErrorISR;
  else {
    if (KernelState == osKernelInactive) {
      #if defined(USE_FREERTOS_HEAP_5) && (HEAP_5_REGION_SETUP == 1)
        vPortDefineHeapRegions (configHEAP_5_REGIONS);
      KernelState = osKernelReady;
      stat = osOK;
    } else {
      stat = osError;

  return (stat);
  \brief   Get IPSR Register
  \details Returns the content of the IPSR Register.
  \return               IPSR Register value
__STATIC_FORCEINLINE uint32_t __get_IPSR(void)
  uint32_t result;

  __ASM volatile ("MRS %0, ipsr" : "=r" (result) );

The most interesting fact is that, such problem occurs only if functions responsible of reading GPIO pin are used, such as:


There is a link to repository with my project:
I would appreciate any help.
Best regards

The wrappers (looks like maybe CMSIS wrapper) are not provided by FreeRTOS, but typically by the chip manufacturer. As such, it is hard to supply support for them here, as there are many versions of them, none that are provided here.

My first guess on the issue is that FreeRTOS disables the interrupts before the scheduler starts, and depending on the type of machine you are on, that disabling can look like you are in an ISR, and that could confuse IS_IRQ().

Thank you richard for your answer. I really appreciate that :slight_smile:
Anyway I still fight with that problem.

If you are using a set of CMSIS wrappers, you will need to read the documentation for how to use those wrappers provided by the people who wrote them. (There may be an instruction that osKernelInitialize() must be the very first call in the program). Those wrappers may also be buggy.

Unless you really need the portability to run your program on a variety of RTOSes, the CMSIS wrappers are just another layer that can have problems/bugs. I would suggest you try calling the FreeRTOS functions directly, and not use a wrapper.

Yeah, I know that using wrapper for RTOS is an additional complexity, that was not my choice but my boss. I personally think that adding additional complexity into firmware is a bad practice. It should as simple as it is possible, and CMSIS wrapper is not needed at all.

As I said, you need to report that bug (if it is a bug, and not a misuse of the function, read the documentation), then you need to report it to the supplier of the CMSIS wrapper.

If they don’t help, maybe you can report to your boss that the available CMSIS wrapper to too buggy to use, and get permission to use direct calls to FreeRTOS.

I debug it the second day, and what I found, IPSR register set its content to 32 after first call to the function in the main(). What is more interesting, it doesn’t happen all the day, sometimes IPSR is clear (i.e. contents 0), other time it contents 32. This is very interesting problem. If I am able to ensure that this is a bug concerning wrapper, I will report that to the supplier of CMSIS wrapper.

Looked up the ipsr, and that value indicates that your main is running now as if it was inside IRQ16, so maybe you have some problem in your program where you actually are getting into an interrupt before you get here.

Based on reference manual for STM32F401RE this number points to DMA1_STREAM5_IRQn which I do not use in my program.