那为什么是ioctl函数呢?这个问题弄清楚灰常重要!因为我们前边说过file_operations内的函数是对文件操作的的映射,我们要控制led,实质是控制IO口的电平,这点不管它操作系统的驱动还是单片机的驱动实质都是一样的啦!此时,我瞬间明白鸟,icctl不是IO Control的缩写吗?不是文件的控制IO吗?因为我们要控制led,所以需要控制IO口,要控制IO对应的系统调用函数不是ioctl吗?我们在驱动中需要做的是给这个ioctl函数进行编写,然后系统可以通过调用ioctl这个系统函数来通过file_operactions来关联到真正的驱动函数。欧耶 ~      终于都清楚啦!
  现在,软件方面的核心都打通啦!既然是驱动,当然少不了硬件啦!
  这四个led与固定的四个IO口连接,像这样的东西开发板原理图上是交代的很清楚的,我们必须按照开发板上的关系来进行。这四个led占用的IO寄存器分别为GPB5/GPB6/GPB7/GPB8;这 好比当年我们单片机的P0/P1一样一样的,P0/P1都被定义在了reg51.h里面,而这里的IO口同样也被定义到了<arch/regs-gpio.h>里,这里我们声明这四个IO口寄存器,这样我们操作IO口可以控制led了。
  1 static unsigned long led_table []= {
  2         S3C2410_GPB(5),
  3         S3C2410_GPB(6),
  4         S3C2410_GPB(7),
  5         S3C2410_GPB(8),
  6 };
  这里需要注意的是与led连接的GPIO口可以用于输入/输出或者其他功能,我们的开发板上led接的是共阳极的,所以我们需要这些GPIO口作为输出口,只要我们输出低电平可以让led亮了。既然这个IO口有多种功能,那一定有相关的配置寄存器 。所以我们需要将每个led对应的寄存器定义为输出。
  1 static unsigned int led_cfg_table  []={
  2         S3C2410_GPIO_OUTPUT,
  3         S3C2410_GPIO_OUTPUT,
  4         S3C2410_GPIO_OUTPUT,
  5         S3C2410_GPIO_OUTPUT,
  6 };
  做好了前面的所有工作,现在是驱动的核心了。如何控制 ?这的确是一个question?这时忽然想起了,前面分析的file_operations,这个玩意不是系统和驱动的纽带吗?控制led系统需要ioctl函数,所以在flie_operations中我们也需要一个和驱动直接联系的ioctl函数,那么我们命名这个函数为heatnan_leds_ioctl;函数的原型前面file_operaction 中已经给出了,有种直接领表填单的赶脚!而且下面的开发思路也都清晰起来,那是需要什么样的功能直接参考file_operactions结构体的参数模型是了。
  针对于led的驱动,要实现应用程序控制led的亮灭——>需要系统调用ioctl函数——>要使系统的ioctl函数能够控制硬件——>需要在file_operations中建立一个真正控制led驱动的函数——>新建控制led的函数(这里命名为heatnan_leds_ioctl).
  首先我们建立连接关系:
  1 static struct file_operations dev_fops={
  2         .owner = THIS_MODULE,
  3         .ioctl= heatnan_leds_ioctl,
  4 };
  建立这个核心纽带后,要书写heatnan_leds_ioctl这个函数啦!
  要书写这个函数必须要对这个函数的两种形式有所了解,即需要对ioctl函数做功课,ioctl在系统函数中有三个参数,第三个参数可选,第一个参数代表操作设备的号,第二个参数代表操作命令,第三个可选参数可以以不同数据类型作为参数传递也不是必须的。
  与之在file_operactions中对应的ioctl则多了一个参数,它的前两个参数对应系统函数的第一个参数,控制命令则进行原封不动的接收。

 

1 static int heatnan_leds_ioctl(
2         struct inode *inode,
3         struct file *file,
4         unsigned int cmd,
5         unsigned long arg)
6 {
7        if(arg<0||arg>3)
8        {
9            return -EINVAL;
10        }
11        switch(cmd)
12        {
13             case 0:
14             case 1:
15                 {
16                       s3c2410_gpio_setpin(led_table[arg],!cmd);
17                       return 0;
18                 }
19             default:
20                       return -EINVAL;
21
22        }
23  }