4065|6

3416

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

【SINA31s评测】NO.5 第一个驱动 [复制链接]

好久没更新,SINA31s开始吃灰了
晚上写了个简单的字符设备驱动
发现不少的坑

芯灵思的环境搭得有点坑
譬如
如果需要编译应用程序,还得先执行一次lunch
配置好后,才能执行envsetup.sh进行配置
最后才能mmm编译应用
还有就是,琢磨了半天makefile
头都绕晕了
还是不知道怎么对单个驱动编译ko
只能把驱动加入Kconfig,编译整个内核,生成ko
可能是看代码的水平太次
最大的一个坑
Make menuconfig后,内核的配置丢失了丢失了失了
居然还没有备份的deconfig文件
只能解压源码,换个姿势再来一次……
楼主也彻底湿了

磕磕绊绊,最终还是调试好了简单的驱动
  1. #include "test.h"

  2. static int test_major = 0;
  3. static int test_minor = 0;

  4. int   user_data;

  5. static struct class *test_class = NULL;
  6. static struct device *test_dev = NULL;
  7. static struct class_device *test_classdev[4];

  8. static int test_drv_open(struct inode *inode, struct file *file)
  9. {
  10.         test_minor = MINOR(inode -> i_rdev);//取出次设备号
  11.         printk(KERN_EMERG"test_drv_open,major=%d,minor=%d.....\n",test_major,test_minor);//大坑,用最高的打印优先级
  12.         return 0;
  13. }

  14. static int test_drv_write(struct file *file,const char __user *buf,size_t count,loff_t* ppos)
  15. {
  16.         int fd;
  17.         printk(KERN_EMERG"test_drv_write.....\n");
  18.         fd = copy_from_user(&user_data,buf,count); // copy_to _user();
  19.         if(fd)
  20.                 {printk(KERN_EMERG"Got Nothings....\n");}
  21.         else {printk(KERN_EMERG"Got val = %d..\n",user_data);}
  22.         switch (test_minor)
  23.         {
  24.                 case 0 : printk(KERN_EMERG"test_drv[%d] got the val = %d.\n",test_minor,user_data);
  25.                         break;
  26.                 case 1 : printk(KERN_EMERG"test_drv[%d] got the val = %d.\n",test_minor,user_data);
  27.                         break;
  28.                 case 2 : printk(KERN_EMERG"test_drv[%d] got the val = %d.\n",test_minor,user_data);
  29.                         break;
  30.                 case 3 : printk(KERN_EMERG"test_drv[%d] got the val = %d.\n",test_minor,user_data);
  31.                         break;
  32.                 default:
  33.                         break;
  34.         }
  35.         return 0;
  36. }

  37. static int test_drv_release(struct inode* inode, struct file* filp)
  38. {
  39.         printk("test_drv_release.....\r\n");
  40.         return 0;
  41. }

  42. static struct file_operations test_drv_fops = {
  43.         .owner = THIS_MODULE,
  44.         .open = test_drv_open,
  45.         .write = test_drv_write,
  46.         .release = test_drv_release,
  47. };

  48. static int test_drv_init(void)
  49. {
  50.         int err;
  51.         test_major = register_chrdev(0, "test_drv", &test_drv_fops);//动态分配系统主设备号
  52.         if(test_major ==  -EBUSY)
  53.         {
  54.                 printk(KERN_EMERG"Device registed failed...\n");
  55.                 }
  56.         else{
  57.                 printk(KERN_EMERG"Device registed sucess,major = %d\n",test_major );
  58.                 }
  59.         test_class = class_create(THIS_MODULE,"test_drv_class");//创建设备类
  60.         if(!IS_ERR(test_class)) {
  61.                 err = PTR_ERR(test_class);
  62.                 printk(KERN_ALERT"Sucess to create test class,ERR=%d.\n",err);
  63.         }   
  64. /*
  65.         test_dev = device_create(test_class,NULL,MKDEV(test_major,0),NULL,"test_drv");//创建设备  (单个设备)
  66.         if(!IS_ERR(test_dev)) {
  67.                 err = PTR_ERR(test_dev);
  68.                 printk(KERN_ALERT"Sucess to create test device,ERR=%d.\n",err);
  69.                 }
  70. */
  71.         for(test_minor = 0; test_minor < 4; test_minor++){
  72.         test_classdev[test_minor] = device_create(test_class,NULL,MKDEV(test_major,test_minor),NULL,"test_drv[%d]",test_minor);//创建设备 (多个设备)      
  73.         if(!IS_ERR(test_classdev[test_minor])) {
  74.                 err = PTR_ERR(test_classdev[test_minor]);
  75.                 printk(KERN_ALERT"Sucess to create test device[%d],ERR=%d.\n",test_minor,err);
  76.                 }  
  77.         }
  78.         return 0;
  79. }

  80. static void test_drv_exit(void)
  81. {       
  82.         unregister_chrdev(test_major, "test_drv");//注销系统设备号

  83.         //device_destroy(test_class, MKDEV(test_major,0));//注销设备 单个
  84.        
  85.         for(test_minor = 0; test_minor < 4; test_minor++){
  86.         device_destroy(test_class, MKDEV(test_major,test_minor));//注销设备 多个
  87.                 }
  88.        
  89.         class_destroy(test_class);//注销设备类

  90.         printk(KERN_EMERG"test_drv_exit.....\n");
  91.         printk("...................\n");//普通优先级,毛都不出
  92. }

  93. module_init(test_drv_init);
  94. module_exit(test_drv_exit);

  95. MODULE_LICENSE("Dual BSD/GPL");
  96. MODULE_AUTHOR("ljj3166");
