TQ210搭载Android4.0.3系统构建之LED从驱动到HAL到JNI到应用程序(驱动篇)

来源:互联网 发布:淘宝质检报告怎么上传 编辑:程序博客网 时间:2024/06/06 10:58

原帖地址:http://blog.csdn.net/undergrowth/article/details/9157817

 

开发板:TQ210

OS:Android 4.0.3

以下所有内容都是在TQ210开发板上实现,并且很多内容也是天嵌公司提供,我将一些内容进行了删减、替换,然后加入了一些自己的理解,同时也是记录自己学习的旅程。

废话不多说 先看硬件电路图 很简单 通过NPN三极管控制LED的阴极 NPN三极管的基极给高电平 则三级管导通 则LED等点亮 反之则熄灭

 

 

LED驱动源码

led_unders.c

  1. #include <linux/miscdevice.h>  //包含miscdevice misc_register...  
  2. #include <linux/init.h> //包含__init __exit...  
  3. #include <linux/fs.h>  //包含file_operations...  
  4. #include <linux/err.h> //包含EINVAL..  
  5. #include <mach/gpio.h> //包含S5PV210_GPC0() ...  
  6. #include <plat/gpio-cfg.h> //包含S3C_GPIO_SFN() s3c_gpio_cfgpin() gpio_direction_output()..  
  7.   
  8. #define DEVICE_NAME     "led_unders"  //设备名  
  9. #define GPIO_CTIOL_ON 1    //控制LED亮  
  10. #define GPIO_CTIOL_OFF 0  //控制LED 灭  
  11.   
  12.   
  13. static unsigned int gpio_table[]=  //引用I/O引脚  
  14. {  
  15.     S5PV210_GPC0(3), //开发板的手册上是GPC1 ,是错的  
  16.     S5PV210_GPC0(4),  
  17. };  
  18.   
  19. static unsigned int gpio_cfg_table[]= //设置IO为输出  
  20. {  
  21.     S3C_GPIO_SFN(1), //设置引脚为输出  
  22.     S3C_GPIO_SFN(1),  
  23. };  
  24.   
  25.   
  26. static int gpio_led_under_open(struct inode *inode,struct file *file) //打开led_unders设备  
  27. {  
  28.     int ret=0,i;  
  29.     for(i=0;i<sizeof(gpio_table)/sizeof(gpio_table[0]);i++)  
  30.         {  
  31.         s3c_gpio_cfgpin(gpio_table[i], gpio_cfg_table[i]); //设置引脚为输出  
  32.         ret=gpio_direction_output(gpio_table[i],GPIO_CTIOL_OFF); //设置引脚为0  
  33.         }  
  34.     if(ret==0) printk("led_open success.\n");  
  35.     else {ret=-1; printk("led_open failed.\n");}  
  36.     return ret;  
  37. }  
  38.   
  39.   
  40. static int gpio_led_under_close(struct inode *inode,struct file *file)  
  41. {  
  42.     printk(KERN_INFO "led_close success.\n");  
  43.     return 0;  
  44. }  
  45.   
  46. static long gpio_led_under_ioctl(struct file *file,unsigned int cmd,unsigned long arg) //控制哪个led灯亮或者灭  
  47. {  
  48.     int ret=0;  
  49.     printk(KERN_INFO "led ioctl.\n");  
  50.     arg=arg-1;   
  51.     if(arg>sizeof(gpio_table)/sizeof(gpio_table[0])) return -EINVAL; //判断传递的参数是否合法  
  52.     switch(cmd)  
  53.     {  
  54.         case GPIO_CTIOL_ON:  
  55.             gpio_direction_output(gpio_table[arg],GPIO_CTIOL_ON); //点亮LED  
  56.             break;  
  57.         case GPIO_CTIOL_OFF:  
  58.             gpio_direction_output(gpio_table[arg],GPIO_CTIOL_OFF); //熄灭LED  
  59.             break;  
  60.         default:  
  61.             ret=-1;  
  62.             printk(KERN_INFO "led ioctl error");  
  63.     }  
  64.     return ret;  
  65. }  
  66.   
  67. static struct file_operations dev_fops=  
  68. {  
  69.     .owner=THIS_MODULE,  
  70.     .unlocked_ioctl=gpio_led_under_ioctl,  
  71.     .open=gpio_led_under_open,  
  72.     .release=gpio_led_under_close,  
  73. };  
  74.   
  75. static struct miscdevice misc_led=  
  76. { //led混杂设备结构体定义  
  77.     .minor=MISC_DYNAMIC_MINOR,  //动态分配次设备号  
  78.     .name=DEVICE_NAME,    //设备名称  
  79.     .fops=&dev_fops,    //设备操作结构体  
  80. };  
  81.   
  82. static int __init led_init()  //led初始化  
  83. {  
  84.     int ret;  
  85.     ret=misc_register(&misc_led); //注册混杂设备成功注册返回0  
  86.     if(ret==0) printk(KERN_INFO "led_init driver success.\n");  
  87.     else { printk(KERN_INFO "led_init driver failed.\n"); ret=-1;}  
  88.     return ret;  
  89. }  
  90.   
  91. static void __exit led_exit() //led卸载  
  92. {  
  93.     int ret=misc_deregister(&misc_led); //卸载混杂设备 ,成功返回0  
  94.     if(ret==0) printk(KERN_INFO "led_exit driver success.\n");  
  95.     else printk(KERN_INFO "led_exit driver failed.\n");  
  96. }  
  97.   
  98.   
  99. //模块入口与出口  
  100. module_init(led_init);  
  101. module_exit(led_exit);  
  102. MODULE_LICENSE("GPL"); //gpl许可  

