×
单片机 > 单片机程序设计 > 详情

STM32CubeMX+FreeRTOS实验---使用两个实例,共用一个task

发布时间:2020-06-01 发布时间:
|

    假如有两个Task,行为类型,只是个别参数不一样。那么可以使用同一个task,来实现两个实例。这两个实例是相互独立的:Each created instance will execute independently

under the control of the FreeRTOS scheduler.


   以两个LED的task任务为例子,假设LED1和LED2都是每1s变换一次。那么,建立2个task:分别是LED1Flash和LED2Flash,使用同样的task入口:StartLEDFlashTask



生成iar工程后,在main.c中有 以下代码:


/* Create the thread(s) */

  /* definition and creation of LED1Flash */

  osThreadDef(LED1Flash, StartLEDFlashTask, osPriorityNormal, 0, 128);

  LED1FlashHandle = osThreadCreate(osThread(LED1Flash), NULL);

 

  /* definition and creation of LED2Flash */

  osThreadDef(LED2Flash, StartLEDFlashTask, osPriorityLow, 0, 128);

  LED2FlashHandle = osThreadCreate(osThread(LED2Flash), NULL);

只是一个定义


osThreadDef只是一个定义,把相关的内容绑在一起,不是函数。

osThreadCreate才是一个函数。第二个参数就是*argument,对应StartLEDFlashTask函数的输入参数。


因此在osThreadDef之前加入code。


/*import user code,may be changed by stm32cubeMX*/

/*take attention */

    uint16_t led1pin,led2pin = 0 ; 

    led1pin = GPIO_PIN_4 ;

    led2pin = GPIO_PIN_5 ;

另外,osThreadCreate需要改成


 LED1FlashHandle = osThreadCreate(osThread(LED1Flash), (void *)(&led1pin));

 

LED2FlashHandle = osThreadCreate(osThread(LED2Flash), (void *)(&led2pin));

在StartLEDFlashTask函数改成

/* USER CODE BEGIN 5 */

    uint16_t * pxledpin ;

    pxledpin = (uint16_t *)argument ;

  /* Infinite loop */

  for(;;)

  {

    osDelay(1000);

    HAL_GPIO_TogglePin(GPIOA, (*pxledpin));

    

  }

  /* USER CODE END 5 */ 

 

两个灯就能同时点亮和熄灭了 。


查看IAR内嵌的FreeRTOS插件,可以看到,这两个task只是共用代码,但是stack和任务的优先级是独立的。



也就是说,在上面的代码里面,pxledpin是task里定义的局部变量,是保存在任务的stack里面。因此两个任务有两个独立的pxledpin变量。




假如需要两个led分别闪烁,可以在main.c加入以下代码


全局部分


typedef struct

{

uint16_t ledpin ;

uint32_t timer ;

}LEDFlashPara_TypeDef ;

 main主函数部分修改为


  LEDFlashPara_TypeDef led1para,led2para ;

  led1para.ledpin = GPIO_PIN_4 ;

  led1para.timer = 1000 ;

  

  led2para.ledpin = GPIO_PIN_5 ;

  led2para.timer = 500 ;

  

  /* Create the thread(s) */

  /* definition and creation of LED1Flash */

  osThreadDef(LED1Flash, StartLEDFlashTask, osPriorityNormal, 0, 128);

  LED1FlashHandle = osThreadCreate(osThread(LED1Flash), (void *)(&led1para));

 

  /* definition and creation of LED2Flash */

  osThreadDef(LED2Flash, StartLEDFlashTask, osPriorityLow, 0, 128);

  LED2FlashHandle = osThreadCreate(osThread(LED2Flash), (void *)(&led2para));


Task部分修改为

LEDFlashPara_TypeDef ledpara ;

ledpara = *( (LEDFlashPara_TypeDef *)argument) ;

   

  /* Infinite loop */

  for(;;)

  {

    osDelay(ledpara.timer);

HAL_GPIO_TogglePin(GPIOA, ledpara.ledpin);

  }

这样两个任务就能按照不同的频率同时正常工作了

如果把task部分修改为以下代码:


LEDFlashPara_TypeDef *pledpara ;

pledpara = (LEDFlashPara_TypeDef *)argument ;

   

  /* Infinite loop */

  for(;;)

  {

    osDelay(pledpara->timer);

HAL_GPIO_TogglePin(GPIOA, pledpara->ledpin);

  }

就会发现LED1的task正常翻转几次以后就无法正常翻转了。




未完 待续




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