FreeRTOS学习笔记——总览

考虑到RTOS能够提升单片机开发能力,也是开发复杂任务的必经之路,还是有必要学习的。
FreeRTOS教程多,免费开源,是个不错的选择。后续可以考虑继续学习RT-Thread等。
参考1:FreeRTOS(教程非常详细)——作者:不秃也很强
参考2:部分内容由GPT生成,请注意核实。

一、FreeRTOS简介

FreeRTOS 是一个开源、实时操作系统 (RTOS),它提供了对多任务处理、资源管理和硬件抽象的支持。它主要用于嵌入式系统开发,特别适合资源受限的环境。以下是对 FreeRTOS 的简介,包括其特点、优缺点等内容:

FreeRTOS 简介

FreeRTOS 是一个功能强大的实时操作系统,广泛应用于嵌入式系统中。它轻量且高效,适用于对时间要求较高的应用场景,如自动化控制、工业设备、智能家居设备等。作为一个实时操作系统,FreeRTOS 支持多任务调度,并提供了诸如任务优先级、队列、信号量、互斥量等基本的同步机制。

特点

  1. 轻量级:
    FreeRTOS 内核非常小巧,适用于资源受限的嵌入式系统。它的内核代码可以精简到几 KB 的大小,适合存储空间有限的设备。

  2. 优先级调度:
    FreeRTOS 支持基于优先级的任务调度,用户可以为任务分配不同的优先级,并根据任务的优先级进行调度。

  3. 支持多种架构:
    FreeRTOS 支持多种微处理器架构,包括 ARM Cortex-M、AVR、PIC、RISC-V 等。可以在多种硬件平台上进行移植。

  4. 可配置性强:
    FreeRTOS 是高度可配置的,用户可以根据项目的需要定制调度策略、内存管理方案以及其他系统资源的管理方式。

  5. 广泛的社区支持:
    作为一个开源项目,FreeRTOS 拥有强大的社区支持,用户可以轻松获取文档、示例代码和开发者论坛的帮助。

  6. 实时性:
    FreeRTOS 是为实时应用设计的,支持精确的任务调度和时间管理,能够保证高优先级任务的及时响应。

  7. 集成丰富的同步机制:
    提供了信号量、队列、互斥量等同步机制,支持多任务之间的通信和协调。

  8. 低功耗支持:
    FreeRTOS 支持低功耗管理,适合电池供电的设备,能够根据任务需求调整处理器的工作状态。

优点

  1. 开源和免费:
    FreeRTOS 是完全开源的,可以自由使用并根据需要修改源代码,这使得它特别适合学术研究和商业产品开发。

  2. 高度可移植:
    支持多种硬件平台和编译器,开发者可以在不同的硬件上移植和使用 FreeRTOS。

  3. 灵活的任务管理:
    提供了丰富的任务调度功能,能够在多任务系统中灵活管理任务,包括任务创建、删除、挂起、恢复等。

  4. 实时性能:
    对实时任务的响应时间控制严格,适合需要严格时间约束的嵌入式系统。

  5. 广泛应用和成熟:
    已经被广泛应用于各类商业产品中,经过了大量实际应用的验证,具有很高的稳定性。

缺点

  1. 功能相对简单:
    虽然 FreeRTOS 提供了多任务管理和基本的同步机制,但其功能相较于一些更复杂的操作系统(如 Linux)较为简单,不支持复杂的进程管理、文件系统和网络协议栈。

  2. 调试较难:
    由于是嵌入式系统,调试 FreeRTOS 程序通常比较复杂。虽然有一些调试工具,但相比于标准操作系统,嵌入式开发环境的调试仍然面临一些挑战。

  3. 内存管理:
    FreeRTOS 的内存管理功能相对较为基础,缺乏先进的内存保护和虚拟内存管理,可能导致一些内存溢出等问题。

  4. 不适合复杂的任务管理:
    FreeRTOS 的多任务支持适合简单到中等复杂度的任务管理,对于需要大量进程、线程调度和高效资源管理的大规模应用可能不太适用。

