大三了,在保研、考研、保研加分政策改变的焦虑中渡过了2021的前5个月。好久没有认真学东西了。不管了,先学点东西把手里的比赛做完,加不加分都随缘。
FreeRTOS-HAL库
一、简介
FreeRTOS是一个迷你的实时操作系统内核。
作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程
等,可基本满足较小系统的需要。
二、理解
main初始化函数中多了两个函数:
①MX_FREERTOS_Init()
是hal库自动生成的freertos任务创建函数
②osKernelStart()
是开启任务调度
任务调度开启之后,就正式进入FreeRTOS系统接管领域,之后程序只会跑在中断和任务函数中,这时候就可以对while(1)说再见了!
三、使用
3.1 移植FreeRTOS ---- 添加任务
【注意】基时建议选择TIM1
3.2 认识程序框架
1、Cude生成的Keil工程,架构从底往上依次是:内核、驱动层、硬件抽象层、应用层。
2、上三层跟裸机程序是一样的,主要增加了内核层
- croutine.c : 协程相关
- event_groups.c : 事件标志组相关
- tasks.c: 任务控制块:描述任务属性的结构体,用于任务创建、挂起、恢复、调度
- list.c: 列表和列表项,FreeRTOS的一种基础数据结构
- queue.c : 队列相关
- timers.c : 软件定时器相关
- heap_4.c : 内存管理相关
- port.c : 针对不同硬件平台的接口
3.3 阅读FreeRTOS.c与main.c
FreeRTOS.c
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/*--------创建 任务句柄【CubeMX 配置】----------*/
osThreadId defaultTaskHandle;
osThreadId myTask01Handle;
osThreadId myTask02Handle;
/*--------声明 任务处理函数【CubeMX 配置】----------*/
void StartDefaultTask(void const * argument);
void StartTask01(void const * argument);
void StartTask02(void const * argument);
/*--------声明 FREERTOS初始函数-------------------*/
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
*ppxIdleTaskStackBuffer = &xIdleStack[0];
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
/* place for user code */
}
/*--------初始化函数实现----对每个任务配置----------*/
void MX_FREERTOS_Init(void)
{
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
osThreadDef(myTask01, StartTask01, osPriorityIdle, 0, 128);
myTask01Handle = osThreadCreate(osThread(myTask01), NULL);
osThreadDef(myTask02, StartTask02, osPriorityIdle, 0, 128);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
}
/*--------默认任务 实现----------*/
void StartDefaultTask(void const * argument)
{
/* Infinite loop */
for(;;)
{
osDelay(1);
}
}
void StartTask01(void const * argument)
{
/* Infinite loop */
for(;;)
{
osDelay(1);
}
}
运行到osDelay() 系统就会把cpu让出来,给别的任务(取决于优先级)
main.c
MX_FREERTOS_Init(); //初始化RTOS
osKernelStart(); //开启调度命令,接下来就全归RTOS调度
3.4 A任务删除B任务
在A任务处理函数加:vTaskDelete(TaskBHandle)
四、实例:
两个任务向同一个串口发送消息,频率分别为1s每次和5s每次
void Task1(void const * argument)
{
/* USER CODE BEGIN Task1 */
/* Infinite loop */
for(;;)
{
uint8_t TxData[10]= "1111111111";
HAL_UART_Transmit(&huart4,TxData,10,0xffff);
osDelay(1000);
}
void Task2(void const * argument)
{
/* USER CODE BEGIN Task2 */
/* Infinite loop */
for(;;)
{
uint8_t TxData[10]= "2222222222";
HAL_UART_Transmit(&huart4,TxData,10,0xffff);
osDelay(5000);
}
}
————————————————
版权声明:本文为CSDN博主「外来务工人员徐某」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33033059/article/details/106677140
五、总结
注意 任务与任务间的通讯:①申明外部变量extern ②任务通讯机制
注意 串口中断&任务优先级 串口中断最高
配置完成后,在任务处理函数 实现自己原本的 算法即可。