1、为什么要使用RTOS?
设计需求
1、LED等间隔500ms周期闪烁;
2、MCU间隔1s采集内部温度传感器数值;
3、MCU通过串口周期10s采集外部气压传感器模块数值;
状态机实现
定义一个状态机标志,StateMachine
开启MCU内部定时器,采用定时中断的方式,中断溢出1ms触发中断。在中断函数中累计并判断时间,T=500ms StateMachine = 0x0001,T=1s StateMachine = 0x0002,T=10s StateMachine = 0x0004。在大循环中对状态机进行判断,执行相应的操作。
RTOS实现
LEDTaskHandle = osThreadNew(StartLED, NULL, &LEDTask_attributes);
ADCTaskHandle = osThreadNew(StartADC, NULL, &ADCTask_attributes);
PRETaskHandle = osThreadNew(StartPressure, NULL, &PRETask_attributes);
void LEDTask(void *argument)
{
for(;;)
{
LED ~= LED;
osDelay(500);
}
}
void ADCTask(void *argument)
{
for(;;)
{
ADC
osDelay(1000);
}
}
void PRETask(void *argument)
{
for(;;)
{
PRE;
osDelay(10000);
}
}
从上面代码中可以看出,我们只需要创建三个任务分别处理设计需求即可。深入学习RTOS的调度机制以后,我们会知道RTOS的这种方式其实也是采用中断调度的方式进行控制的,只不过这些工作都是由系统已经为我们封装好了。
2、任务创建
/* Init scheduler */
osKernelInitialize();
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
myTask02Handle = osThreadNew(StartTask02, NULL, &myTask02_attributes);
/* Start scheduler */
osKernelStart();
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
TaskNumber = 1;
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
osDelay(500);
}
/* USER CODE END 5 */
}
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for(;;)
{
TaskNumber = 2;
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_10);
osDelay(2000);
}
/* USER CODE END StartTask02 */
}