对于驱动的学习停歇了几乎一周的时间,期间忙于补习Linux应用编程和搜索驱动、内核相关书籍,以便之后更进一步地学习。在之前友善提供的驱动例程里面,涉及的知识面非常有限,需要研究更多的驱动源码,了解更多的驱动知识,是当务之急。研究别人代码的同时,当然不忘自己也要动手练习。以下贴出串口驱动程序,并在程序里附上简要注释。
几个问题需要我们注意:
1.设备如何注册、注销
串口驱动被作为一个单独的模块被加载进内核,在模块的加载和卸载函数中,只需注册和注销一个platform_driver结构体。
注册:
注销:
2.几个非常重要的结构体
s3c2410_uartcfg :保存ucon ulcon ufcon三个串口寄存器的值
s3c24xx_uart_info :提供串口设备环境信息,并提供三个函数的接口
platform_device :设备的信息
platform_driver :设备注册用
3.读写寄存器的宏定义
(1)读寄存器
unsigned long ucon = rd_regl(port, S3C2410_UCON);
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
static unsigned char __raw_readb(unsigned int ptr)
{
return *((volatile unsigned char *)ptr);
}
#define portaddr(port, reg) ((port)->membase + (reg))
(2)写寄存器
wr_regl(port, S3C2410_UCON, ucon);
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
#define portaddr(port, reg) ((port)->membase + (reg))
#define __raw_writel(v,p) (*(unsigned long *)(p) = (v))
4.函数的注册方式
细心的朋友可能会发现,我们之前一直使用的是传统的 device driver 机制(通过 driver_register 函数进行注册)本串口所使用的是一个设备用 Platform_device 表示,驱动用 Platform_driver 进行注册的机制。而后者是在内核2.6版本所提出来的新事物,其优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过 platform device 提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性(这些标准接口是安全的)。关于这两种机制更深入的分析,请看以下链接:http://blog.csdn.net/jarvis_xian/archive/2011/05/23/6440649.aspx