stm32 - STM32 FreeRTOS - UART延迟中断问题
问题描述
我正在尝试使用 UART 接收中断读取大小未知的数据。在回调函数中,我启用了 Rx 中断以读取字符,直到获得 \n。如果 \n 被获取,则被延迟中断处理程序的更高优先级任务被唤醒。问题是我尝试通过回调函数逐个读取字节,并尝试将每个字符放入缓冲区,但不幸的是缓冲区无法获取任何字符。此外,延迟中断处理程序无法被唤醒。
我的STM32板子是STM32F767ZI,我的IDE是KEIL。
分享代码前的一些重要说明: 1. rxIndex 和 gpsBuffer 被声明为全局。2. 周期功能正常工作。
这是我的代码:
- 周期函数,优先级 = 1
void vPeriodicTask(void *pvParameters)
{
const TickType_t xDelay500ms = pdMS_TO_TICKS(500UL);
while (1) {
vTaskDelay(xDelay500ms);
HAL_UART_Transmit(&huart3,(uint8_t*)"Imu\r\n",sizeof("Imu\r\n"),1000);
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
}
}
- 延迟中断,优先级 = 3
void vHandlerTask(void *pvParameters)
{
const TickType_t xMaxExpectedBlockTime = pdMS_TO_TICKS(1000);
while(1) {
if (xSemaphoreTake(xBinarySemaphore,xMaxExpectedBlockTime) == pdPASS) {
HAL_UART_Transmit(&huart3,(uint8_t*)"Semaphore Acquired\r\n",sizeof("Semaphore
Acquired\r\n"),1000);
// Some important processes will be added here
rxIndex = 0;
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
}
}
}
- 回调函数:
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
gpsBuffer[rxIndex++] = rData;
if (rData == 0x0A) {
BaseType_t xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
}
- 主功能
HAL_UART_Receive_IT(&huart3,&rData,1);
xBinarySemaphore = xSemaphoreCreateBinary();
if (xBinarySemaphore != NULL) {
//success
xTaskCreate(vHandlerTask,"Handler",128,NULL,1,&vHandlerTaskHandler);
xTaskCreate(vPeriodicTask,"Periodic",128,NULL,3,&vPeriodicTaskHandler);
vTaskStartScheduler();
}
解决方案
使用 HAL 是解决问题的最佳方法。它使用依赖于 systick 的 HAL_Delay,你应该重写这个函数来读取 RTOS 滴答声。
我使用队列来传递数据(对数据的引用),但它应该可以工作。使用 HAL 函数时总是有一个很大的问号。
void HAL_UART_RxCptlCallBack(UART_HandleTypeDef *huart)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
gpsBuffer[rxIndex++] = rData;
if (rData == 0x0A) {
if(xSemaphoreGiveFromISR(xBinarySemaphore,&xHigherPriorityTaskWoken) == pdFALSE)
{
/* some error handling */
}
}
HAL_UART_Receive_IT(huart,(uint8_t*)&rData,1);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
最后,如果我使用 HAL 和 RTOS,我总是会修改 HAL 处理超时的方式。
推荐阅读
- mysql - MySQL查询以减去第一行的第一列和第二行的第二列
- php - 电子邮件验证 PHP 中的一个条件和多于一个 else 语句
- java - Spring boot:用户“postgres”的密码认证失败
- python - 将 pd.Series 字符串转换为 ndarray
- java - FFT 或 IFFT 丢失数据
- sql - 为什么 Oracle SQL 中的 ADD_MONTHS 函数存在问题
- python - Django 处理匿名用户
- c++ - 使用 Rcpp 在 Ubuntu Xenial 上抛出 std::runtime_error 时出现段错误
- python - 如何在不创建新环境的情况下使用 yml 文件安装 python 库列表
- python - 如何从包含数字列表的熊猫单元格中检索特定元素