0 前言
本次实验要使用FreeRTOS嵌入式实时操作系统,之前几个实验都是在裸机上跑的,但当我们要多线程操作时,就需要用到RTOS(Real-Time Operating System)。
通常我们裸机开发要做软件延时用的是FSP库R_BSP_SoftwareDelay
函数,它是阻塞式运行的。而在FreeRTOS实时操作系统开发里面使用到vTaskDelay
函数,它是对CPU的时分复用,系统将这个任务挂起,让CPU去执行其他任务,一旦时间到了,就再回到先前的任务继续执行。
1 软件部分
1.1 新建工程
类似先前的实验步骤,先来创建工程 https://bbs.elecfans.com/jishu_2468424_1_1.html,注意在RTOS这里选择FreeRTOS。
1.2 配置LED对应的GPIO
与先前点亮LED实验的步骤一样,配置P113和P207均为Output Mode
1.3 新增线程(Threads)
点击Stacks选项卡--在左侧的New Thread -- 点击新创建的Thread 属性 -- 修改Name和Symbol,下图所示的是LED1线程,LED2的同理。
1.4 选择堆算法
接着为堆选择算法,这里一共有1~5共5个算法可选,每种算法介绍如下:
Heap_1:这是最简单的内存分配实现,它不允许释放已分配的内存。这意味着一旦内存被分配出去,就不能被回收,这可能导致内存的快速耗尽。
Heap_2:与Heap_1相比,Heap_2允许内存的释放。但是,它不会合并相邻的空闲内存块,因此可能会导致内存碎片化。
Heap_3:Heap_3使用标准的malloc()和free()函数来管理内存,因此堆的大小由链接器配置决定,而不是由FreeRTOS的配置文件设置。
Heap_4:Heap_4在Heap_2的基础上进行了改进,它会合并相邻的空闲内存块,从而减少内存碎片化的可能性。Heap_4使用“第一次适应算法”来分配内存,通常建议作为内存管理的首选方案。
Heap_5:Heap_5与Heap_4类似,但它支持从多个非连续的内存块中分配内存,这对于系统内存不是连续块的情况非常有用。`
这里我选择Heap 4算法。
点击LED1 -- New Stack -- RTOS -- FreeRTOS Heap4
接下来可能会报错,要开启动态内存分配。点击LED1这个线程 -- 在属性里Support Dynamic Allocation 改为 Enabled
1.5 编写代码
保存配置文件,生成项目代码。
在左侧会多出LED1_thread_entry.c
和LED2_thread_entry.c
,这两个文件是留给我们写线程具体功能的。
在LED1_thread_entry.c
中的死循环中添加代码
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_HIGH);
vTaskDelay (500);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_13, BSP_IO_LEVEL_LOW);
vTaskDelay (500);
在LED2_thread_entry.c
中的死循环中添加代码
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_HIGH);
vTaskDelay (800);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, BSP_IO_LEVEL_LOW);
vTaskDelay (800);
上面代码是让P113对应的LED灯亮灭各500ms,P207对应的LED灯亮灭各800ms
在hal_entry.c
的hal_entry函数中添加代码,用来开启线程
LED1_thread_entry();
LED2_thread_entry();
2 实际效果
编译、烧录。
观察现象,可以看出两颗LED的亮灭时间并不相同,但每隔8s会同时亮一下(500ms*2 与 800ms*2的最小公倍数为8s)
该现象可以通过下方视频看出。
3 附件
*附件:05_FreeRTOS.zip