当你翻开代码一看居然有一些诸如s3c2410_gpio_setpin的函数的时候,你一定心中一声感叹!艹,这个函数那来的?
  为什么会有这些函数呢?原因是linux平台对arm体系是有支持的,比如这些基本的函数,当我们开发程序的时候可以用,有人觉得为什么要用它的自己写不是更cool吗?个人觉得从学习角度来说未尝不可,但从开发觉得还是高效重要,为什么在应用程序里C++比C更流行,正是因为C++的效率更高,有更多库的支持,因此我觉得不管是我们软件应用开发也好或者硬件的应用开发也好,开发的难度一定是越来越小,开发效率是越来越高!所以,平台给我们提供的函数能用则用!
  这个函数一旦建立,我们可以通过通过操作系统的ioctl函数来间接操作heatnan_leds.ioctl,从而控制led。
  下面是一些程式化的东西了,模块的初始化,模块的退出以及设备的注册等一些列比较俗的问题了。
  ×××××××××××××××××××累的赶脚,活剥不起来la,linux驱动开发感觉累累的!@
  下面贴出整个led驱动代码,主要是仿照数据手册写的,这次主要是入门的学习以及对驱动开发的理解。明天要进入脱离数据手册的驱动编写辣!好赤鸡的感觉!
  1 #include<linux/kernel.h>
  2 #include<linux/module.h>
  3 #include<linux/miscdevice.h>
  4 #include<linux/gpio.h>
  5 #include<linux/fs.h>
  6 #include<linux/init.h>
  7 #include<mach/regs-gpio.h>
  8 #include<mach/hardware.h>
  9
  10 #define DEVICE_NAME "heat_leds"
  11
  12
  13 static unsigned long led_table []= {
  14         S3C2410_GPB(5),
  15         S3C2410_GPB(6),
  16         S3C2410_GPB(7),
  17         S3C2410_GPB(8),
  18 };
  19 static unsigned int led_cfg_table  []={
  20         S3C2410_GPIO_OUTPUT,
  21         S3C2410_GPIO_OUTPUT,
  22         S3C2410_GPIO_OUTPUT,
  23         S3C2410_GPIO_OUTPUT,
  24 };
  25 static int heatnan_leds_ioctl(
  26         struct inode *inode,
  27         struct file *file,
  28         unsigned int cmd,
  29         unsigned long arg)
  30 {
  31        if(arg<0||arg>3)
  32        {
  33            return -EINVAL;
  34        }
  35        switch(cmd)
  36        {
  37             case 0:
  38             case 1:
  39                 {
  40                       s3c2410_gpio_setpin(led_table[arg],!cmd);
  41                       return 0;
  42                 }
  43             default:
  44                       return -EINVAL;
  45
  46        }
  47 }
  48 static struct file_operations dev_fops={
  49         .owner = THIS_MODULE,
  50         .ioctl= heatnan_leds_ioctl,
  51 };
  52 static struct miscdevice misc={
  53         .minor=MISC_DYNAMIC_MINOR,
  54         .name=DEVICE_NAME,
  55         .fops=&dev_fops,
  56 };
  57 static int __init led_init(void)
  58 {
  59         int ret;
  60         int i;
  61         for(i=0;i<4;i++)
  62         {
  63                 s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
  64                 s3c2410_gpio_cfgpin(led_table[i],0);
  65         }
  66         ret=misc_register(&misc);
  67         printk(DEVICE_NAME" initialized ");
  68         return ret;
  69 }
  70 static void __exit led_exit(void)
  71 {
  72         misc_deregister(&misc);
  73 }
  74 module_init(led_init);
  75 module_exit(led_exit);
  76 MODULE_LICENSE("GPL");
  终于tmd写完了这个驱动函数,可如果事情到这里结束那也是相当完美啊!按照昨天的方法顺利把驱动模块化编译成功弄到了开发板上,
  结果
  结果,烧上驱动测试程序后灯真的没亮,我用lsmod和dev下豆发现了模块正在运行,灯是不亮。。。。。。
  后来我猜想可能是开发板的内核中已经有了led驱动,我这个led驱动和那个led驱动本质是一样的只是名字不一样那个,应该是冲突了。。。。。
  于是卸下屏幕观看,开机,灯全亮,加载我的驱动,灯全灭,欧耶~看来我猜的有道理???????
  好了,不说那些桑心的事啦!整理整理发型,明天继续!
  等串口线回来了,一定要把这个问题弄清楚,看是不是这样的!如果有遇到这个问题的大牛不妨分享下经验,灰常感谢!
  驱动编程有感:
  1 驱动编程有种瞻前顾后的感觉,在linux系统中的编程,眼光停留在硬件上远远不够的,还要注意linux系统的外部接口,只有这样才能做到外部接口和自己写的驱动接口完美衔接。
  2 感觉驱动开发像带着脚镣跳舞,底层的硬件的基本相关函数,linux已经支持,上层的系统接口,linux系统也已经制定了,我们能做的,是再硬件和系统之间合理周旋。是一个非常考验人的活!前期感觉是累,后期恐怕是智商挑战了吧!
  3 分析linux驱动的时候,可以适当采用倒叙分析,先从操作系统接口开始,一步一步找到和硬件完美的契合点。