字符驱动设计----mini2440 LED驱动设计之路

发布时间:2024-06-20  

大多数书籍在介绍字符驱动过于理论化,纵览一章都是些文字,再附上一些零碎的代码,看的人头晕,时间长了自然就不想看了。 对于驱动的学习,刚开始不能过于理论化,一定要结合实际,要不然像空中楼台,住在上面,心里老感觉不踏实。那么如何入手呢?我觉得三点是很重要的:

1  驱动设计的总体框架(对于每种类型的驱动设计,最好画出模型图)

2  参考现有实例化的驱动

3  针对某一具体硬件,自己写驱动来实现

 接下来以字符驱动设计为例,也是mini2440led驱动实现。

1 字符设备驱动模型如下图所示,这是一个总体调用框架图,具体的字符设备驱动模型参照另外一篇引用的文章【字符设备驱动模型】,驱动层主要做的工作是file_operations结构体中一些关键函数的实现,包括open,read,ioctl。本例中主要实现open,ioctl。

2 现有驱动模型实例

  1. #include    

  2. #include    

  3. #include    

  4. #include    

  5. #include    

  6. #include    

  7. #include    

  8. #include    

  9.   

  10. #define DEVICE_NAME     "leds"  /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */   

  11. #define LED_MAJOR       231     /* 主设备号 */   

  12.   

  13. /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */  

  14. #define IOCTL_LED_ON    0   

  15. #define IOCTL_LED_OFF   1   

  16.   

  17. /* 用来指定LED所用的GPIO引脚 */  

  18. static unsigned long led_table [] = {  

  19.     S3C2410_GPB5,  

  20.     S3C2410_GPB6,  

  21.     S3C2410_GPB7,  

  22.     S3C2410_GPB8,  

  23. };  

  24.   

  25. /* 用来指定GPIO引脚的功能:输出 */  

  26. static unsigned int led_cfg_table [] = {  

  27.     S3C2410_GPB5_OUTP,  

  28.     S3C2410_GPB6_OUTP,  

  29.     S3C2410_GPB7_OUTP,  

  30.     S3C2410_GPB8_OUTP,  

  31. };  

  32.   

  33. /* 应用程序对设备文件/dev/leds执行open(...)时, 

  34.  * 就会调用s3c24xx_leds_open函数 

  35.  */  

  36. static int s3c24xx_leds_open(struct inode *inode, struct file *file)  

  37. {  

  38.     int i;  

  39.       

  40.     for (i = 0; i < 4; i++) {  

  41.         // 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能   

  42.         s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);  

  43.     }  

  44.     return 0;  

  45. }  

  46.   

  47. /* 应用程序对设备文件/dev/leds执行ioclt(...)时, 

  48.  * 就会调用s3c24xx_leds_ioctl函数 

  49.  */  

  50. static int s3c24xx_leds_ioctl(  

  51.     struct inode *inode,   

  52.     struct file *file,   

  53.     unsigned int cmd,   

  54.     unsigned long arg)  

  55. {  

  56.     if (arg > 4) {  

  57.         return -EINVAL;  

  58.     }  

  59.       

  60.     switch(cmd) {  

  61.     case IOCTL_LED_ON:  

  62.         // 设置指定引脚的输出电平为0   

  63.         s3c2410_gpio_setpin(led_table[arg], 0);  

  64.         return 0;  

  65.   

  66.     case IOCTL_LED_OFF:  

  67.         // 设置指定引脚的输出电平为1   

  68.         s3c2410_gpio_setpin(led_table[arg], 1);  

  69.         return 0;  

  70.   

  71.     default:  

  72.         return -EINVAL;  

  73.     }  

  74. }  

  75.   

  76. /* 这个结构是字符设备驱动程序的核心 

  77.  * 当应用程序操作设备文件时所调用的open、read、write等函数, 

  78.  * 最终会调用这个结构中指定的对应函数 

  79.  */  

  80. static struct file_operations s3c24xx_leds_fops = {  

  81.     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */  

  82.     .open   =   s3c24xx_leds_open,       

  83.     .ioctl  =   s3c24xx_leds_ioctl,  

  84. };  

  85.   

  86. /* 

  87.  * 执行“insmod s3c24xx_leds.ko”命令时就会调用这个函数 

  88.  */  

  89. static int __init s3c24xx_leds_init(void)  

  90. {  

  91.     int ret;  

  92.   

  93.     /* 注册字符设备驱动程序 

  94.      * 参数为主设备号、设备名字、file_operations结构; 

  95.      * 这样,主设备号就和具体的file_operations结构联系起来了, 

  96.      * 操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数 

  97.      * LED_MAJOR可以设为0,表示由内核自动分配主设备号 

  98.      */  

  99.     ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);  

  100.     if (ret < 0) {  

  101.       printk(DEVICE_NAME " can't register major numbern");  

  102.       return ret;  

  103.     }  

  104.       

  105.     printk(DEVICE_NAME " initializedn");  

  106.     return 0;  

  107. }  

  108.   

  109. /* 

  110.  * 执行”rmmod s3c24xx_leds.ko”命令时就会调用这个函数  

  111.  */  

  112. static void __exit s3c24xx_leds_exit(void)  

  113. {  

  114.     /* 卸载驱动程序 */  

  115.     unregister_chrdev(LED_MAJOR, DEVICE_NAME);  

  116. }  

  117.   

  118. /* 这两行指定驱动程序的初始化函数和卸载函数 */  

  119. module_init(s3c24xx_leds_init);  

  120. module_exit(s3c24xx_leds_exit);  

  121.   

  122. /* 描述驱动程序的一些信息,不是必须的 */  

  123. MODULE_AUTHOR("http://my.csdn.net/czxyhll.");        // 驱动程序的作者  

  124. MODULE_DESCRIPTION("S3C2410/S3C2440 LED Driver");   // 一些描述信息   

  125. MODULE_LICENSE("GPL");                              // 遵循的协议  


现在就对字符设备驱动进行分析:

1 在open函数里有s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]),此函数实现相应GPIO的功能,包括输入输出及其他功能。这个函数看似简单,如果想彻底弄明白还是有一定的难度,应为此函数的实现涉及到I/O内存空间,物理地址PA与虚拟地址VA的映射,GPIO寄存器的方面的知识。先附上其函数原型。

  1. void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)  

  2. {  

  3.     void __iomem *base = S3C24XX_GPIO_BASE(pin);  

  4.     unsigned long mask;  

  5.     unsigned long con;  

  6.     unsigned long flags;  

  7.   

  8.     if (pin < S3C2410_GPIO_BANKB) {  

  9.         mask = 1 << S3C2410_GPIO_OFFSET(pin);  

  10.     } else {  

  11.         mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;  

  12.     }  

  13.   

  14.     switch (function) {  

  15.     case S3C2410_GPIO_LEAVE:  

  16.         mask = 0;  

  17.         function = 0;  

  18.         break;  

  19.   

  20.     case S3C2410_GPIO_INPUT:  

  21.     case S3C2410_GPIO_OUTPUT:  

  22.     case S3C2410_GPIO_SFN2:  

  23.     case S3C2410_GPIO_SFN3:  

  24.         if (pin < S3C2410_GPIO_BANKB) {  

  25.             function -= 1;  

  26.             function &= 1;  

  27.             function <<= S3C2410_GPIO_OFFSET(pin);  

  28.         } else {  

  29.             function &= 3;  

  30.             function <<= S3C2410_GPIO_OFFSET(pin)*2;  

  31.         }  

  32.     }  

  33.   

  34.     /* modify the specified register wwith IRQs off */  

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>