总结

FreeRTOS 是一个非常适合嵌入式系统的小型实时操作系统,它提供了强大的多任务处理能力和良好的实时性支持,尤其适合资源有限、对时间要求严格的应用。它的开源特性和高可配置性使得它在嵌入式领域有着广泛的应用,但对于需要更复杂功能的系统,可能需要考虑其他更强大的 RTOS 或操作系统。

希望这个简介能够帮助你理解 FreeRTOS 的基本概念,后续可以在博客中进一步深入探讨具体的使用场景和移植过程。

二、函数名前缀和参数命名规范

在 FreeRTOS 中,函数名前缀和参数命名通常有一些约定,这些约定有助于区分不同类型的变量、函数或对象的作用。下面是一些常见的命名约定,解释了这些前缀的含义:

1. x 前缀

  • x 是 FreeRTOS 中非常常见的前缀,表示 “变量”。它用于标识一个 结构体、句柄、或其他对象,这些对象通常会存储状态信息或数据,并且可能会在多个任务间传递。
  • xTaskHandle:例如 xTaskHandle 是一个句柄类型,用于引用任务。
  • xQueueHandle:表示队列的句柄。
  • xSemaphoreHandle:表示信号量的句柄。
  • xEventGroupHandle:表示事件组的句柄。

例子:

xQueueHandle xQueue;  // 队列句柄
xTaskHandle xTask;    // 任务句柄

2. v 前缀

  • v 前缀通常表示 “void” 类型的函数,即不返回值的函数。许多 FreeRTOS 的 API 函数都是以 v 为前缀的,它们执行任务但不需要返回值。

例子:

void vTaskDelay( TickType_t xTicksToDelay );  // 延迟函数,不返回值
void vTaskStartScheduler(void);                // 启动调度器函数

3. px 前缀

  • px 前缀表示一个 指针,尤其是指向任务、队列、信号量等对象的指针。在 FreeRTOS 的许多数据结构中,使用了指针来管理和传递对象。

例子:

TaskHandle_t *pxTask;  // 任务指针
QueueHandle_t *pxQueue;  // 队列指针

4. ux 前缀

  • ux 前缀通常表示 无符号类型的变量,尤其是一些与计数、任务优先级、事件等有关的变量。

例子:

uxQueueMessagesWaiting( QueueHandle_t xQueue );  // 返回队列中消息的数量
uxTaskPriorityGet( TaskHandle_t xTask );  // 获取任务的优先级

5. pv 前缀

  • pv 前缀表示 指向 void 类型的指针。它通常用于指向无法预先确定类型的通用数据结构。

例子:

void *pvParameter = NULL;  // 无类型的参数

6. prv 前缀

  • prv 表示 “private”(私有的)。通常用于表示在文件内部或静态作用域中的私有函数。它表明这些函数不应该被外部调用,仅限于文件内部的使用。

例子:

static void prvTaskFunction(void *pvParameters);  // 私有任务函数

7. ux 和 x 的结合

  • uxx 在某些情况下会结合使用,用于表示 无符号普通 的参数或返回值。

8. 其他命名约定

  • TickType_t:表示 FreeRTOS 中时间计时单位的类型,通常是无符号整数。
  • BaseType_t:表示带符号的基础类型,常用于任务或事件标志返回的结果。
  • TickType_tBaseType_t:都是 FreeRTOS 内部时间和状态相关的标准数据类型。

总结:

这些命名约定为开发者提供了一定的 代码规范,便于理解和维护代码。在使用 FreeRTOS 时,熟悉这些命名规则能帮助你更快速地理解 API 的含义和功能,从而有效地进行开发。

三、开发规范

为了确保后续开发的规范性、可维护性和代码的统一性,命名约定是非常重要的。以下是一些通用的命名约定,适用于 FreeRTOS 或其他嵌入式开发项目。你可以根据具体项目的需求进行调整和扩展:

