STM32+cubeMX+FreeRTOS学习(1)

背景:

最近项目要在STM32L152上移植FreeRTOS轻量级系统,本文将从FreeRTOS的入门知识讲起,记录FreeRTOS的一些基本知识点和学习心得。

硬件平台:STM32L152 ,备注:PA12连接LED1,PA11连接LED2;

软件平台:keil v5和  cubeMx。

内容:

1.FreeRTOS简介

FreeRTOS是一种轻量级实时操作系统。RTOS:Real Time OperatingSystem实时操作系统。FreeRTOS可拆分为Free + RTOS,前面Free代表一种操作系统类型的名称,后面RTOS代表实时操作系统。

近几年,FreeRTOS的排名在嵌入式操作系统的排名中还是比较高的,且有不断上升趋势。

STM32+cubeMX+FreeRTOS学习(1)_第1张图片

2. cubeMX中FreeRTOS的生成及任务创建

首先,打开CUBEMX软件,点击NEW Project,选择芯片STM32L152RC;

 

STM32+cubeMX+FreeRTOS学习(1)_第2张图片

2,配置RCC时钟

STM32+cubeMX+FreeRTOS学习(1)_第3张图片

3,设置PA12和PA11为GPIO_OUTPUT;

STM32+cubeMX+FreeRTOS学习(1)_第4张图片

4,使能FREERTOS;

STM32+cubeMX+FreeRTOS学习(1)_第5张图片

5,设置时钟树,本例外部晶振8M,8倍频,2分频,得到32M;

STM32+cubeMX+FreeRTOS学习(1)_第6张图片

6,配置FREERTOS,创建两个任务;

STM32+cubeMX+FreeRTOS学习(1)_第7张图片

STM32+cubeMX+FreeRTOS学习(1)_第8张图片

STM32+cubeMX+FreeRTOS学习(1)_第9张图片

7,生成基于Keil V5的代码。

STM32+cubeMX+FreeRTOS学习(1)_第10张图片

8,添加LED点亮和熄灭程序;

STM32+cubeMX+FreeRTOS学习(1)_第11张图片

 编译运行,可以看到LED1和LED2 分别以不同的频率闪烁。

下面重点分析生成的代码:

STM32+cubeMX+FreeRTOS学习(1)_第12张图片

下面分析MX_FREERTOS_Init()函数;

void MX_FREERTOS_Init(void) 

{

  osThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128);//宏定义,定义了一个名为os_thread_def_Task_LED1的osThreadDef_t类型结构体,并赋值给各个成员变量。

  Task_LED0Handle = osThreadCreate(osThread(Task_LED1), NULL);//创建了LED1任务
  
  osThreadDef(Task_LED2, Func_LED2, osPriorityNormal, 0, 128);//宏定义,定义了一个名为os_thread_def_Task_LED2的osThreadDef_t类型结构体,并赋值给各个成员变量。
  Task_LED1Handle = osThreadCreate(osThread(Task_LED2), NULL);//创建了LED2任务

}

go to definition  of osThreadDef,该宏定义如下

#define osThreadDef(name, thread, priority, instances, stacksz)  \
const osThreadDef_t os_thread_def_##name = \
{ #name, (thread), (priority), (instances), (stacksz)}
#endif

上诉宏定义中出现了##和# 符号,其中

 

##是一个连接符号,用于把参数连在一起;   

#是“字符串化”的意思。出现在宏定义中的#是把跟在后面的参数转换成一个字符串。

 例如:

#define paster( n ) printf( "token" #n" = %d\n ", token##n )

所以paster(9);就是相当于 printf("token 9 = %d\n",token9);

那么osThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128);等价于下面的定义

#defineosThreadDef(Task_LED1, Func_LED1, osPriorityNormal, 0, 128) \
const osThreadDef_t os_thread_def_Task_LED1 = { Task_LED1,Func_LED1,osPriorityNormal, 0, 128}
#endif

总结:

本例中的两个任务函数Func_LED1和Func_LED2,他们实际占用CPU的时间很少,在调用osDelay()函数之后,它们就进入阻塞状态了,它们在等待“定时时间到”事件。在用户任务都进入阻塞状态时,运行的是空闲任务。空闲任务是启动调度器时自动创建的。

在调试过程中,尝试把两个任务函数的osDelay都改成500后,观察现象是LED1和LED2同时同频率的闪烁,但这和FreeRTOS中的某一任意时刻,只会有一个任务在运行,不会有同时两个任务在运行的理论相悖。之后分析发现,在调用osDelay()函数之后,它们就进入阻塞状态了,当500ms到时,LED1先切换至运行态,之后LED2切换至运行态,然后进入组态等待下一个500ms。LED1运行和切换到LED2这个时间非常短,以至于表面上看lED1和LED2同时运行,实际上依然是2个任务在不停的切换。

 

 

 

 

 

你可能感兴趣的:(FreeRTOS,STM32)