Linux设备驱动移植注意事项

  • 移植驱动前注意数据类型:

u8u16u32u64s8s16s32s64只能在内核空间使用

_ _u8_ _u16_ _u32用来用户空间

驱动中最好使用 int8_tint16_tint32_tuint8_tuint16_tuint32_tint64_tuint64_t 这些 C99 标准确定长度类型

  • 结构体对界

默认情况下,编译器为结构体的每个成员按其自然对界(natural alignment)条件分配空间,各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。自然对界指按结构体的成员中 sizeof 最大的成员对齐

  • Little Endian Big Endian

采用 Little Endian 模式的 CPU 对操作数的存放方式是从低字节到高字节,而 Big Endian 模式对操作数的存放方式是从高字节到低字节

  • 内存页面大小

内存页一般在4-64k大小。不同的 PAGE_SIZE 和 PAGE_SHIFT可以确定申请内存大小

当在内核空间中通过 get_free_pages()函数申请内存时,公式如下:PAGE_SIZE * 2order

即,PAGE_SIZE和order确定内存大小。

  • 当出现从无操作系统的驱动移植到linux上。则需要注意以下几点

一:无操作系统的硬件访问方法中往往没有物理地址到虚拟地址的映射过程,因此,在搬到 Linux 系统中的时候,要注意以静态映射或 ioremap()等方式映射到虚拟地址

二:硬件访问中往往夹杂着延时,因此,在无操作系统的源码中,经常会出现xxx_delay()这样的 for 循环延迟,这些代码应该被内核中的 ndelay()或 udelay()替换。如果延迟时间达到数十 ms,应该使用 msleep()或 msleep_interruptible()等函数

三:如果系统中用的 Linux 不支持抢占调度,while (!(regb &0x1));需要相当长的时间(如数十 ms),这种忙等待会导致其他的进程全部得不到机会执行

四:从良好的代码风格角度出发,模块中不需要输出到内核空间且不需为模块中其他文件所用的全局变量及函数最好显式申明为 static 类型,需要输出的内核符号最好以模块名为前缀

猜你喜欢

转载自blog.csdn.net/qq_33600019/article/details/82840995