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

    假如有两个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正常翻转几次以后就无法正常翻转了。


未完 待续




  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值