学习 1-在Ubuntu上为Android系统编写Linux内核驱动程序

       学习android以来,对于其从上到下的调用接口一直是做些修修补补的工作,为了系统的掌握Android从上到下的调用关系,更好的写好驱动以便为应用所调用,转载并学习了 老罗的Android之旅 的文章,收益颇深,在此表示感谢!


按照老罗的描述,添加kernel中hello设备驱动,编译,仅在hello_create_proc时出现错误,经查看知道owner不是结构proc_dir_entry中的的变量,屏蔽编译ok,代码更改如下:

[cpp]  view plain copy
  1. /*创建/proc/hello文件*/    
  2. static void hello_create_proc(void) {    
  3.     struct proc_dir_entry* entry;    
  4.         
  5.     entry = create_proc_entry(HELLO_DEVICE_PROC_NAME, 0, NULL);    
  6.     if(entry) {    
  7.       //  entry->owner = THIS_MODULE;  //Harvey remove  
  8.         entry->read_proc = hello_proc_read;    
  9.         entry->write_proc = hello_proc_write;    
  10.     }    
  11. }    

其余按照说明,验证ok,为了增加理解,自己添加dev/hello的ioctl,代码修改如下:
[cpp]  view plain copy
  1. /* 定义幻数 */    
  2. #define HELLODEV_IOC_MAGIC  't'    
  3.     
  4. /* 定义命令 */    
  5. #define HELLODEV_IOCPRINT          _IO(HELLODEV_IOC_MAGIC, 1)  //没参数    
  6. #define HELLODEV_IOCGETDATA            _IOR(HELLODEV_IOC_MAGIC, 2, int)  //读    
  7. #define HELLODEV_IOCSETDATA     _IOW(HELLODEV_IOC_MAGIC, 3, int)  //写    
  8.   
  9. static int hello_ioctl(struct inode *inode, struct file *fp,unsigned int cmd, unsigned long arg);  
  10.     
  11. /*设备文件操作方法表*/    
  12. static struct file_operations hello_fops = {    
  13.     .owner = THIS_MODULE,    
  14.     .open = hello_open,    
  15.     .release = hello_release,    
  16.     .read = hello_read,    
  17.     .write = hello_write,     
  18.     .ioctl = hello_ioctl,//harvey add   
  19. };    

[cpp]  view plain copy
  1. static int hello_ioctl(struct inode *inode, struct file *fp,  
  2.             unsigned int cmd, unsigned long arg)  
  3. {  
  4.     
  5.     int err = 0;    
  6.     int ret = 0;    
  7.     struct hello_android_dev* dev;                
  8.     void __user *argp = (void __user *)arg;  
  9.         
  10.     /*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/    
  11.     dev = container_of(inode->i_cdev, struct hello_android_dev, dev);    
  12.       
  13.     /* 检测命令的有效性 */    
  14.     if (_IOC_TYPE(cmd) != HELLODEV_IOC_MAGIC)     
  15.         return -EINVAL;    
  16.     //if (_IOC_NR(cmd) > MEMDEV_IOC_MAXNR)     
  17.     //    return -EINVAL;    
  18.     
  19.     /* 根据命令类型,检测参数空间是否可以访问 */    
  20.     if (_IOC_DIR(cmd) & _IOC_READ)    
  21.         err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));    
  22.     else if (_IOC_DIR(cmd) & _IOC_WRITE)    
  23.         err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));    
  24.     if (err)     
  25.         return -EFAULT;   
  26.   
  27.     /* 根据命令,执行相应的操作 */    
  28.     switch(cmd) {    
  29.     
  30.       /* 打印当前设备信息 */    
  31.       case HELLODEV_IOCPRINT:    
  32.         printk("<--- CMD MEMDEV_IOCPRINT Done--->\n\n");    
  33.       break;    
  34.           
  35.       /* 获取参数 */    
  36.       case HELLODEV_IOCGETDATA:    
  37.         if(copy_to_user(argp, &(dev->val), sizeof(dev->val)))  
  38.         {  
  39.             printk("do gpio_ioctl:copy_from_user error!\n");  
  40.             ret = -EFAULT;  
  41.         }  
  42.         else  
  43.         {  
  44.             printk("<--- CMD Get DATA Done  %d--->\n",dev->val);    
  45.         }  
  46.       break;    
  47.           
  48.       /* 设置参数 */    
  49.       case HELLODEV_IOCSETDATA:     
  50.         if (copy_from_user(&(dev->val), argp, sizeof(dev->val)))  
  51.         {  
  52.             printk("do gpio_ioctl:copy_from_user error!\n");  
  53.             ret = -EFAULT;  
  54.         }  
  55.                else  
  56.                 {  
  57.                     printk("<--- CMD Set DATA Done  %d--->\n",dev->val);    
  58.                 }  
  59.       break;    
  60.     
  61.       default:      
  62.         return -EINVAL;    
  63.     }    
  64.     return ret;   
  65.   
  66. }  

修改external/hello来调用ioctl,验证ok,代码如下:

[cpp]  view plain copy
  1. /* 定义幻数 */    
  2. #define HELLODEV_IOC_MAGIC  't'    
  3.     
  4. /* 定义命令 */    
  5. #define HELLODEV_IOCPRINT       _IO(HELLODEV_IOC_MAGIC, 1)  //没参数    
  6. #define HELLODEV_IOCGETDATA            _IOR(HELLODEV_IOC_MAGIC, 2, int)  //读    
  7. #define HELLODEV_IOCSETDATA     _IOW(HELLODEV_IOC_MAGIC, 3, int)  //写    
  8.   
  9. int main(int argc, char** argv)  
  10. {  
  11. ……  
  12.     ioctl(fd,HELLODEV_IOCPRINT);  
  13.     printf("Read original value:\n");  
  14.     //read(fd, &val, sizeof(val));  
  15.     //fread( &val, sizeof(val),1,fd);  
  16.     ioctl(fd,HELLODEV_IOCGETDATA,&val);  
  17.       
  18.     printf("%d.\n\n", val);  
  19.     val = 5;  
  20.     printf("Write value %d to %s  \n\n", val, DEVICE_NAME);  
  21.        // fwrite(&val, sizeof(val),1,fd);  
  22.     ioctl(fd,HELLODEV_IOCSETDATA,&val);  
  23.          
  24.     printf("Read the value again:\n");  
  25.   
  26.     ioctl(fd,HELLODEV_IOCGETDATA,&val);  
  27. ……  
  28. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值