接上篇:RTOS超低功耗平台应用---FreeRTOS启动&任务创建
首先了解一下信号量,一般信号量主要实现两个功能:
1,两个任务之间或者中断函数跟任务之间的同步功能
2,多个共享资源的管理
FreeRTOS针对这两种功能分别提供了二值信号量和计数信号量,其中二值信号量可以理解成计数,即初始化为仅有一个资源可以使用。
实验是创建一个线程,该线程通过ISR发出的信号量打印按钮按下计数,包含一个LED闪烁任务。
- /**
- * @brief Start a Task.
- * @param argument: Not used
- * @retval None
- */
- static void vAppStartTask( void *pvParameters )
- {
- (void) pvParameters;
-
- for(;;)
- {
- BSP_LED_Toggle(LED2);
-
- vTaskDelay(200);
- }
- }
- /**
- * @brief Button Task.
- * @param argument: Not used
- * @retval None
- */
- static void prvAppButtonTask( void *pvParameters )
- {
- configASSERT( xTestSemaphore ); /* The assert function determines whether the semaphore is valid. */
-
- /* This is the task used as an example of how to synchronise a task with
- an interrupt. Each time the button interrupt gives the semaphore, this task
- will unblock, increment its execution counter, then return to block
- again. */
-
- /* Take the semaphore before started to ensure it is in the correct
- state. */
- xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
-
- for( ;; )
- {
- xSemaphoreTake( xTestSemaphore, portMAX_DELAY );
- ulButtonPressCounts++;
- printf("Button Press Counts:%d\r\n",ulButtonPressCounts);
- }
- }
- /**
- * @brief EXTI line detection callback.
- * @param GPIO_Pin: Specifies the pins connected EXTI line
- * @retval None
- */
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if(GPIO_Pin == KEY_BUTTON_PIN)
- {
- if (uwIncrementState == 0)
- {
- /* Change the Push button state */
- uwIncrementState = 1;
- }
- else
- {
- /* Change the Push button state */
- uwIncrementState = 0;
- }
- }
- }
复制代码 主函数中使用xSemaphoreCreateBinary() 创建信号量,- xTestSemaphore = xSemaphoreCreateBinary();
复制代码 按键检测任务中使用xSemaphoreTake()函数来获取信号量。按键检测使用外部中断,信号量使用完毕后的释放也是在终端服务函数中,如下
- xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK ); //获取信号,传入创建的信号量句柄xTestSemaphore
复制代码- /**
- * @brief EXTI15_10 IRQ
- * @param None
- * @retval None
- */
- void EXTI15_10_IRQHandler(void)
- {
-
- static BaseType_t xHigherPriorityTaskWoken;
-
- /* Inerrupt message handling */
- HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
-
- /* The handler releases a semaphore.
- xHigherPriorityTaskWoken has been initialised to zero. */
-
- if (utime_tick >= 200)
- {
- /* The second parameter of the send sync signal is used to save
- whether a high-priority task is ready.*/
- xSemaphoreGiveFromISR( xTestSemaphore, &xHigherPriorityTaskWoken );
- utime_tick = 0;
- }
复制代码
程序运行后会执行LED闪烁任务按键计数任务,当获取到信号量后计数值加1,同时释放信号量共下次资源可用。运行效果如下
|