1. 函数命名

  • 动词+名词结构:函数名应该清晰表达其功能,通常使用动词+名词结构来描述。

  • 避免简写:使用完整的单词,避免使用不常见的缩写。

  • 动词使用

    • create: 创建任务、队列、信号量等(如 createTaskcreateQueue)。
    • init: 初始化操作(如 initSysteminitHardware)。
    • get: 获取某个值(如 getTaskPriority)。
    • set: 设置某个值(如 setTaskPriority)。
    • handle: 处理某个操作(如 handleInterrupt)。
    • start, stop: 启动和停止操作(如 startSchedulerstopTask)。
    • check: 检查状态(如 checkQueueEmpty)。

例子

void createTask(void);
void initSystem(void);
int getQueueLength(QueueHandle_t xQueue);
void startScheduler(void);
void stopTask(TaskHandle_t xTask);

2. 参数命名

  • 小写字母+驼峰法:使用小写字母,并遵循驼峰命名规则(第一个单词首字母小写,后续单词首字母大写)。
  • 描述性:参数命名要有描述性,能反映它在函数中的作用。
  • 避免缩写:尽量避免使用缩写,除非是众所周知的缩写(如 ptr 表示指针)。

例子

void setTaskPriority(TaskHandle_t taskHandle, UBaseType_t priority);
void initQueue(QueueHandle_t *queueHandle, size_t queueSize);

3. 结构体命名

  • 类型名称+结构体标识:结构体的名称应该能明确表示其用途和类型。通常以类型名称为基础,加上 Struct 后缀。
  • 驼峰命名法:使用大驼峰命名法(每个单词首字母大写)。
  • 结构体成员命名:结构体成员一般使用小写字母,并用下划线分隔(如果需要)。

例子

typedef struct TaskConfig {uint32_t taskId;uint32_t taskPriority;void (*taskFunction)(void *);
} TaskConfig_t;

4. 全局变量命名

  • 小写字母+下划线分隔:全局变量命名应简洁明了,使用小写字母和下划线分隔各个词。
  • 避免与局部变量冲突:确保全局变量的命名不会与函数中的局部变量冲突。

例子

uint32_t system_status;
TaskHandle_t scheduler_task;

5. 常量命名

  • 全大写+下划线分隔:常量(如宏、枚举等)使用全大写字母,单词之间使用下划线分隔。
  • 前缀标识:可以使用一些前缀来表示常量的作用或范围,例如 MAX_ 表示最大值,CONFIG_ 表示配置相关常量。

例子

#define MAX_TASK_PRIORITY 10
#define CONFIG_QUEUE_SIZE 128

6. 句柄命名

  • Handle 结尾:句柄一般是指向某个对象(如任务、队列等)的指针,命名时可以在名称的后面加上 Handle 后缀。

例子

TaskHandle_t taskHandle;
QueueHandle_t queueHandle;
SemaphoreHandle_t semaphoreHandle;

7. 类型定义

  • typedef 类型名+描述性后缀:如果需要为某些数据类型定义类型别名,可以使用描述性的名称,并以 _t 结尾。

例子

typedef uint32_t TickType_t;
typedef struct {int x;int y;
} Position_t;

8. 文件命名

  • 小写字母+下划线分隔:文件名应简洁明了,使用小写字母和下划线分隔,便于识别文件内容。
  • 与功能匹配:文件名应与文件中的功能或模块匹配。

例子

task_scheduler.c
queue_manager.c
system_init.c

9. 宏命名

  • 全大写字母:宏定义使用全大写字母,单词之间使用下划线分隔,便于区分常量和宏定义。

例子

#define TASK_STACK_SIZE 1024
#define QUEUE_TIMEOUT 100

10. 命名约定总结

  • 可读性优先:命名应具有描述性,能准确反映变量或函数的用途。
  • 统一性:保持项目中的命名风格一致,避免混用不同的命名方式。
  • 避免使用类似“temp”、“data”等没有实际意义的名称,除非是临时变量。
  • 避免过度缩写:缩写可以提高代码简洁性,但要确保其他开发者能理解这些缩写的含义。