Makefile文件

  1. obj-m   :=led_unders.o  
  2.   
  3. KERNELDIR   :=~/java/Kernel_3.0.8_TQ210_for_Android_v1.0/  
  4. PWD :=$(shell pwd)  
  5.   
  6. build:kernel_module  
  7. kernel_module:  
  8.     make -C $(KERNELDIR) M=$(PWD) modules  
  9. clean:  
  10.     make -C $(KERNELDIR) M=$(PWD) clean  

 

Makefile的详细编写 参看GUN的Makefile手册 给一个简单实例连接 http://www.embedu.org/Column/Column310.htm

该驱动模块采用混杂设备来表示led设备,通过使用misc_register函数告诉内核misc_led设备所拥有的功能,

对于混杂设备我看了看源码,个人理解misc_register主要做了三件事,

1.通过MISC_DYNAMIC_MINOR这个标志获取到次设备号

2.通过class_device_create创建/dev/led_unders设备文件

3.通过list_add将misc_led添加到混杂设备链表

测试文件

led_under_driver_test.c

  1. #include <stdio.h>  
  2. #include <fcntl.h>   //文件操作  
  3.   
  4. #define DEVICE_NAME "/dev/led_unders"  //设备名称  
  5.   
  6. #define GPIO_IOCTL_ON 1   //打开led  
  7. #define GPIO_IOCTL_OFF 0  //关闭led  
  8.   
  9. #define LED1 1  
  10. #define LED2 2  
  11.   
  12.   
  13. /*  
  14. usage: led1/led2 on/off  
  15. */  
  16.   
  17. int main(int argc,char **argv)  
  18. {  
  19.     int fd,ison=0,isnumber=0;  
  20.     fd=open(DEVICE_NAME,O_RDWR); //以可读可写的方式打开设备文件  
  21.     if(fd<0)  //判断是否成功打开文件  
  22.         {  
  23.             printf("open %s failed.\n",DEVICE_NAME);  
  24.             return 0;  
  25.         }  
  26.     if(argc!=3)   //判断参数是否合法  
  27.         {  
  28.             printf("usage:\n");  
  29.             printf("led1/led2 on/off\n");  
  30.         }  
  31.     if(strcmp(argv[2],"on")==0) ison=GPIO_IOCTL_ON;  //判断是打开还是关闭LED  
  32.     else ison=GPIO_IOCTL_OFF;  
  33.     if(strcmp(argv[1],"led1")==0) isnumber=LED1;  //判断是操作哪一个LED  
  34.     else isnumber=LED2;  
  35.     if(ison!=0&&isnumber!=0) ioctl(fd,ison,isnumber);  //操作led  
  36.     return 0;  
  37. }  


通过输入的参数来控哪个led灯的亮或者灭

编译文件 Android.mk

  1. LOCAL_PATH :=$(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE_TAGS :=eng  
  4. LOCAL_SRC_FILES :=led_under_driver_test.c  
  5. LOCAL_MODULE :=led_unders  
  6. LOCAL_MODULE_PATH :=$(LOCAL_PATH)  
  7. include $(BUILD_EXECUTABLE)  


对于android编译系统 可以查看官网 http://www.kandroid.org/online-pdk/guide/build_system.html

但是对于LOCAL_MODULE_TAGS :=eng 这一项还不是很理解 LOCAL_MODULE_TAGS的设置与Build Variants有关,但是LOCAL_MODULE_TAGS :=eng为默认设置,即不设置默认就是LOCAL_MODULE_TAGS :=eng,但是在实际编译过程中,如果不加LOCAL_MODULE_TAGS :=eng的话,编译会出错,具体原因还不清楚,有清楚的朋友,麻烦告诉我一下哈。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 从网上买的沙发物流超级慢怎么办 三星c5手机玩王者荣耀卡怎么办 买手机送话费的卡不想用了怎么办 到银行存钱被骗买保险了怎么办 去银行存钱被骗买了保险怎么办 京东申请退款后卖家又发货了怎么办 苹果6s没有4g网怎么办 花呗分期付款买手机额度不够怎么办 手机天猫不支持购买淘宝商品怎么办 天猫国际购买商品狠盾怎么办 在微信上微拍堂买东西被骗了怎么办 京东自营买到返修手机怎么办? 7p弯了怎么办能修复吗 农商银行app登录密码忘了怎么办 网址上的重庆时时彩不能提现怎么办 天天中彩票自己账户登录不了怎么办 天猫上卖王者荣耀的兑换码是怎么办 身份证借别人开淘宝永久封店怎么办 天猫店铺被扣12分怎么办 天猫法人变更之前的天猫贷款怎么办 在日本旅游遇到精日导游怎么办 银行资金交易异常卡被冻结怎么办 如果淘宝被盗了店铺乱上东西怎么办 快递不送货直接代售点签收怎么办 淘宝快递没收到却显示已签收怎么办 支付宝余额未满16受限怎么办 未满16岁支付宝余额受限怎么办 手机天猫购物买的数量大怎么办 扣扣游戏领礼包出现账号异常怎么办 美容院转让给别人客人要退钱怎么办 卖家毁约中介费担保费怎么办 天猫买东西店家不开增值税票怎么办 天猫专卖店品牌不授权了怎么办 临时京东账号被冻结买的东西怎么办 天猫强行退款给买家商家怎么办 淘宝店铺没交保证金被释放了怎么办 沭阳县地段生过了报名时间怎么办 淘宝买东西地址和收件人填错怎么办 才装修的房子马上要住怎么办 淘宝发货显示无效的发货人怎么办 微信位置和所在地位置不一样怎么办