假如有两个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正常翻转几次以后就无法正常翻转了。
未完 待续
上一篇:stm32 FreeRTOS中如何创建任务
下一篇:FreeRTOS学习笔记——基础知识与移植(STM32F103)
推荐阅读最新更新时间:2024-11-12 20:10
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LT3091IT7 的参考设计
- IP6538验证板
- 使用 Analog Devices 的 AD9640 的参考设计
- 点灯工程师
- 使用 ON Semiconductor 的 RC5051 的参考设计
- B-L475E-IOT01A1、STM32L4 探索套件物联网节点、低功耗无线、BLE、NFC、SubGHz、Wi-Fi
- AM3G-2405SZ 5V 3 瓦直流转直流转换器的典型应用
- LTC3826IG-1 高效双路 8.5V/3.3V 降压转换器的典型应用电路
- 使用 Analog Devices 的 LT1764EFE-3.3 的参考设计
- DER-870 - 使用 BridgeSwitch 电机驱动器和 LinkSwitch-TN2 的 400 W 三相逆变器