FreeRTOS命名及变量规则

初学FreeRTOS的用户对其变量和函数的命名比较迷惑,    FreeRTOS的核心源代码遵从MISRA编码标准指南,关于MISRA编码标准,可以查看文章https://wenku.baidu.com/view/5e7b2f4ee518964bcf847c99.html。下面专门做一下介绍:

变量

 uint32_t定义的变量都加上前缀ul。u代表unsigned 无符号,l代表long长整型。

 uint16_t定义的变量都加上前缀us。u代表unsigned无符号,s代表short短整型。

 uint8_t定义的变量都加上前缀uc。u代表unsigned无符号,c代表char字符型。

 stdint.h文件中未定义的变量类型,在定义变量时需要加上前缀x,比如BaseType_t和TickType_t定义的变量。

 stdint.h文件中未定义的无符号变量类型,在定义变量时要加上前缀u,比如UBaseType_t 定义的变量要加上前缀ux。

 size_t 定义的变量也要加上前缀ux。

 枚举变量会加上前缀e。

 指针变量会加上前缀p,比如uint16_t定义的指针变量会加上前缀pus。

 根据MISRA代码规则,char定义的变量只能用于ASCII字符,前缀使用c。

 根据MISRA代码规则,char *定义的指针变量只能用于ASCII字符串,前缀使用pc。

函数

 加上了static声明的函数,定义时要加上前缀prv,这个是单词private的缩写。

 带有返回值的函数,根据返回值的数据类型,加上相应的前缀,如果没有返回值,即void类型 ,函数的前缀加上字母v。

 根据文件名,文件中相应的函数定义时也将文件名加到函数命名中,比如tasks.c文件中函数vTaskDelete,函数中的task就是文件名中的task。

 宏定义

 根据宏定义所在的文件,文件中的宏定义声明时也将文件名加到宏定义中,比如宏定义configUSE_PREEMPTION 是定义在文件 FreeRTOSConfig.h里面。宏定义中的config就是文件名中的config。另外注意,前缀要小写。

除了前缀,其余部分全部大写,同时用下划线分开。

数据类型

FreeRTOS使用的数据类型主要分为stdint.h文件中定义的和自己定义的两种。其中char和char *定义的变量要特别注意。

  • char:与MISRA编码标准指南一致,char类型变量仅被允许保存ASCII字符
  • char *:与MISRA编码标准指南一致,char *类型变量仅允许指向ASCII字符串。当标准库函数期望一个char *参数时,这样做可以消除一些编译器警告;特别是考虑到有些编译器将char类型当做signed类型,还有些编译器将char类型当做unsigned类型。

FreeRTOS主要自定义了以下四种数据类型:

 TickType_t 如果用户使能了宏定义 configUSE_16_BIT_TICKS,那么TickType_t定义的就是16位无符号数,如果没有使能,那么TickType_t定义的就是32位无符号数。对于32位架构的处理器,一定要禁止此宏定义,即设置此宏定义数值为0即可。

 BaseType_t 这个数据类型根据系统架构的位数而定,对于32位架构,BaseType_t定义的是32位有符号数,对于16位架构,BaseType_t定义的是16位有符号数。如果BaseType_t被定义成了char型,要特别注意将其设置为有符号数,因为部分函数的返回值是用负数来表示错误类型。

 UBaseType_t 这个数据类型是BaseType_t类型的有符号版本。

 StackType_栈变量数据类型定义,这个数量类型由系统架构决定,对于16位系统架构,StackType_t定义的是 16位变量,对于32位系统架构,StackType_t定义的是32位变量。

示例如下:

