要看懂驱动源码,肯定是要从最基本的看起,C语言中,如printf("hello world\n");而对于驱动,肯定是LED,呵呵,恰好年轻时写过一个,还保留着,而且是流水灯式的,下面以ARM270(共有8个LED灯)为例。
一、无操作系统时的LED驱动
在嵌入式系统的设计中,LED一般直接由CPU的GPIO(通用可编程 I/O 口)控制。GPIO一般由两组寄存器控制,即一组控制寄存器和一组数据寄存器。控制寄存器可设置GPIO 口的工作方式为输入或输出。当引脚被设置为输出时,向数据寄存器的对应位写入1和0会分别在引脚上产生高电平和低电平;当引脚设置为输入时,读取数据寄存器的对应位可获得引脚上相应的电平信号。则在无操作系统的情况下,设备驱动代码如下所示。
//片选B-CS4基地址为0x10000000,数码管的偏移地址为0x500000.
#defineSHOW_LED (*((volatile unsigned int *)0x10500000))
#defineCTRL _LED (*((volatile unsigned int *)0x40E00068)) //GPIO80设置为转换功能2
//初始化LED ,一般不需要初始化,因为boot已经对其进行初始化了。
voidLightInit(void)
{
CTRL_LED = 0x1400; /*设置GPIO为输出*/
}
//点亮第n个LED
voidLightOn(void)
{
SHOW_LED &= ~(1 << n);/*在GPIO上输出低电平*/
}
//熄灭第n个LED
voidLightOff(void)
{
SHOW_LED |= (1 << n); /*在GPIO上输出高电平*/
}
上述程序中的LightInit()、LightOn()、LightOff()等函数都将作为 LED驱动提供给应用程序的外部接口函数。 程序中ToVirtual()等函数的作用是当系统启动了硬件MMU之后,根据物理地址和虚拟地址的映射关系,将寄存器的物理地址转化为虚拟地址。