Chinaunix首页 | 论坛 | 博客
  • 博客访问: 73131
  • 博文数量: 13
  • 博客积分: 302
  • 博客等级: 二等列兵
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-27 18:51
文章分类

全部博文(13)

文章存档

2012年(1)

2011年(12)

我的朋友

分类: 嵌入式

2011-04-01 19:28:37

这篇文档重在记述TQ2440的LED驱动,重点在于将LED作为混杂设备注册的方法

即 misc_register(&dev)和misc_deregister(®ister)

这篇文档所基于的环境如下

硬件环境:TQ2440开发板

kernel :linux 2.6.32

文件系统: busybox1.13.1,yaffs2

效果图如下

 

一、code

 

  1. /*
  2. name: leds driver for tq2660
  3. author :keytounix
  4. as char devices
  5. */
  6. #include <linux/module.h>
  7. #include <linux/kernel.h>
  8. #include <linux/init.h>
  9. #include <linux/sched.h>
  10. #include <linux/poll.h>
  11. #include <linux/timer.h>
  12. #include <linux/irq.h>
  13. #include <linux/cdev.h>
  14. #include <linux/wait.h>//waitqueue

  15. #include <linux/errno.h>
  16. #include <linux/interrupt.h>//irq

  17. #include <linux/io.h>
  18. #include <linux/types.h>
  19. #include <linux/delay.h>
  20. #include <linux/semaphore.h>//sem

  21. #include <linux/fs.h>
  22. #include <linux/platform_device.h>//

  23. #include <linux/miscdevice.h>

  24. #include <linux/device.h>
  25. #include <linux/workqueue.h>//workqueue


  26. #include <asm/uaccess.h>
  27. #include <asm/irq.h>

  28. //soc相关


  29. #include <mach/gpio.h>
  30. #include <mach/regs-clock.h>
  31. #include <mach/regs-gpio.h>
  32. #include <mach/hardware.h>
  33. #include <mach/irqs.h>


  34. #define led_name "usr_leds"
  35. #define LED_NAME "usr_leds"

  36. //这个,是为了实现

  37. //任何时刻只能有一个

  38. //使用者能操作led

  39. struct semaphore sem[4];
  40. //打开

  41. static int led_open0(struct inode *nodep,struct file * filep);
  42. static int led_open1(struct inode *nodep,struct file * filep);
  43. static int led_open2(struct inode *nodep,struct file * filep);
  44. static int led_open3(struct inode *nodep,struct file * filep);
  45. //关闭

  46. static int led_release(struct inode *nodep,struct file * filep);
  47. //ioctrl函数

  48. static int led_ioctl(struct inode *nodep,struct file * filep,unsigned int cmd,long args);
  49. //写数据

  50. static int led_write(struct file * filep,char * __user buff,size_t count, loff_t *offt);
  51. //这个函数用来实现对led的读写




  52. static void led_display(int ledno,int status);

  53. struct file_operations fops[]=
  54. {
  55. [0]={
  56. .owner=THIS_MODULE,
  57. .open=    led_open0,
  58. .release=led_release,
  59. .write =led_write,
  60. .ioctl=led_ioctl,
  61. },
  62. [1]=
  63. {
  64. .owner=THIS_MODULE,
  65. .open=led_open1,
  66. .release=led_release,
  67. .write =led_write,
  68. .ioctl=led_ioctl,
  69. },
  70. [2]=
  71. {
  72. .owner=THIS_MODULE,
  73. .open=led_open2,
  74. .release=led_release,
  75. .write =led_write,
  76. .ioctl=led_ioctl,
  77. },
  78. [3]=
  79. {
  80. .owner=THIS_MODULE,
  81. .open=led_open3,
  82. .release=led_release,
  83. .write =led_write,
  84. .ioctl=led_ioctl,
  85. },

  86. };
  87. struct LED_INFO
  88. {
  89. char * name;
  90. unsigned pin;
  91. }led_info[]=
  92. {
  93. [0]={
  94. .name="led1",
  95. .pin=S3C2410_GPB(5)
  96. },
  97. [1]={
  98. .name="led2",
  99. .pin=S3C2410_GPB(6)
  100. },
  101. [2]={
  102. .name="led3",
  103. .pin=S3C2410_GPB(7)
  104. },
  105. [3]={
  106. .name="led4",
  107. .pin=S3C2410_GPB(8)
  108. }
  109. };

  110. static struct miscdevice led_dev[]=
  111. {
  112. [0]=
  113. {
  114. .minor =MISC_DYNAMIC_MINOR,
  115. .name ="led0",
  116. .fops =&fops[0]    
  117. },
  118. [1]=
  119. {
  120. .minor =MISC_DYNAMIC_MINOR,
  121. .name ="led1",
  122. .fops=&fops[1]
  123. },
  124. [2]=
  125. {
  126. .minor=MISC_DYNAMIC_MINOR,
  127. .name ="led2",
  128. .fops =&fops[2]
  129. },
  130. [3]=
  131. {
  132. .minor=MISC_DYNAMIC_MINOR,
  133. .name ="led3",
  134. .fops=&fops[3]
  135. }
  136. };


  137. #define LED_ON 0
  138. #define LED_OFF 1
  139. #define pin(x) led_info[x].pin


  140. #define _DEBUG_ 1


  141. #if _DEBUG_

  142. #define debug(format,msg...) printk(format,##msg)

  143. #else

  144. #define debug(format,msg...) (void *)(0)

  145. #endif
  146. #define dbgi(name,i) debug("in %s ,%s is %d\n",__func__,name,i)

  147. //打开函数,这个 函数里面我们需要获得sem

  148. static int led_open0(struct inode * nodep,struct file *filep)
  149. {
  150.     down(&sem[0]);
  151.     dbgi("filep->private_data",0);
  152.     filep->private_data=0;
  153.     return 0;
  154. }
  155. static int led_open1(struct inode * nodep,struct file *filep)
  156. {
  157.     down(&sem[1]);
  158.     dbgi("filep->private_data",1);
  159.     filep->private_data=1;
  160.     return 0;
  161. }
  162. static int led_open2(struct inode * nodep,struct file *filep)
  163. {
  164.     down(&sem[2]);
  165.     dbgi("filep->private_data",2);
  166.     filep->private_data=2;
  167.     return 0;
  168. }
  169. static int led_open3(struct inode * nodep,struct file *filep)
  170. {
  171.     down(&sem[3]);
  172.     dbgi("filep->private_data",3);
  173.     filep->private_data=3;
  174.     return 0;
  175. }

  176. //关闭函数

  177. static int led_release(struct inode *nodep,struct file *filep)
  178. {
  179.     int i=filep->private_data;
  180.     dbgi("filep->private_data",i);
  181.     i=(i<=3 && i>=0?i:0);
  182.     up(&sem[i]);
  183.     return 0;
  184. }


  185. //ioctrl函数

  186. static int led_ioctl(struct inode * nodep,struct file *filep,unsigned int cmd ,long args)
  187. {
  188.     return 0;
  189. }

  190. static void led_display(int ledno,int status)
  191. {
  192. s3c2410_gpio_setpin(pin(ledno),status);    
  193. debug("in %s,ledno=%d,ledstatus=%d\n",__func__,ledno,status);
  194.     return;
  195. }
  196. //

  197. static int led_write(struct file * filep,char * __user buff,size_t count, loff_t *offt)
  198. {
  199.     int i=filep->private_data;
  200.     
  201.     char led_status[6];
  202.     int cmd;
  203.     dbgi("before i =(i<=3 && i>=0 ? i: 0),i=",i);
  204.     i =(i<=3 && i>=0 ? i: 0);
  205.     dbgi("after i =(i<=3 && i>=0 ? i: 0),i=",i);
  206.     copy_from_user(led_status,buff,count);
  207.     if(led_status[0]=='1' || led_status[0]==1)
  208.         cmd=LED_ON;
  209.     else
  210.         cmd=LED_OFF;
  211.         
  212.         led_display(i,cmd);
  213.     return 0;
  214. }

  215. ////

  216. static void __init led_init()
  217. {

  218.     int i=4;
  219.        for(i=0;i<=3;i++)
  220.        {
  221.     misc_register(&led_dev[i]);
  222.     init_MUTEX(&sem[i]);
  223.     }
  224. }
  225. static void __exit led_exit()
  226. {    int i=4;
  227.     for(i=0;i<=3;i++)
  228.     misc_deregister(&led_dev[i]);
  229. }

  230. MODULE_AUTHOR("keytounix");
  231. MODULE_LICENSE("GPL");
  232. MODULE_DESCRIPTION("driver leds for TQ2440");
  233. module_init(led_init);
  234. module_exit(led_exit);

 

二、Makefile

 

  1. TARGET=led
  2. KERNEL=2.6.32
  3. CC=arm-linux-gcc -w
  4. obj-m :=$(TARGET).o
  5. KERNELDIR :=/kernel/linux-$(KERNEL)
  6. default:
  7. make -C $(KERNELDIR) M=$(shell pwd) modules

 

三、test code

 

  1. //arm-linux-gcc -marcharmv4t t.c -o t

  2. //#insmod led.ko

  3. //#mdev -s

  4. //#./t /dev/ledx 1or0

  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <fcntl.h>
  8. #include <unistd.h>
  9. int main(int argn,char*argv[])
  10. {
  11. int fd=open(argv[1],O_WRONLY,0640);
  12. int w_size=write(fd,argv[2],sizeof(argv[2]));
  13. close(fd);
  14. return 0;
  15. }
阅读(2449) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~