snifer

[原创]嵌入式系统中如何分配确定的空间大小给数据项

0
阅读(3084)

在Blackfin嵌入式系统中,经常需要在内核代码需要指定大小的数据项,或者用来匹配二进制结构*或者用来在结构中插入填充字段对齐数据。

 

为此目的,内核提供如下的数据类型,它们都在头文件<asm/types.h>中声明,这个文件又被头文件<uclinux/types.h>所包含:

 

u8;    /* 无符号字节(8位) */

u16;   /* 无符号字(16 位) */

u32;   /* 无符号32位数值*/

u64;   /* 无符号64位数值*/

 

这些数据类型只能被内核代码所访问(也即,在包含头文件<uclinux/types.h>之前必须先定义__KERNEL__)。相应的有符号类型也是存在的,但一般不用;如果你需要使用它们的话,只要把名字中的u替换为s就可以了。

 

如果用户空间的程序需要使用这些类型,可以在这些名字前面添加2个下划线:__u8和其它类型是独立于__KERNEL__定义的。例如,如果一个驱动程序需要通过ioctl系统调用与一个运行在用户空间内的程序交换二进制结构的话,头文件必须将结构中的32位字段定义为__u32

 

重要的是要记住这些类型特定于ucLinux,使用它们就会防碍软件向其他Unix变体的移植。但是,有些情况下也需要明确说明数据大小,而标准头文件(在每个Unix系统上都能找到的)并未声明较合适的数据类型。

 

你也许注意到,有时内核也使用一般的数据类型,象unsigned int,用于那些大小与体系结构无关的项。这通常是为了向后兼容。当u32及其相关类型在1.1.67版本引入时开发者没办法把存在的数据类型改成新类型,因为当结构字段和赋予的值之间类型不匹配时,编译器会发出警告+。Linus当初可没预料到为自己使用而编写的这个操作系统会发展成为多平台的;因此,一些旧的结构的数据类型定义上不是很严格。

*读分区表时,执行二进制文件时或者解码一个网络包时,就会发生这种情况。

+实际上,即使两种类型仅是同一对象的不同名字,例如PC上的unsigned longu32类型,编译器也会发出类型不匹配的信号。

最近想写一本驱动方面的书,在整理资料和一个出版社联系,希望能静下心来积淀一下,争取有所突破,谢谢大家的支持。