在开始具体的学习之前,你应该先了解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++风格的注释(//).
  • 布局

    布局和格式按照以下代码示例.
  1. /* Library includes come first… */
  2. #include <stdlib.h>
  3. /* …followed by FreeRTOS includes… */
  4. #include FreeRTOS.h
  5. /* …followed by other includes. */
  6. #include HardwareSpecifics.h
  7. /* #defines comes next, bracketed where possible. */
  8. #define A_DEFINITION ( 1 )
  9. /*
  10. * Static (file private) function prototypes appear next, with comments
  11. * in this style – with each line starting with a ‘*’.
  12. */
  13. static void prvAFunction( uint32_t ulParameter );
  14. /* File scope variables are the last thing before the function definitions.
  15. Comments for variables are in this style (without each line starting with
  16. a ‘*’). */
  17. static BaseType_t xMyVariable;
  18. /* The following separate is used after the closing bracket of each function,
  19. with a blank line following before the start of the next function definition. */
  20. /*———————————————————–*/
  21. void vAFunction( void )
  22. {
  23. /* Function definition goes here – note the separator after the closing
  24. curly bracket. */
  25. }
  26. /*———————————————————–*/
  27. static UBaseType_t prvNextFunction( void )
  28. {
  29. /* Function definition goes here. */
  30. }
  31. /*———————————————————–*/
  32. File Layout
  33. /* Function names are always written on a single line, including the return
  34. type. As always, there is no space before the opening parenthesis. There
  35. is a space after an opening parenthesis. There is a space before a closing
  36. parenthesis. There is a space after each comma. Parameters are given
  37. verbose, descriptive names (unlike this example!). The opening and closing
  38. curly brackets appear on their own lines, lined up underneath each other. */
  39. void vAnExampleFunction( long lParameter1, unsigned short usParameter2 )
  40. {
  41. /* Variable declarations are not indented. */
  42. uint8_t ucByte;
  43. /* Code is indented. Curly brackets are always on their own lines
  44. and lined up underneath each other. */
  45. for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
  46. {
  47. /* Indent again. */
  48. }
  49. }
  50. /* For, while, do and if constructs follow a similar pattern. There is no
  51. space before the opening parenthesis. There is a space after an opening
  52. parenthesis. There is a space before a closing parenthesis. There is a
  53. space after each semicolon (if there are any). There are spaces before and
  54. after each operator. No reliance is placed on operator precedence –
  55. parenthesis are always used to make precedence explicit. Magic numbers,
  56. other than zero, are always replaced with a constant or #defined constant.
  57. The opening and closing curly brackets appear on their own lines. */
  58. for( ucByte = 0U; ucByte < fileBUFFER_LENGTH; ucByte++ )
  59. {
  60. }
  61. while( ucByte < fileBUFFER_LENGTH )
  62. {
  63. }
  64. /* There must be no reliance on operator precedence – every condition in a
  65. multi-condition decision must uniquely be bracketed, as must all
  66. sub-expressions. */
  67. if( ( ucByte < fileBUFFER_LENGTH ) && ( ucByte != 0U ) )
  68. {
  69. /* Example of no reliance on operator precedence! */
  70. ulResult = ( ( ulValue1 + ulValue2 ) ulValue3 ) * ulValue4;
  71. }
  72. /* Conditional compilations are laid out and indented as per any
  73. other code. */
  74. #if( configUSE_TRACE_FACILITY == 1 )
  75. {
  76. /* Add a counter into the TCB for tracing only. */
  77. pxNewTCB->uxTCBNumber = uxTaskNumber;
  78. }
  79. #endif
  80. A space is placed after an opening square bracket, and before a closing
  81. square bracket.
  82. ucBuffer[ 0 ] = 0U;
  83. ucBuffer[ fileBUFFER_LENGTH 1U ] = 0U;
  84. 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. node+ajax实战案例(1)

    1.mysql入门 1.1.数据库相关概念 1.1.1.什么是数据? 描述事物的符号记录称为数据,描述事物的符号可以是数字.文字.声音.图片.视频等,有多种表现形式,都可以经过数字化后存入计算机 1. ...

  2. ORACLE数据库数据被修改或者删除恢复数据(闪回)

    1. SELECT * FROM CT_FIN_RiskItem  --先查询表,确定数据的确不对  (cfstatus 第一行缺少) 2. select * from CT_FIN_RiskItem ...

  3. wsl环境下配置ubuntu16.04

    wsl环境下配置ubuntu16.04 在公司同事的安利下,终于给自己用了8年的老笔记本(戴尔XPS L502X)换上了固态硬盘(WD500G,SATA3接口) 当然,系统重装了一遍,所有的软件也都没 ...

  4. python 中去除空格的方法

    python 中去除空格的方法: def trim(s): l=[] for i in s: if i!=' ': l.append(i) return ''.join(l) 其中可以使用下面的 '' ...

  5. (一)ansible 安装配置

    CentOS 7.5 一,安装 yum -y install ansible 二,配置hosts文件 /etc/ansible/hosts s1 ansible_ssh_port= ansible_s ...

  6. BUUCTF-Misc-No.1

    # BUUCTF-Misc # 签到 flag{buu_ctf} 金三胖 说实话直接看出来flag{he11ohongke} 二维码 直接binwalk扫一下,-e分离就出来一个带锁的zip爆破一下就 ...

  7. Qt-文件系统

    1  简介 参考视频:https://www.bilibili.com/video/BV1XW411x7NU?p=45 参考文档:<Qt教程.docx> 说明:本文主要介绍Qt的文件系统. ...

  8. Python比较操作符、变量赋值、对象拷贝

    Python比较操作符.变量赋值.对象拷贝 目录 Python比较操作符.变量赋值.对象拷贝 1. 比较操作符 == 和 is 1.1 区别 1.2 实例 2. 变量及其赋值 2.1 概念和逻辑关系 ...

  9. Django之模型层第一篇:单表操作

    Django之模型层第一篇:单表操作 一 ORM简介 ​ 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数 ...

  10. pip install scrapy报错:error: Unable to find vcvarsall.bat解决方法

    今天在使用pip install scrapy 命令安装Scrapy爬虫框架时,出现了很让人头疼的错误,错误截图如下: 在网上查找解决方法时,大致知道了问题的原因.是因为缺少C语言的编译环境,其中一种 ...