c - 用于将中断与 FreeRTOS 中的任务同步的二进制信号量
问题描述
大家好,我正在使用 RTOS 迈出第一步。UART
我试图在中断模式下接收大量数据。我有一个显示任务,其中命令被写入全局缓冲区,我刚刚创建了一个UART Handler Task
我想读取字节的位置。我面临的问题是。
- 我在里面使用的信号量
UART Task
是未知的,即使我在主函数中声明它是全局的,所以xSemaphoreTake()
函数在那里有错误。也许一个有用的注意:这UART Task
是在一个单独的文件中。 - 我的实现
HAL_UART_RxCpltCallback
是UART Task
干净的吗?
这是我写的代码:
SemaphoreHandle_t uartInterruptSemaphore = NULL;
int main(void)
{
/* USER CODE BEGIN 1 */
void mainTask(void* param) {
uartInterruptSemaphore = xSemaphoreCreateBinary();
if(uartInterruptSemaphore != NULL) {
// Display Thread with a 2 priority
xTaskCreate(&displayTask, "Display Thread", 1000, &huart4, 2, NULL);
// deferred Interrupt to be synchronized with the Display Task, must have a higher priority than the display task
xTaskCreate(&UartHandlerTask, "UART Handler Task", 1000, &huart4, 3, NULL);
}
for(;;){
}
}
我写的回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *uart_cb) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if(uart_cb->Instance == USART4) {
xSemaphoreGiveFromISR(uartInterruptSemaphore, &xHigherPriorityTaskWoken);
}
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
和处理程序任务:
void UartHandlerTask(void* param) {
huart_cache = param;
const uint8_t tmp = rx_byte; //rx byte is global volatile variable
for(;;){
if(xSemaphoreTake(uartInterruptSemaphore, portMAX_DELAY) == pdPASS) {
HAL_UART_Receive_IT((UART_HandleTypeDef *)huart_cache, (uint8_t *)&rx_byte, 1);
// write data to the buffer
RX_interrupt(tmp);
}
}
}
解决方案
我建议在尝试使用 RTOS 之前更好地处理 C。与使用二进制信号量相比,这还将向您展示一种从中断中解除阻塞任务的更好方法:https ://www.freertos.org/2020/09/decrease-ram-footprint-and-accelerate-execution-with-freertos -notifications.html
推荐阅读
- ruby-on-rails - 如何在 ruby on rails 中使用 Ajax 正确运行分页
- spring - 外部化 application.properties
- cmake - 如何为cmake设置包含顺序
- json - 由于数据类型,解析 Json 返回错误
- c# - 如何使用 Google.Apis.Sheets.v4.Data.FindReplaceRequest?
- ajax - Yii2 Kartik 可编辑小部件
- ubuntu - Ejabberd 在没有任何日志的情况下终止
- mysql - SQL查询打印部分字符串值
- redux-saga - yield 和 yield put() 函数的区别
- html - 为什么 CSS Grid 的自动填充属性在列方向上不起作用