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

来源:互联网 发布:cms监控软件操作说明 编辑:程序博客网 时间:2024/06/07 19:24

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


未完 待续