fs4412开发板led驱动

阅读实验手册第16章《 LED 驱动开发实验 》P275下:
   fs4412_led.c, fs4412_led.h, test.c 文件 

1.系统调用函数

test.c的main函数中,

while(1) {

       ioctl(fd, LED_ON, &i);

       usleep(500000);

       ioctl(fd, LED_OFF, &i);

       usleep(500000);

       if(++i == 5)

           i = 1;

}

是系统调用函数,调用了fs4412_led.c文件中的ioctl{}函数。函数如下:

fs4412开发板led驱动_第1张图片

fs4412开发板led驱动_第2张图片

函数分析:

(1).函数参数中的file指针对应于应用程序传递的文件描述符fd,这和传递open方法的参数一样。

cmd 由用户空间直接不经修改的传递给驱动程序

arg 可选。

(2). 在驱动程序中实现的ioctl函数体内,实际上是有一个switch {case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是每一个程序员自己的事情,因为设备都是特定的。

对应于这个函数,命令码是fs4412_led.h文件中定义的宏命令:

fs4412开发板led驱动_第3张图片

(3). 用户使用intioctl(int fd,unsinged long cmd,...)时,...就是要传递的参数;

   再通过int(*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsignedlong arg)中的arg传递;

  如果arg是一个整数,可以直接使用;

  如果是指针,我们必须确保这个用户地址是有效的,因此,使用之前需要进行正确检查。

对应于这个函数的copy_from_user指针,是内部有检查的,我们不需要检测。

 

 

2. 找出寄存器地址解析代码并解释

在fs4412_led.c文件一开头,定义了如下

#define FS4412_GPF3CON  0x114001E0 //绑定寄存器地址(物理地址)

………..

static unsigned int *gpf3con;  //定义指针(虚拟地址)

………..

寄存器地址解析代码:

fs4412_led.c文件中的fs4412_led_ioremap()函数将IO地址空间映射到内核的虚拟空间上,定义了地址与指针的关联,从而可以利用得到的指针进行操作。这样做的目的是保证函数安全。函数片段如下:

gpf3con = ioremap(FS4412_GPF3CON, 4);

   if (gpf3con == NULL) {

       printk("ioremap gpf3con\n");

       ret = -ENOMEM;

       return ret;

 

3. 找出寄存器读写代码并解释

fs4412_led_io_init()函数进行了寄存器读写

void fs4412_led_io_init(void)

{

   writel((readl(gpf3con) & ~(0xff << 16)) | (0x11 << 16),gpf3con);

   writel(readl(gpx2dat) & ~(0x3<<4), gpf3dat);

   writel((readl(gpx1con) & ~(0xf << 0)) | (0x1 << 0),gpx1con);

   writel(readl(gpx1dat) & ~(0x1<<0), gpx1dat);

   writel((readl(gpx2con) & ~(0xf << 28)) | (0x1 << 28),gpx2con);

   writel(readl(gpx2dat) & ~(0x1<<7), gpx2dat);

}

以第一行为例:

将gpf3con指针指向的那块物理地址空间中的内容读出来,进行& ~(0xff << 16)) | (0x11 << 16)等一系列操作后,再写回gpf3con指向的物理空间中(0x114001E0)

 

4. 和裸机环境下的驱动编程,有何不同?试给出自己的理解和认识

  裸机编程指的是没有操作系统支持的硬件系统编程,而实际的编程工作肯定需要一个环境,通常这样的情况中,编程和编译的环境叫做“宿主机”,最终的程序在“目标机”上运行(交叉编译)。而OS环境编程指的是最终运行的程序是在有操作系统支持的环境中运行,而编程和编译的环境,可能是运行程序的机器(本地编译),也可能不是(交叉编译)。

  裸机编程现在主要是正对低端的嵌入式系统,如SCM(single chip machine)、各式MCU、DSP等。当然,编写PC的bootloader肯定也属于裸机编程。

 

  裸机编程的最原始办法是用汇编语言(一种机器指令的一一对应的记法,和加上一些简单的汇编伪指令),只能使用很有限的指令集,每行代码只能做微小的事情。因此现在裸机编程也普遍使用更高级的语言(通常是C语言),那么从C语言转换到汇编语言这个过程就叫做编译。编译器根据不同的机器,将通用的C代码转化为特定的机器代码,只有十分少量的机器代码仍然需要用到汇编,这其实是一种混合编程的模式。那么,编译器实在是一种十分重要的工具,编译的理论和实践知识也会十分丰富。

   而在有OS支持的环境中编程则更加便利了。首先OS管理并扩展了整个机器资源,提供了一个通用的API系统调用接口,程序员通过这个接口与硬件资源打交道,因此在OS上编程更加不需要考虑机器的特性,换句话说就是移植性最佳。作为资源的扩展,OS提供了大量的机制(包括进程、内存管理、设备操作等等)和库文件(这些库文件属于可重用的代码),让编写实用程序更加便利。

你可能感兴趣的:(Linux)