你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32超低功耗平台上的RTOS培训 -- 实验2 中断和任务同步(信....

[复制链接]
TLLED 发布时间:2018-4-17 10:26
接上篇:STM32超低功耗平台上的RTOS培训 -- 实验1 任务创建



FreeRTOS中断方式的二值信号量是实现中断函数与任务之间的同步。



    程序任务框图:
    下面是本程序实现中断函数与任务之间同步的框图:
      1.jpg


     程序执行的条件:
    > 创建两个任务:一个任务vAppStartTask()用于LED2指示灯闪烁;
                              一个任务prvAppButtonTask()用与等待中断后,通过串口发送按键次数;
    > 二值信号量的初始值为0,按键中断调用xSemaphoreGiveFromISR();函数释放信号量。任务prvAppButtonTask()调用xSemaphoreTake()函数获取信号量资源。
   执行过程描述:
    > 任务vAppStartTask()用于LED2指示灯闪烁,和信号量之前没有关联;
    > 任务prvAppButtonTask()运行过程中调用xSemaphoreTake()函数,由于信号量的初始值为0,没有信号量资源可用,任务prvAppButtonTask()由运行态进入到阻塞态,串口无数据输出。
    > 按键后,发生外部中断,中断发生,中断程序中调用xSemaphoreGiveFromISR()函数,释放信号量资源,信号量数值加1,此时信号量计数值为1,任务prvAppButtonTask()由阻塞态进入就绪态,在调度器的作用下由就绪态进入到运行态。任务prvAppButtonTask()获得信号量后,信号量数值减1,此时信号量值又变成0。
    > 再次循环执,任务prvAppButtonTask()由于没有信号量资源可用,再次进入阻塞态重复执行。

    程序执行:
        > 板子上LD2闪烁
        > 串口输出数据: 按一下板子上B1 USER按键,串口输出一帧数据。
    2.jpg

    程序相关的代码:为了便于查看有关信号量相关的函数位置,只截取程序中相关函数。

int main(void)
{
        HAL_Init();
        SystemClock_Config();
        __HAL_RCC_PWR_CLK_ENABLE(); //Modified by ST MCU China Team, Added by JWR 2018.01.29
        
        /* Initialize LED */
        BSP_LED_Init(LED1);
        BSP_LED_Init(LED2);
        
        /* Initialize buttons */
        BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
        
        /* Configure  Uart */
        BSP_Uart_Init();
        
        
        //vSemaphoreCreateBinary( xTestSemaphore );
        xTestSemaphore = xSemaphoreCreateBinary();   //创建二值信号量,首次创建信号量计数值为0
        xTaskCreate(
                     vAppStartTask,
                     "Start",
                     configMINIMAL_STACK_SIZE,
                     NULL,
                     Start_TASK_PRIORITY,
                     ( TaskHandle_t * ) NULL
                    );
        
        xTaskCreate(
                      prvAppButtonTask,
                      "ButTest",
                      configMINIMAL_STACK_SIZE,
                      ( void * ) NULL,
                      But_TEST_PRIORITY,
                      NULL
                   );
        
        vTaskStartScheduler();
        for (;;);
}

/**
* @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 函数确定信号量是否有效
        
        //获取信号量,等待时间为0,则xSemaphoreTake()在信号量无效时会立刻返回
        xSemaphoreTake( xTestSemaphore, mainDONT_BLOCK );
        
        for( ;; )
        {
                xSemaphoreTake( xTestSemaphore, portMAX_DELAY ); //获取信号量,超时时间为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;
                }
        }  
}

/**
* @brief  EXTI15_10 IRQ
* @param  None
* @retval None
*/
void EXTI15_10_IRQHandler(void)
{
        
        static BaseType_t xHigherPriorityTaskWoken;  //高优先级任务是否被唤醒的状态保存                    
        
        HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);    //中断消息处理                             
      
        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;
        }
        //如果 xHigherPriorityTaskWoken = pdTRUE,则切换到当前最高任务执行,然后退出中断
        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}


/**
* @brief  FreeRTOS Tick Hook FUNC
* @param  None
* @retval None
*/
void vApplicationTickHook()
{
        utime_tick++;        /*Use for button glitch filter,It's not for the freertos kernel*/
        if (utime_tick >= 65535)
        {
                utime_tick = 200;
        }
}


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/










收藏 1 评论2 发布时间:2018-4-17 10:26

举报

2个回答
zero99 回答时间:2018-4-17 14:53:16
支持下
蓝夜 回答时间:2018-7-21 10:48:13
写的很好,突出了重点

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版