总结

通过遵循这些命名约定,可以确保代码的清晰性和可维护性。为不同类型的参数、变量、函数等选择合适的命名规则,不仅可以提高开发效率,还能减少后期维护中的混淆和错误。在写博客时,你可以根据这些规则为开发项目提供清晰的命名标准,并帮助其他开发者更好地理解代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91687.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91687.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Clip微调系列:《coOp: learning to prompt for vision-language models》

论文链接:arxiv.org/pdf/2109.01134v1 推荐视频(clip_coop的代码逻辑讲解,代码简单,有助于理解):CLIP和CoOp工作的简单Pytorch复现和理解_哔哩哔哩_bilibili 其他参考链接:CoOp - CLIP 自适应Prompt工程 【一】_coop…

[论文阅读] 人工智能 + 软件工程 | 开源软件中的GenAI自白:开发者如何用、项目如何管、代码质量受何影响?

开源软件中的GenAI自白:开发者如何用、项目如何管、代码质量受何影响? 论文:Self-Admitted GenAI Usage in Open-Source SoftwarearXiv:2507.10422 Self-Admitted GenAI Usage in Open-Source Software Tao Xiao, Youmei Fan, Fabio Calefato…

AI绘画版权问题全解析:你的作品真的属于你吗?

AI绘画版权问题全解析:你的作品真的属于你吗? 关键词:AI绘画、版权归属、生成式AI、训练数据、独创性、法律合规、知识产权 摘要:当你用MidJourney生成一张“赛博朋克风格的熊猫”,或用Stable Diffusion画出“梵高笔触的星空咖啡馆”时,你是否想过:这张图的版权属于你、…

深入理解Linux文件I/O:系统调用与标志位应用

目录 一、引入 二、标志位 1、什么是标志位? 2、标志位传递示例 输出结果分析 关键点解释 三、文件描述符(File Descriptor)(先大概了解) 四、接口介绍:open()函数 1、命令查看 2、头文件 3、函数原型 4、参数说明 …

海康线扫相机通过采集卡的取图设置

目录 1、扫描高度小于65000行 1.1 软触发 1、采集卡设置项 2、相机设置项 1.2 硬触发 1、采集卡设置项 2、相机设置项 2、扫描高度大于65000行 1.1 软触发 1、采集卡设置项 2、相机设置 1.2 硬触发 1、采集卡设置项 2、相机设置 2.1 帧扫描 2.2 行扫描 3、注意…

InfluxDB 3与Apache Parquet:打造高性能时序数据存储与分析解决方案

在当今数据驱动的时代,各行业产生的数据量呈爆炸式增长,如何高效存储和管理海量数据成为企业和开发者面临的重大挑战。对于时序数据而言,其具有数据量大、写入频繁、查询模式多样等特点,对存储系统的性能和效率提出了更高的要求。…

20250718-4-Kubernetes 应用程序生命周期管理-Pod对象:实现机制_笔记