/* 首先在这里包含库文件... */
#include <stdlib.h> /* ...然后是FreeRTOS的头文件... */
#include "FreeRTOS.h" /* ...紧接着包含其它头文件. */
#include "HardwareSpecifics.h" /* 随后是#defines, 在合理的位置添加括号. */
#define A_DEFINITION ( 1 ) /*
* 随后是Static (文件内部的)函数原型,
* 如果注释有多行,参照本条注释风格---每一行都以’*’起始.
*/
static void prvAFunction( uint32_t ulParameter ); /* 文件作用域变量(本文件内部使用)紧随其后,要在函数体定义之前. */
static BaseType_t xMyVariable. /* 每一个函数的结束都有一行破折号,破折号与下面的第一个函数之间留一行空白。*/ /*-----------------------------------------------------------*/ void vAFunction( void )
{
/* 函数体在此定义,注意要用大括号括住 */
}
/*-----------------------------------------------------------*/ static UBaseType_t prvNextFunction( void )
{
/* 函数体在此定义. */
}
/*-----------------------------------------------------------*/ /*
* 函数名字总是占一行,包括返回类型。 左括号之前没有空格左括号之后有一个空格,
* 每个参数后面有一个空格参数的命名应该具有一定的描述性.
*/
void vAnExampleFunction( long lParameter1, unsigned short usParameter2 )
{
/* 变量声明没有缩进. */
uint8_t ucByte; /* 代码要对齐. 大括号占独自一行. */
for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
{
/* 这里再次缩进. */
}
} /*
* for、while、do、if结构具有相似的模式。这些关键字和左括号之间没有空格。
* 左括号之后有一个空格,右括号前面也有一个空格,每个分号后面有一个空格。
* 每个运算符的前后各一个空格。使用圆括号明确运算符的优先级。不允许有0
* 以外的数字(魔鬼数)出现,必要时将这些数字换成能表示出数字含义的常量或
* 宏定义。
*/
for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
{
} while( ucByte < fileBUFFER_LENGTH )
{
} /*
* 由于运算符优先级的复杂性,我们不能相信自己对运算符优先级时刻保持警惕
* 并能正确的使用,因此对于多个表达式运算时,使用括号明确优先级顺序
*/
if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) )
{
ulResult = ( ( ulValue1 + ulValue2 ) - ulValue3 ) * ulValue4;
} /* 条件表达式也要像其它代码那样对齐。 */
#if( configUSE_TRACE_FACILITY == 1 )
{
/* 向TCB增加一个用于跟踪的计数器. */
pxNewTCB->uxTCBNumber = uxTaskNumber;
}
#endif /*方括号前后各留一个空格*/
ucBuffer[ ] = 0U;
ucBuffer[ fileBUFFER_LENGTH - 1U ] = 0U;

裸机程序的运行缺点

采用中断和查询结合的方式可以解决大部分裸机应用,但随着工程的复杂,裸机方式的缺点就暴露出来了:
 必须在中断 (ISR) 内处理时间关键运算 内处理时间关键运算 :
 ISR ISR 函数变得非常复杂,并且需要很长执行时间 。
 ISR ISR 嵌套可能产生不预测的执行时间和堆栈 需求。
 超级循环和 ISR 之间的 数据交换是通过全局共享变量进行:
 应用程序的员必须确保数据一致性 。
 超级循环可以与系统计时器轻松同步,但:
 如果系统需要多种不同的周期时间,则会很难实现 。
 超过 超级循环周期的耗时函数需要做拆分。
 增加 软件开销,应用程序难以理解 。
 超级循环 使得 应用程序变得非常复杂,因此难以扩展 :
 一个简单的更改就可能产生不预测副作用 ,对这种副作用进行分析非常耗时。
 超级循环概念的这些缺点可以通过使用实时操作系统 (RTOS) 来解决。

