采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。
**FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。**而且最重要的一点,freertos完全免费,而且非常方便移植,在hal库里可以直接使用。
hal库打开FreeRTOS非常方便
然后初始化所有需要的外设之后,进入工程
加入FreeRTOS之后,main初始化函数中多了两个函数:
**MX_FREERTOS_Init()**是hal库自动生成的freertos任务创建函数,其中的内容在后面会讲到
**osKernelStart()**是开启任务调度,进去看看
里面就是FreeRTOS提供的API中一个开启任务调度的函数vTaskStartScheduler()
任务调度开启之后,就正式进入FreeRTOS系统接管领域(其实操作系统在启动时就已经存在,只是可以这么理解),之后程序只会跑在中断和任务函数中,这时候就可以对while(1)说再见了!
那么接下来就可以创建任务函数,hal库默认生成的底层是在freertos.c文件中创建并运行任务函数
在freertos.c文件中可以发现前面main.c中看到的MX_FREERTOS_Init()
原函数是这样的
void MX_FREERTOS_Init(void) {
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
}
这其中就是自动生成了一个任务函数的创建,相当于给一个模板,你要再创建新的任务函数就按这个模板来套。
任务函数创建完成之后,那么程序怎么跑在任务函数中呢,freertos.c文件下面还有一个函数
void StartDefaultTask(void const * argument)
{
for(;;)
{
osDelay(1);
}
}
这个就是hal库默认创建的任务函数StartDefaultTask执行程序的地方,任务函数初始化完成之后,任务调度开启,程序就会跑在这个任务函数里了,由于hal库只默认生成了一个任务函数,所以程序就只会跑在这一个任务函数中。
那么如果要多创建几个任务函数,也就是多线程,可以按照hal库给的模板再多创建几个,但是如果这几个函数全部挤在一个freertos.c文件中,好像太冗杂了,可以这样做
创建一个Init_Task.c文件,用来做任务函数和驱动的初始化,再多加几个c文件,一般用得到几个任务函数就创建几个,这里暂时只用到两个
在Init_Task.c文件中进行任务函数和驱动的初始化:
osThreadId Init_TaskHandle;
osThreadId Test_TaskHandle;
osThreadId Display_TaskHandle;
void Task_Init(void);
void Driver_Init(void);
void Init_Task(void const * argument)
{
Driver_Init();
vTaskDelete(Init_TaskHandle);
}
void Task_Init(void)
{
osThreadDef(Init_Task, Init_Task, osPriorityHigh, 0, 128);
Init_TaskHandle = osThreadCreate(osThread(Init_Task), NULL);
osThreadDef(Test_Task, Test_Task, osPriorityNormal, 0, 128);
Test_TaskHandle = osThreadCreate(osThread(Test_Task), NULL);
osThreadDef(Display_Task, Display_Task, osPriorityNormal, 0, 128);
Display_TaskHandle = osThreadCreate(osThread(Display_Task), NULL);
}
void Driver_Init(void)
{
}
要注意的一点是,头文件中必须包含内核文件cmsis_os.h,内核文件中包含了任务句柄结构体,任务初始化结构体等
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
osThreadId osThreadGetId (void);
到这,任务函数创建完毕
但是,如果不在main中将任务创建函数加进去,任务调度是到不了这的,所以要在main中**Task_Init()**加进去
这样,任务调度函数启动之后,程序就会跑在创建的几个任务函数中
其他任务函数也可以和Init_Task()一样
例如:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)