在开始具体的学习之前,你应该先了解freeRTOS的编程标准.这能够方便你在接下来的阅读中快速的了解一些内容

的基本信息,并方便记忆.此外,良好的编程风格也是工作效率的保障.

你可以在https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html中找到英文的原文信息.

尽管此前有人翻译过这份文档,但发布时间在很早以前,一些标准已经发生了改变.这里按照此前翻译的思路根据官方文档进行了更新和修订.

编程标准(Coding Standard)

FreeRTOS代码遵循MISRA(Motor Industry Software Reliability Association)标准,但也有些区别.具体来说:

  • 为了效率,有两个API函数拥有超过一个的出口点.
  • 使用了标准的C数据类型,而不是用typedef将其重定义.
  • 在创建任务时,代码会直接处理堆栈的栈顶和栈底地址.由于不同平台的总线宽度并不相同,这就需要不可避免地对指针变量进行算数运算.
  • trace宏的定义在默认情况为空,所以不会产生任何代码.因此,MISRA的遵从检查其实是用假的宏定义来运行的.

    此外,除了在stdint.h中,freeRTOS没有使用任何C99标准中的语法和特性.在FreeRTOS/Source/include目录下有一个名为stdint.readme的文件,如果你想要使用stdint的数据类型的话,将它重命名为stdint.h.

命名约定(Naming Conventions)

在freeRTOS的内核和示例中,按照以下约定命名:

  • 变量名

    • uint32_t 数据类型的变量的变量名以 ul 为前缀.
    • uint16_t 数据类型的变量的变量名以 us 为前缀.
    • uint8_t 数据类型的变量的变量名以 uc 为前缀.
    • 非stdint数据类型的变量的变量名以 x 为前缀.例如,BaseType_t TickType_t.
    • 无符号的非stdint数据类型的变量的变量名再添加一个额外的前缀 u .例如,UBaseType_t(unsigned BaseType_t)数据类型的变量的变量名以 ux x为前缀.
    • size_t 数据类型的变量的变量名也以 x 为前缀.
    • 指针变量拥有一个额外的前缀 p.例如,uint16_t的指针的变量名以 pus为前缀.
    • 按照MISRA的标准,char数据类型只允许储存ASCII字符,以 c 为前缀.char的指针只允许指向ASCII字符串,以 pc 为前缀.
  • 函数名

    - 文件的内部函数以prv为前缀.

    - API函数以返回值类型为前缀,参见前面变量名的命名约定(额外添加了v作为void返回值的前缀).例如,vTaskDelete代表这个函数的返回值类型为void.

    - 函数名以所在文件名为开头.例如,vTaskDelete函数在Task.c中定义.


  • - 宏用所在文件名的一部分以小写作为前缀.例如,configUSE_PRESSMPTIONFreeRTOSConfig.h中定义.

    - 宏的其余部分用大写字母,用下划线分割.

数据类型

除了以下例外,只使用了stdint和freeRTOS自己定义的数据类型:

  • 按照MISRA的标准,char数据类型只允许储存ASCII字符.
  • 按照MISRA的标准,char的指针只指向ASCII字符串.

为每种接口,定义了4种数据类型:

  • TickType_t

    如果configUSE_16_BIT_TICKS是真值,那么TickType_t为16-bit.否则则是32-bit.
  • BaseType_t

    该数据类型定义了一个平台下效率最高的原生数据类型.例如,在32位的平台下,BaseType_t将被定义为32-bit的数据类型.

    此外,如果BaseType_t被定义为了char,必须注意一定要是有符号的数据类型.因为在作为函数的返回值时,需要使用负值来表示错误.
  • UBaseType_t

    无符号的UBaseType_t.
  • StackType_t

    用于在栈中储存数据.尽管存在例外,但通常,在16-bit平台下该数据类型为16-bit,而在32-bit平台下为32-bit.

