嵌入式系统开发中,C语言的地位是无法取代的,所以我用C语言为自己建立一个常用功能函数库。在基于单片机的开发中,经常会遇到“以时间换空间”或者“以空间换时间”的抉择。因为单片机不是运算能力有限,就是存储空间有限!
尽管现如今基于ARM核的微处理器已经普及,其运算能力和存储能力相对于以前8位时代,可谓是翻天覆地!但作为软件开发者,希望自己所写代码能具备移植性的同时还要尽量高效,是一种境界,也是现实要求:人们通常在产品设计上,希望同样的成本做更多的事,或者同样的事用尽量少的成本!
作为程序开发者,研究算法和语言、积累自己的功能函数库,对于提升自己的编程水平、对C语言的应用能力,不失为一个好方法。
我在这里记录下我常用的程序库,方便自己和他人查阅、参考。
这些代码是基于ARM处理器进行实验,所以在分析性能时,用的是ARM汇编。
下面的文件内容是可移植类型定义的头文件(基于ARM),以后的代码都是基于这些类型:
1 #ifndef __FRAME_TYPES__H__ 2 #define __FRAME_TYPES__H__ 3 //////////////////////////////////////////////////////////////////////////////// 4 #include <stdint.h> 5 6 typedef signed char s8_t; 7 typedef unsigned char u8_t; 8 typedef signed short s16_t; 9 typedef unsigned short u16_t; 10 typedef signed long s32_t; 11 typedef unsigned long u32_t; 12 typedef signed long long s64_t; 13 typedef unsigned long long u64_t; 14 typedef float f32_t; 15 typedef double f64_t; 16 typedef unsigned char bool_t; 17 typedef signed long sbase_t; 18 typedef unsigned long ubase_t; 19 20 #if defined __LITTLE_ENDIAN__ 21 #if __LITTLE_ENDIAN__ > 0 22 // 小端字节顺序。 23 #define IS_BIG_ENDIAN (0) 24 #else 25 // 大端字节顺序。 26 #define IS_BIG_ENDIAN (1) 27 #endif 28 #else 29 #error <__LITTLE_ENDIAN__>未定义! 30 #endif 31 32 #ifndef NULL 33 #define NULL ((void*)0) 34 #endif 35 36 #ifndef TRUE 37 #define TRUE (!0) 38 #endif 39 40 #ifndef FALSE 41 #define FALSE (!1) 42 #endif 43 44 //////////////////////////////////////////////////////////////////////////////// 45 #endif /* __FRAME_TYPES__H__ */
其中:sbase_t和ubase_t两种类型,是根据编译器以及处理器位数而定。在ARM的C编译器中定义为32位,在8位单片机的C编译器中定义为8位整数。定义这两个类型,是为了某些函数在参数传递和返回值时,得到更多的优化。比如:ARM处理器的寄存器是32位宽的,指令的处理都基于寄存器,所以临时变量都是32位的;而函数返回u8_t类型时,编译器会将临时运算结果从32位截断成8位以后再返回。如果此时明知运算结果不会超出8位整数范围,那么截断操作就是多余的。这种情况下,使函数返回ubase_t或者sbase_t就行了。