多任务的优点

  针对这些情况,使用多任务系统就可以解决这些问题了。下面是一个多任务系统的流程图:

  多任务系统或者说RTOS的实现,重点就在这个调度器上,而调度器的作用就是使用相关的调度算法来决定当前需要执行的任务。如上图所示的那样,创建了任务并完成OS初始化后,就可以通过调度器来决定任务A,任务B和任务C的运行,从而实现多任务系统。另外需要初学者注意的是,这里所说的多任务系统同一时刻只能有一个任务可以运行,只是通过调度器的决策,看起来像所有任务同时运行一样。为了更好的说明这个问题,再举一个详细的运行例子,运行条件如下:

 使用抢占式调度器。

 1个空闲任务,优先级最低。

 2个应用任务,一个高优先级和一个低优先级,优先级都比空闲任务优先级高。

 中断服务程序,含USB中断,串口中断和系统滴答定时器中断。

  下图是任务的运行过程,其中横坐标是任务优先级由低到高排列,纵坐标是运行时间,时间刻度有小到大。

多任务系统运行过程

(1) 启动RTOS,首先执行高优先级任务(vTaskStartScheduler)。

(2) 高优先级任务等待事件标志(xEventGroupWaitBits)被阻塞,低优先级任务得到执行。

(3) 低优先级任务执行的过程中产生USB中断,进入USB中断服务程序。

(4) 退出USB中断复位程序,回到低优先级任务继续执行。

(5) 低优先级任务执行过程中产生串口接收中断,进入串口接收中断服务程序。

(6) 退出串口接收中断复位程序,并发送事件标志设置消息(xEventGroupSetBitsFromISR),被阻塞的高优先级任务就会重新进入就绪状态,这个时候高优先级任务和低优先级任务都在就绪态,抢占式调度器就会让高优先级的任务先执行,所以此时就会进入高优先级任务。

(7) 高优先级任务由于等待事件标志(xEventGroupWaitBits)会再次被阻塞,低优先级任务开始继续执行。

(8) 低优先级任务调用函数vTaskDelay,低优先级任务被挂起,从而空闲任务得到执行。

(9) 空闲任务执行期间发生滴答定时器中断,进入滴答定时器中断服务程序。

(10) 退出滴答定时器中断,由于低优先级任务延时时间到,低优先级任务继续执行。

(11) 低优先级任务再次调用延迟函数vTaskDelay,低优先级任务被挂起,从而切换到空闲任务。空闲任务得到执行。

  FreeRTOS就是一款支持多任务运行的实时操作系统,具有时间片,抢占式和合作式三种调度方法。通过FreeRTOS实时操作系统可以将程序函数分成独立的任务,并为其提供合理的调度方式。

FreeRTOSreeRTOS reeRTOSreeRTOS 的运行支持以下 四种状态 :
 Run ninging —运行态
当任务处于实际运行状态被称之为运行态,即 CPU 的使用权被这个任务占用。
 Ready —就绪态
处于就绪态的任务是指那些能够运行(没有被阻塞和挂起),但是当前没有运行的任务, 因为同优先级或更高优先级的任务正在运行。
 Blocked locked —阻塞态
由于等待信号量,消息等待信号量,消息 队列 ,事件标志组等而处于的状态被称之为阻塞态,另外任务调用延迟函数也会处于阻塞态。
 Suspended—挂起态