编程风格

  • 缩进

    使用Tab缩进,一个Tab等于4个空格.
  • 注释

    注释不能超过80行,除非用来描述一个参数.

    不使用C++风格的注释(//).
  • 布局

    布局和格式按照以下代码示例.
/* Library includes come first… */
#include <stdlib.h>
/* …followed by FreeRTOS includes… */
#include “FreeRTOS.h”
/* …followed by other includes. */
#include “HardwareSpecifics.h”
/* #defines comes next, bracketed where possible. */
#define A_DEFINITION ( 1 ) /*
* Static (file private) function prototypes appear next, with comments
* in this style – with each line starting with a ‘*’.
*/
static void prvAFunction( uint32_t ulParameter ); /* File scope variables are the last thing before the function definitions.
Comments for variables are in this style (without each line starting with
a ‘*’). */
static BaseType_t xMyVariable; /* The following separate is used after the closing bracket of each function,
with a blank line following before the start of the next function definition. */ /*———————————————————–*/ void vAFunction( void )
{
/* Function definition goes here – note the separator after the closing
curly bracket. */
}
/*———————————————————–*/ static UBaseType_t prvNextFunction( void )
{
/* Function definition goes here. */
}
/*———————————————————–*/ File Layout /* Function names are always written on a single line, including the return
type. As always, there is no space before the opening parenthesis. There
is a space after an opening parenthesis. There is a space before a closing
parenthesis. There is a space after each comma. Parameters are given
verbose, descriptive names (unlike this example!). The opening and closing
curly brackets appear on their own lines, lined up underneath each other. */
void vAnExampleFunction( long lParameter1, unsigned short usParameter2 )
{
/* Variable declarations are not indented. */
uint8_t ucByte; /* Code is indented. Curly brackets are always on their own lines
and lined up underneath each other. */
for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
{
/* Indent again. */
}
} /* For, while, do and if constructs follow a similar pattern. There is no
space before the opening parenthesis. There is a space after an opening
parenthesis. There is a space before a closing parenthesis. There is a
space after each semicolon (if there are any). There are spaces before and
after each operator. No reliance is placed on operator precedence –
parenthesis are always used to make precedence explicit. Magic numbers,
other than zero, are always replaced with a constant or #defined constant.
The opening and closing curly brackets appear on their own lines. */
for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
{
} while( ucByte < fileBUFFER_LENGTH )
{
} /* There must be no reliance on operator precedence – every condition in a
multi-condition decision must uniquely be bracketed, as must all
sub-expressions. */
if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) )
{
/* Example of no reliance on operator precedence! */
ulResult = ( ( ulValue1 + ulValue2 ) – ulValue3 ) * ulValue4;
} /* Conditional compilations are laid out and indented as per any
other code. */
#if( configUSE_TRACE_FACILITY == 1 )
{
/* Add a counter into the TCB for tracing only. */
pxNewTCB->uxTCBNumber = uxTaskNumber;
}
#endif A space is placed after an opening square bracket, and before a closing
square bracket.
ucBuffer[ 0 ] = 0U;
ucBuffer[ fileBUFFER_LENGTH – 1U ] = 0U; Formatting of C Constructs

