当前位置: 首页 > news >正文

第27章_瑞萨MCU零基础入门系列教程之freeRTOS实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id=728461040949

配套资料获取:https://renesas-docs.100ask.net

瑞萨MCU零基础入门系列教程汇总: https://blog.csdn.net/qq_35181236/article/details/132779862


第27章 freeRTOS实验

本章目标

  • 学会使用RASC创建一个基于freertos的工程;
  • 学会使用RASC创建freertos任务,体验RTOS的多任务调度;

27.1 创建基于FreeRTOS的工程

使用RASC工具创建基于freertos的MDK工程非常的简单快捷,在前文创建MDK工程《3.5.1 使用RASC创建MDK工程》的最后一步那里,在“RTOS Selection”中选“FreeRTOS(v10.4.6+fsp.4.3.0)”即可,如下图所示:

接下来会默认勾选“FreeRTOS-Minimal-Static Allocation”:

到这一步后直接点击下方的“Finish”即可创建一个带有FreeRTOS的RA6M5 MDK工程了。

27.2 FreeRTOS初体验

27.2.1 新建线程

在RASC中新建线程非常简单,在其配置界面的“Stacks”中右侧界面的“Threads”处点击“New Thread”,即可新建一个FreeRTOS的线程,也就是任务,如下图所示:

上图中已经添加了两个线程“log_thread”和“led_thread”。

27.2.2 添加堆分配算法模块

添加完线程之后还需要添加堆分配算法,FreeRTOS支持5种堆算法:heap1~heap5。本实验选择的是heap4,首先选中任意一个FreeRTOS线程,比如“led_thread”,然后点击配置界面的“New
Stack”,找到“RTOS”后选择要使用的算法即可,如下图所示:

FreeRTOS中,只能选择一种堆算法。虽然上图里是在“led_thread”中为它选择了某个堆算法,但是这个堆算法不是“属于”某个线程,而是属于整个FreeRTOS的。你不能在另一线程里选择另一种堆算法。

27.2.3 配置FreeRTOS通用参数

要使用FreeRTOS,需要配置内核相关的许多参数,比如时钟基准,时钟频率,任务栈大小,分配内存时使用静态分配还是动态分配等等,这些参数在FSP种点击任意一个FreeRTOS线程即可看到关于内核的通用参数配置,然后根据自己的实际需求进行设置:

  1. Common-General

在此处设置RTOS内核运行的时钟频率、任务最大优先级等参数,如下图所示:

  1. Common-Memory Allocation

在此处设置内存分配相关的参数,比如是否支持静态内存分配、堆的大小,如下图所示:

  1. 其它通用参数

还有很多参数,比如是否支持任务通知、互斥量等等,FreeRTOS是一个可以高度定制的内核,要想弄清楚这些参数,需要对它比较熟悉。

27.2.4 配置线程参数

对于某个线程,需要设置它的名称、栈大小、优先级等参数,如下图所示:

27.2.5 驱动程序

本实验使用的是串口和LED的驱动程序,请读者自行移植。

27.2.6 线程程序

  1. LED线程

在LED的线程入口函数中,本实验先对LED设备进行初始化,然后每隔300ms改变一次LED的状态以实现闪烁效果,代码如下:

#include "led_thread.h"
#include "drv_gpio.h"
#include "hal_data.h"
/* LedThread entry function */
/* pvParameters contains TaskHandle_t */
void led_thread_entry(void * pvParameters)
{FSP_PARAMETER_NOT_USED(pvParameters);/* TODO: add your own code here */struct IODev *pLedDev = IOGetDecvice("UserLed");if(NULL != pLedDev)pLedDev->Init(pLedDev);bool state = false;while(1){pLedDev->Write(pLedDev, state);state = !state;vTaskDelay(300);}
}

需要注意的是这里使用的是RTOS内核的延时函数,它让当前线程进入阻塞状态,让出处理器资源。

  1. 串口打印线程

在串口打印线程的入口函数中,首先初始化了串口,然后每隔100ms计数一次并打印出来,代码如下:

#include "log_thread.h"
#include "drv_uart.h"
#include "hal_data.h"
#include <stdio.h>
/* LogThread entry function */
/* pvParameters contains TaskHandle_t */
void log_thread_entry(void * pvParameters)
{FSP_PARAMETER_NOT_USED(pvParameters);/* TODO: add your own code here */UARTDrvInit();uint32_t count = 0;while(1){printf("\r\nLog: %d\r\n", count++);vTaskDelay(100);}
}

27.2.7 FreeRTOS启动分析

FreeRTOS的启动过程,看main函数即可。创建2个线程后,启动调度器。代码如下:

int main(void)
{g_fsp_common_thread_count = 0;g_fsp_common_initialized = false;/* Create semaphore to make sure common init is done before threads start running. */g_fsp_common_initialized_semaphore =#if configSUPPORT_STATIC_ALLOCATIONxSemaphoreCreateCountingStatic(#elsexSemaphoreCreateCounting(#endif256,1#if configSUPPORT_STATIC_ALLOCATION, &g_fsp_common_initialized_semaphore_memory#endif);if (NULL == g_fsp_common_initialized_semaphore) {rtos_startup_err_callback(g_fsp_common_initialized_semaphore, 0);}/* Init RTOS tasks. */led_thread_create();log_thread_create();/* Start the scheduler. */vTaskStartScheduler();return 0;
}
  • 第07~22行:创建了一个计数型信号量;
  • 第25~26行:创建线程;
  • 第29行:开启FreeRTOS的调度器,如果开启成功则不会走到30行的“return 0”;

对于RASC创建的FreeRTOS工程,它不会调用hal_entry()函数。

27.2.8 测试结果

将编译出来的二进制可执行文件烧录到板子上运行,可以观察到LED在闪烁,而且串口在打印如下图这样的信息:


本章完
http://www.lryc.cn/news/165733.html

相关文章:

  • Java学习之--类和对象
  • Unity技术手册-UGUI零基础详细教程-Canvas详解
  • 破天荒呀!小杜微信有名额了
  • 领域驱动设计:领域模型与代码模型的一致性
  • TypeScript命名空间和模块
  • C++学习笔记--函数重载(1)
  • 交叉编译poco-1.9.2
  • C++中如何处理超长的数字(long long类型的整数都无法存储的)
  • RabbitMQ MQTT集群方案官方说明
  • 深圳唯创知音电子将参加IOTE 2023第二十届国际物联网展•深圳站
  • 《TCP/IP网络编程》阅读笔记--I/O复用
  • [C#] 允许当前应用程序通过防火墙
  • 帆软FineReport决策报表Tab实现方案
  • 只打印文名
  • 【经典小练习】JavaSE—拷贝文件夹
  • FPGA-结合协议时序实现UART收发器(六):仿真模块SIM_uart_drive_TB
  • Spring Boot集成EasyExcel实现数据导出
  • EasyExcel3.0读(日期、数字或者自定义格式转换)
  • 浅谈C++|STL之vector篇
  • 微信、支付宝修改步数【小米运动】
  • stu02-初识HTML
  • 软件测试7大误区
  • 【深度学习】 Python 和 NumPy 系列教程(十二):NumPy详解:4、数组广播;5、排序操作
  • CSS宽度问题
  • 浅谈C++|STL之string篇
  • Kubernetes Dashboard安装部署
  • 在Qt的点云显示窗口中添加坐标轴C++
  • [密码学入门]凯撒密码(Caesar Cipher)
  • uboot 顶层Makefile-make xxx_deconfig过程说明三
  • c++中的多线程通信