一、Pod对象1. 资源共享实现机制1)共享网络基本概念实现方式:通过将业务容器网络加入到负责网络的容器(infra container)实现网络共享核心特点:共享网络协议栈(包括TC…

防爆手机是什么?能用普通手机改装吗?

在石油开采平台的井架之上,在化工车间的反应釜旁,在煤矿深达千米的巷道中,一群特殊的工作人员正使用着看似普通的通讯设备。这些设备外壳上醒目的Ex防爆认证标志,揭示着其与众不同的身份——防爆手机。这类专为易燃易爆环境设计的…

gem install报错解析

报错内容 [rootlocalhost ~]# gem install bundler Fetching: bundler-2.6.9.gem (100%) ERROR: Error installing bundler:bundler requires Ruby version > 3.1.0. The current ruby version is 2.5.0.解决方案(任选其一) 这个错误表明你当前的 Ru…

css 如何实现大屏4个占位 中屏2个 小屏幕1个

1、 使用grid.container {display: grid;grid-template-columns: repeat(4, 1fr);gap: 20px;border: 1px solid red;width: 400px;height: 400px;}media (max-width: 768px) {.container {grid-template-columns: 1fr;}}media (min-width: 768px) and (max-width: 992px) {.con…

Redis学习系列之—— JDHotKey 热点缓存探测系统

一、为什么需要热点缓存探测 在回答这个问题前,我们先考虑一下:为什么光用 Redis 还不够,还需要使用本地缓存? 一般来说,Redis 集群的性能能抗住几十万并发,能够应付大部分情况。但对于一些头部 APP&#x…

Linux 安全加固

Linux 安全加固需要从​​用户权限、系统服务、网络防护、日志审计、文件系统、访问控制​​等多个维度入手,目标是减少攻击面、限制未授权访问、提升系统健壮性。以下是​​详细步骤实操示例​​,覆盖主流 Linux 发行版(如 CentOS/Ubuntu&am…

【Docker#2】容器历史发展 | 虚拟化实现方式

一、前言 – 容器技术发展史 容器技术是现今计算技术的重要组成部分,其发展历程可以追溯到很早的计算机系统提供的进程隔离工具。以下是容器技术的发展历程,其中涵盖了从早期的进程隔离技术到现代云计算和云原生的演变: ① Jail 时代 1979 年…

React + Mermaid 图表渲染消失问题剖析及 4 种代码级修复方案

Mermaid 是一个流行的库&#xff0c;它可以将文本图表&#xff08;例如 graph LR; A-->B;&#xff09;转换为 SVG 图表。在静态 HTML 页面中&#xff0c;Mermaid 会查找 <pre class"mermaid"> 代码块&#xff0c;并在页面加载时将它们替换为渲染后的图表。它…

[Element]修改el-pagination背景色

[Element]修改el-pagination背景色 代码 <el-pagination:current-page.sync"queryParams.current":page-size.sync"queryParams.size":page-sizes"[10, 20, 50, 100]"layout"prev, pager, next, jumper, sizes":total"queryP…

Docker 可用镜像列表

Docker 镜像源列表&#xff08;7月15日更新-长期&免费&#xff09;_dockerhub国内镜像源列表-CSDN博客

低代码可视化工作流的系统设计与实现路径研究

一、背景分析在数字化转型不断深化的背景下&#xff0c;企业业务流程呈现出高度定制化与动态调整的趋势&#xff0c;传统信息系统在开发周期、实施成本与扩展能力上的局限性日益凸显&#xff0c;已难以支撑快速响应和敏捷迭代的实际需求。面向这一现实挑战&#xff0c;基于 BPM…

mac mlx大模型框架的安装和使用

mlx是apple平台的大模型推理框架&#xff0c;对mac m1系列处理器支持较好。 这里记录mlx安装和运行示例。 1 安装mlx框架 conda create -n mlx python3.12 conda activate mlx pip install mlx-lm 2 运行mlx测试例 以下是测试程序&#xff0c;使用方法和hf、vllm等推理框架基…

JAVA 使用Apache POI合并Word文档并保留批注的实现

一、需求背景 在实际工作中&#xff0c;我们经常需要将多个Word文档合并成一个文件。但当文档中包含批注&#xff08;Comments&#xff09;时&#xff0c;传统的复制粘贴会导致批注丢失或引用错乱。本文将介绍如何通过Java和Apache POI库实现保留批注及引用关系的文档合并功能。…

Linux的服务管理工具:`systemd`(`systemctl`)和`SysVinit ` 笔记250718

Linux的服务管理工具:systemd(systemctl)和SysVinit 笔记250718 Linux的服务管理工具 Linux 的服务管理工具随着发行版和初始化系统的发展而演变。以下是主要的服务管理工具及其对应的初始化系统&#xff1a; 1. systemd (现代主流标准) 初始化系统&#xff1a; 是绝大多数…