类似阻塞态,通过调用函数 vTaskSuspend( vTaskSuspend( )对指定任务进行挂起,后这个将不被执只对指定任务进行挂起,后这个将不被执只有调用函数 xTaskResume()才可以将这个将这个任务从挂起态恢复 。

下面是任务 在各个状态之间切换的关系图 ,通过这个图 ,大家基本可以对任务的运行状态有了一个整体的认识。

事件状态组的转换

  

freeRTOS与裸机程序相比有什么区别??的更多相关文章

  1. tiny4412 裸机程序 七、重定位代码到DRAM【转】

    本文转载自:http://blog.csdn.net/eshing/article/details/37116637 一.关于DRAM 上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有25 ...

  2. 基于KEIL4开发ARM9(S3C2440)的裸机程序

    本文主要介绍如何使用Keil4开发ARM9(S3C2440)裸机程序. 说明: 一.平台: 操作系统:Windows XP系统 KEIL版本:4.73 开发板:ARM9(S3C2440) 二.建立工程 ...

  3. pc端和android端应用程序测试有什么区别?(ps面试题)

    pc端和android端应用程序测试有什么区别?(ps面试题) [VIP7]大连-凭海临风(215687736) 2014/4/10 8:56:171.测试环境不同PC平台一般都是windows an ...

  4. ubuntu15.10跑裸机程序跑.bin文件

    1:安装tftp:#apt-get update#apt-get install tftp-hpa tftpd-hpa xinetd2:#cd /srv#mkdir tftp#chmod 777 tf ...

  5. EB-SAM9G45裸机程序下载方法

    开发板:EB-SAM9G45 这里提供一种裸程序下载的方法. 在官方提供的下载方法中有手动下载和自动下载,它们都离不开SAM-BA软件,而该软件使用比较麻烦,而且操作不当很容易导致电脑蓝屏,还有一个很 ...

  6. s3c2440 lcd 显示图片裸机程序

    因为前面的裸机程序非常的简单,就不写博了. 程序的流程: 1,初始化C SP 2,关看门狗 3,初始化SDRAM 4,读出 NAND FLASH 中的 包含图片的程式放到SDRAM里面 5,跳转到SD ...

  7. ARM入门实践(一)----Mini6410上最简单的LED点灯裸机程序

    Mini6410上最简单的LED点灯裸机程序 : 实验环境: 根据友善教程,要用ADS,据说现在都不用这个了,但是为了打开友善给的mcp工程,就下了一个,Win7下弄上兼容模式和管理员权限,再下一个S ...

  8. JZ2440学习笔记之第一个裸机程序(Keil-MDK)

    CPU:S3C2440, ARM920T, Internal 4KB RAM, Support boot from NAND flash, 128MB for each bank. JZ2440:Me ...

  9. 微信小程序与手机APP区别

    微信小程序与手机APP区别 ------------------<><><><>------------------ 微信小程序自去年年初,张小龙放话要 ...

随机推荐

  1. [UnityShader基础]03.透明度混合

    如果要渲染半透明物体,那么就需要用到透明度混合. 需要注意的有这几点: 1.设置标签:Tags { "Queue"="Transparent" "Ig ...

  2. Maven CXF wsdl2Java List<Xxx>生成ArrayOfXxx包装对象 解决方法

    添加-xjc-Xxew解决,同时还要给插件添加相应的jar包,如下: <plugin> <groupId>org.apache.cxf</groupId> < ...

  3. JAVA 类的三大特性,封装,继承,多态 的一些发现总结

    < 一 > 封装 < 二 > 继承 1,关于父类中的私有属性和方法,子类能不能访问的问题 1.1,子类不能通过继承拥有父类的私有属性和方法 1.2,子类可以从父类继承下来的 方 ...

  4. This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.

    This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.

  5. ReactiveX 学习笔记(20)使用 RxJava + RxBinding 进行 GUI 编程

    课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...

  6. Linux下MySQL5.7.18 yum方式从卸载到安装

    本文出处:http://www.cnblogs.com/wy123/p/6932166.html 折腾了大半天,看了想,想了看,总算是弄清楚yum安装的过程了,之前写过二进制包安装的,这里用yum安装 ...

  7. office 安装

    在 gaobo百度云下载安装包. 自定义安装,并在自定义界面选择安装路径. 破解:

  8. IntelliJ IDEA2017 激活方法 最新的(亲测可用)

    IntelliJ IDEA2017 激活方法(亲测可用): 搭建自己的授权服务器,对大佬来说也很简单,我作为菜鸟就不说了,网上有教程. 我主要说第二种,现在,直接写入注册码,是不能成功激活的(如果你成 ...

  9. SpringCloud-day02-服务消费者项目建立

    4.4microservice-ticket-consumer-80服务消费者项目建立 我们新建一个服务器提供者module子模块,类似前面建的common公共模块,名称是 microservice- ...

  10. MySQL经典练习题

    表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id ...