信号量
1 信号量用于共享资源的访问:
2 信号量用于任务同步:
为什么一直说在中断服务函数中,不能够做太多的事情?
在进入中断服务函数时,低优先级的中断就不能响应,同类型的中断也无法响应,所以就要求ISR一定要短,快进快出。
最好的解决方案时,在中断服务函数中发送一个信号量,在任务中等待信号量,实现任务同步。
二值信号量
二值信号量简介:
二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的,这不正好就是二值的吗? 任务和中断使用这个特殊队列不用在乎队列中存的是什么消息,只需要知道这个队列是满的还是空的。可以利用这个机制来完成任务与中断之间的同步。
二值信号量执行流程:
创建信号量:
动态创建二值信号量:
实际上,信号量就是通过队列来实现的,源码如下:
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ((uint8_t)0U)
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
#define xSemaphoreCreateBinary() xQueueGenericCreate((UBaseType_t)1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE)
实际上,就是调用创建队列的函数。
信号量的创建方式如下所示:
释放信号量:
获取信号量:
获取函数参数说明:
中断中获取信号量:
二值信号量测试:
串口中断服务函数中接收数据,接收完成后(IDLE)释放二值信号量,任务中获取信号量,根据串口数据来响应。
程序如下所示:
uint8_t RX_BUFFER[USART_BUFFER_LEN];
SemaphoreHandle_t binary_semaphore = NULL;
void start_task(void *pvParameters)
binary_semaphore = xSemaphoreCreateBinary();
if (binary_semaphore != NULL)
xTaskCreate((TaskFunction_t )task1_task,
(uint16_t )TASK1_TASK_SIZE,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t * )&task1_task_Handle);
xTaskCreate((TaskFunction_t )task2_task,
(uint16_t )TASK2_TASK_SIZE,
(UBaseType_t )TASK2_TASK_PRIO,
(TaskHandle_t * )&task2_task_Handle);
vTaskDelete(start_Task_Handle);
void task1_task(void *pvParameters)
printf("task1 running\r\n");
void task2_task(void *pvParameters)
if (binary_semaphore != NULL)
err_state = xSemaphoreTake(binary_semaphore, portMAX_DELAY);
if (strcmp((char *)RX_BUFFER, "LED_ON") == 0)
if (strcmp((char *)RX_BUFFER, "LED_OFF") == 0)
if (strcmp((char *)RX_BUFFER, "BEEP_ON") == 0)
if (strcmp((char *)RX_BUFFER, "BEEP_OFF") == 0)
memset(RX_BUFFER, 0, USART_BUFFER_LEN);
printf("we get %d times binary\n", ++count);
void USART1_IRQHandler(void)
BaseType_t pxHigherPriorityTaskWoken;
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE))
RX_BUFFER[i++] = huart1.Instance->DR;
__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
if (binary_semaphore != NULL)
error_state = xSemaphoreGiveFromISR(binary_semaphore, &pxHigherPriorityTaskWoken);
if (error_state != pdTRUE)
if (pxHigherPriorityTaskWoken == pdTRUE)
temp = huart1.Instance->SR;
temp = huart1.Instance->DR;
测试结果:
转载于:https://blog.csdn.net/dingyc_ee/article/details/104108665
文章评论(0条评论)
登录后参与讨论