复制代码
Push进单板
Insmod安装一下驱动

打印提示,
1个设备类,四个设备,创建成功

ls dev/tes* -l


主设备号、次设备号俱全


cat /proc/devices

设备创建成功


ls /sys/class/test_drv_class/

test_drv_class下的4个设备

试试卸载驱动

卸载也正常



写个应用程序testapp来测试一下驱动吧
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>

  5. void print_usage(char *file)//用法
  6. {
  7.     printf("Usage:\n");
  8.     printf("%s <dev> <hi|bye>\n",file);
  9.     printf("eg. \n");
  10.     printf("%s /dev/test_drv[0] hi\n", file);
  11.     printf("%s /dev/test_drv[0] bye\n", file);
  12.     printf("%s /dev/test_drv[1] hi\n", file);
  13.     printf("%s /dev/test_drv[1] bye\n", file);
  14. }


  15. int main(int argc,char** argv)
  16. {
  17.         int fd;
  18.         int val = 1;
  19.         char* filename;
  20.         printf("hello,world!\n");//测试应用

  21.         if (argc != 3) //判断入口参数个数,错误则打印使用方法
  22.     {
  23.         print_usage(argv[0]);
  24.         return 0;
  25.     }

  26.         filename = argv[1];

  27.         fd = open(filename,O_RDWR); //打开对应设备

  28.         if(fd == -1)
  29.         {
  30.                 printf("can't open %s , fd = %d......!\n",filename,fd);//打开失败,打印错误名称
  31.                 perror("ERROR:");
  32.         }

  33.         else {
  34.                 printf(" open %s OK!\n",filename);
  35.                 }

  36.         if(strcmp(argv[2] ,"hi") == 0) //第三个入口参数判断
  37.         {
  38.                 val = 1;
  39.         }
  40.         else if(strcmp(argv[2],"bye") == 0){val = 0;}
  41.         else {print_usage(argv[0]);}

  42.         write(fd, &val, 4);//向驱动程序写入值

  43.         return 0;
  44. }


复制代码
Push进单板运行一下
不过首先得设置testapp的权限
可能是编译的时候没配置好


执行正常

在调试测试程序的时候
有个天坑
内核打印函数,必须使用优先级较高的参数
直接printk是没有任何信息出现的
可能芯灵思为了串口不那么吵闹,调整了printk的打印级别
刚开始调试的时候
怎么也打印不出语句
一直还以为驱动写得有问题
折腾了2个小时
才发现这个坑
官方文档上居然没见有说明
再一次湿了……
驱动框架先搭到这吧
后面有时间,把硬件的操作也加进来





最新回复

这是一个坑系列之xxxx  详情 回复 发表于 2016-10-21 17:28
点赞 关注
个人签名

So TM what......?


回复
举报

1403

帖子

1

TA的资源

纯净的硅(中级)

沙发
 
厉害厉害,驱动也晚上了,话说这是哪个版本的内核,求共享学习资料

点评

3.10老内核了 资料全靠度娘......  详情 回复 发表于 2016-10-21 20:17
 
个人签名HELLO_WATER
 

回复

7219

帖子

192

TA的资源

五彩晶圆(高级)

板凳
 
这个板子  你连显示器了么 是不是没有显示器 没法开机?

点评

可以开机啊,还行  详情 回复 发表于 2016-10-21 20:18
 
 
 

回复

6040

帖子

196

TA的资源

版主

4
 
这是一个坑系列之xxxx

点评

斑竹快把这个帖子加入活动  详情 回复 发表于 2016-10-21 20:18
 
 
 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

5
 
shinykongcn 发表于 2016-10-20 10:31
厉害厉害,驱动也晚上了,话说这是哪个版本的内核,求共享学习资料

3.10老内核了
资料全靠度娘......
 
个人签名

So TM what......?

 

 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

6
 
常见泽1 发表于 2016-10-21 17:03
这个板子  你连显示器了么 是不是没有显示器 没法开机?

可以开机啊,还行
 
个人签名

So TM what......?

 

 

回复

3416

帖子

0

TA的资源

纯净的硅(高级)

7
 
lcofjp 发表于 2016-10-21 17:28
这是一个坑系列之xxxx

斑竹快把这个帖子加入活动
 
个人签名

So TM what......?

 

 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表