互斥量由一个线程捕获并由另一个 CMSIS 和 FreeRTOS STM 板释放

Mutex captured by one thread and released by another CMSIS and FreeRTOS STM board

我们在 STM32F407 板上的 CMSIS 和 FreeRTOS 中遇到互斥锁问题。

有两个线程可以通过 UART 访问硬件无线电。我们正在使用互斥锁来确保一次只有一个线程可以与无线电通信。

使用SWO在每次捕获或者释放mutex成功后打印到串口,可以看到在某些情况下会出现以下情况:

据我了解,互斥体只能由当前持有互斥体的线程释放。

来自两个互斥调用的 return 值是 osOK。配置文件中已关闭递归互斥锁。两个线程的优先级相同。

可能相关的信息: CMSIS 1.02 版 FreeRTOS v. 8.2.1

SWO输出代码:

void SWO_write(char* output)
{
    for(int i = 0; i < strlen(output); i++)
    {
      ITM_SendChar(output[i]);
    }
}

每次在成功调用后立即捕获或释放互斥体时都会调用此代码。随调用结果一起传入空终止字符串。

我们使用的 CMSIS 和 FreeRTOS 配置确实允许一个线程释放被另一个线程捕获的互斥量。

我添加了一个新的互斥锁来测试一个线程是否可以捕获它而另一个线程可以释放它。我检查了调试器中每个调用的值,并且都 return osOK。 CMSIS/FreeRTOS 确实允许这种行为。这两个位置是唯一更改过互斥量的区域。

CMSIS 不要求获取互斥锁的线程与释放互斥锁的线程相同。来自 CMSIS-RTOS osMutexRelease 的文档:

osStatus osMutexRelease ( osMutexId mutex_id )

Release a Mutex that was obtained with osMutexWait. Other threads that currently wait for the same mutex will be now put into the state READY.

Status and Error Codes

  • osOK: the mutex has been correctly released.
  • osErrorResource: the mutex was not obtained before.
  • osErrorParameter: the parameter mutex_id is incorrect.
  • osErrorISR: osMutexRelease cannot be called from interrupt service routines.

注意不同线程获取和释放mutex时的条件没有错误码。

让同一个线程获取和释放互斥量是一个很好的设计,但 CMSIS 并未强制执行。