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

原帖地址: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的话,编译会出错,具体原因还不清楚,有清楚的朋友,麻烦告诉我一下哈。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值