freeRTOS内核学习笔记(1)-编程标准的更多相关文章

  1. EPROCESS 进程/线程优先级 句柄表 GDT LDT 页表 《寒江独钓》内核学习笔记(2)

    在学习笔记(1)中,我们学习了IRP的数据结构的相关知识,接下来我们继续来学习内核中很重要的另一批数据结构: EPROCESS/KPROCESS/PEB.把它们放到一起是因为这三个数据结构及其外延和w ...

  2. Linux内核学习笔记-2.进程管理

    原创文章,转载请注明:Linux内核学习笔记-2.进程管理) By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  3. Linux内核学习笔记-1.简介和入门

    原创文章,转载请注明:Linux内核学习笔记-1.简介和入门 By Lucio.Yang 部分内容来自:Linux Kernel Development(Third Edition),Robert L ...

  4. ufldl学习笔记和编程作业:Feature Extraction Using Convolution,Pooling(卷积和汇集特征提取)

    ufldl学习笔记与编程作业:Feature Extraction Using Convolution,Pooling(卷积和池化抽取特征) ufldl出了新教程,感觉比之前的好,从基础讲起.系统清晰 ...

  5. ufldl学习笔记和编程作业:Softmax Regression(softmax回报)

    ufldl学习笔记与编程作业:Softmax Regression(softmax回归) ufldl出了新教程.感觉比之前的好,从基础讲起.系统清晰,又有编程实践. 在deep learning高质量 ...

  6. Linux内核学习笔记二——进程

    Linux内核学习笔记二——进程   一 进程与线程 进程就是处于执行期的程序,包含了独立地址空间,多个执行线程等资源. 线程是进程中活动的对象,每个线程都拥有独立的程序计数器.进程栈和一组进程寄存器 ...

  7. 20135316王剑桥Linux内核学习笔记

    王剑桥Linux内核学习笔记 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 计算机是如何工作的 个人理 ...

  8. ufldl学习笔记与编程作业:Softmax Regression(vectorization加速)

    ufldl学习笔记与编程作业:Softmax Regression(vectorization加速) ufldl出了新教程,感觉比之前的好.从基础讲起.系统清晰,又有编程实践. 在deep learn ...

  9. ufldl学习笔记与编程作业:Multi-Layer Neural Network(多层神经网络+识别手写体编程)

    ufldl学习笔记与编程作业:Multi-Layer Neural Network(多层神经网络+识别手写体编程) ufldl出了新教程,感觉比之前的好,从基础讲起,系统清晰,又有编程实践. 在dee ...

随机推荐

  1. SDL软件安全读书笔记(一)

    # 如何应对当前的全球网络安全威胁? 开发安全漏洞尽可能少的软件,应该着眼于源头安全. 边界安全盒深度防御是重要的安全手段,但软件自身的安全是安全防护的第一关. 即使软件源头存在较少的漏洞,这些漏洞也 ...

  2. Java 从入门到进阶之路(二十五)

    在之前的文章我们介绍了一下 Java 中的  集合框架中的Collection 的子接口 List的 增删改查和与数组间相互转换的方法,本章我们来看一下 Java 集合框架中的Collection 的 ...

  3. Oracle 导出、导入某用户所有数据(包括表、视图、存储过程...)

    Oracle 导出.导入某用户所有数据(包括表.视图.存储过程...)前提:在CMD 命令下 导出命令:exp 用户名/密码@数据库 owner=用户名 file=文件存储路径(如:F:\abcd.d ...

  4. day02小程序配置

    附上微信小程序开发文档的网址:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html 学技术 ...

  5. (私人收藏)精美PPT模板

    精美PPT模板 https://pan.baidu.com/s/1vsRnX5h7t3MZ7qdrFvuI1wsucr

  6. 【k8s学习笔记】使用 kubeadm 部署 v1.18.5 版本 Kubernetes集群

    说明 本文系搭建kubernetes v1.18.5 集群笔记,使用三台虚拟机作为 CentOS 测试机,安装kubeadm.kubelet.kubectl均使用yum安装,网络组件选用的是 flan ...

  7. td文字溢出显示省略号

    昨天遇到移动端表格td中文字溢出问题,写了溢出隐藏样式,居然没起作用! { overflow:hidden;//溢出隐藏 white-space:nowrap;//文字不换行 text-overflo ...

  8. BUUCTF-Misc-No.2

    比赛信息 比赛地址:Buuctf靶场 [GUET-CTF2019]虚假的压缩包 | SOLVED 解压文件夹,发现2个zip,第一个伪加密,破解后 n=33 e=3 m=0 while m<10 ...

  9. postman-7-前置请求脚本

    前面讲了,tests初如何校验请求之后返回值是否正确 那前置脚本,就是处理,请求之前接口该如何处理,什么时候会用到呢? 比如:接口字段time,需要填入时间,而且这个是需要当前时间的,: 需要达到自动 ...

  10. 深圳有为JAVA笔试

    深圳有为JAVA笔试 1.定义一个线程类有几种方法?分别是什么? 答:两种方法,一种继承Thread类,重写run()方法,第二种实现runnable接口,实现run()方法. 2.抽象类和接口的区别 ...