此文共连载分析三个uCOS-Ⅱ的三个源码文件夹:uC-CPU 、uC-LIB 、uCOS-Ⅱ

uC-LIB文件夹目录:Prots / lib_mem_a.asm                                 lib_def.h                                 lib_mem.c                                 lib_mem.h                                 lib_str.c                                 lib_str.h

lib_mem_a.asm

这是一个汇编文件,文件中用汇编语言实现了一个函数 Mem_Copy() ,这个函数是用来进行内存拷贝的,之所以用汇编实现这个函数,是因为内存操作在 RTOS 操作系统中是很重要的,用汇编来实现可以效率更高。


void  Mem_Copy (void        *pdest,        ;  ==>  R0
               void        *psrc,         ;  ==>  R1
               CPU_SIZE_T   size)         ;  ==>  R2

为什么使用汇编语言来实现:使用汇编语言的情况一般只有两种,一种是使用汇编效率更高,一种是 C语言 无法实现(比如单片机中的异常向量表)。

EXPORT  Mem_Copy  ;ARM汇编中的函数声明

EXPORT 是 ARM 汇编指令的一个关键字,用来从ARM汇编文件中导出一个符号,这样这个符号就可以在其他文件中引用了,类似 C语言 的 extern 关键字。可以实现函数在汇编文件中定义,在 C语言 文件中调用。

总结:这个文件应该是 ARM 官方书写的,不需要我们做任何修改,只要理解这个函数的作用,做到会使用,出问题可以解决即可。

lib_def.h

这个文件中定义了许多宏,大致分为两类:一类是对一些常数的定义(比如 DISABLE 是 0 ,ENABLE 是 1 等等);一类是对可能用到的和环境有关的数值的定义(比如一年有多少天,一小时有多少分钟等等)。

lib_mem.c  、lib_mem.h

这里面定义和实现了一些有关内存操作函数,注意的是这里面也有一个函数 Mem_Copy()

void  Mem_Copy (void        *pdest,
               void        *psrc,
               CPU_SIZE_T   size)  // 在 lib_mem.c 文件中用 C语言 实现了一个内存copy函数

可以看出函数原型和 lib_mem_a.asm 文件中汇编语言的 Mem_Copy() 函数一模一样,实际上实现的效果也一模一样,只不过是一个用 C语言,一个用汇编语言。不过 C语言 实现的这个函数用 if define 的形式做了限制,所以不会和汇编语言的同一个函数发生重名冲突。

还有一种配置一些模块开关的宏(配置宏),类似 LIB_MEM_CFG_ARG_CHK_EXT_EN 这样的宏;这种宏的作用是用来配置 uCOS-Ⅱ 系统中的可选项目,uCOS-Ⅱ本身设计时设计了许多属性,可以在这些宏中进行使能或禁止,这样在编译(预处理)的时候编译器(预处理器)就可以帮我们把 uCOS-Ⅱ 内核中的这些项目加上或去除。

注意:在使用宏定义配置 uCOS-Ⅱ 内核时需要在 APP 层进行配置。

lib_str.c  、lib_str.h

这里面实现了许多 C标准库 中对字符串操作的函数,为了可以在多个平台上进行使用,不依赖于 C标准库,所以自己实现了有关字符串操作的函数:

CPU_SIZE_T   Str_Len      (CPU_CHAR     *pstr);  //测量字符串长度

CPU_CHAR    *Str_Copy     (CPU_CHAR     *pdest,  //复制字符串
                          CPU_CHAR     *psrc);
                         
CPU_CHAR    *Str_Copy_N   (CPU_CHAR     *pdest,  //复制 len_max 数量的字符
                          CPU_CHAR     *psrc,
                          CPU_SIZE_T    len_max);
                         
CPU_CHAR    *Str_Cat      (CPU_CHAR     *pdest,  //接续字符串
                          CPU_CHAR     *pstr_cat);

CPU_CHAR    *Str_Cat_N    (CPU_CHAR     *pdest,  //接续 len_max 数量的字符串
                          CPU_CHAR     *pstr_cat,
                          CPU_SIZE_T    len_max);

CPU_INT16S   Str_Cmp      (CPU_CHAR     *p1_str, //比较字符串大小,返回相应值
                          CPU_CHAR     *p2_str);

CPU_INT16S   Str_Cmp_N    (CPU_CHAR     *p1_str, //比较 len_max 数量的字符串大小,返回相应值
                          CPU_CHAR     *p2_str,
                          CPU_SIZE_T    len_max);

CPU_CHAR    *Str_Char     (CPU_CHAR     *pstr,
                          CPU_CHAR      srch_char);

CPU_CHAR    *Str_Char_N   (CPU_CHAR     *pstr,
                          CPU_SIZE_T    len_max,
                          CPU_CHAR      srch_char);

CPU_CHAR    *Str_Char_Last(CPU_CHAR     *pstr,
                          CPU_CHAR      srch_char);

CPU_CHAR    *Str_Str      (CPU_CHAR     *pstr,
                          CPU_CHAR     *srch_str);

//这个函数是把一个 uint32 类型的变量转换成一个对应的字符串
//例: uint32 num = 123456;  --------> return  "123456"
CPU_CHAR    *Str_FmtNbr_32(CPU_FP32      nbr,
                          CPU_INT08U    nbr_dig,
                          CPU_INT08U    nbr_dp,
                          CPU_BOOLEAN   lead_zeros,
                          CPU_BOOLEAN   nul,
                          CPU_CHAR     *pstr_fmt);