HDF驱动框架探路(一):工欲善其事,必先利其器(linux驱动开发)

系统 Linux
正如标题所示工欲善其事,必先利其器。这个器就是首先得知道linux驱动开发。那么本文就是讲解linux驱动开发的。

[[436207]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

老规矩还是将最终希望跑出来的效果如下:

HDF驱动框架探路(一):工欲善其事,必先利其器(linux驱动开发)-鸿蒙HarmonyOS技术社区

前言

从本文开始会为记录一个驱动小白的成长道路。当你已经具备了成熟的驱动开发经验的话,那么你可以直接跳过,本文对你毫无用处。作为一个没有接触过任何驱动开发的小白来说,想要搞清楚openharmony的HDF驱动框架的话,我大概梳理了一下,不对之处各位大佬留言指出。想要彻底搞清楚HDF框架我认为第一步必须需要搞清楚linux驱动,因为linux内核是被广泛使用的,无论android,ios,还是openharmony。因为linux内核最基础的用户态和内核态的概念最存在于各种驱动开发中的。

所以有了上述的认识,正如标题所示工欲善其事,必先利其器。这个器就是首先得知道linux驱动开发。那么本文就是讲解linux驱动开发的。

虽然本文是来介绍linux驱动开发的,不过我们还是先来了解一下HDF的概念,只需要知道这个概念,应为我们现在的工作都是为这个概念服务的。那么:什么是HDF驱动框架?HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理和驱动消息机制。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。

什么是驱动开发?

这个看似不是问题的问题却很重要,我们必须需要从这一步开始理清楚,见下图:

HDF驱动框架探路(一):工欲善其事,必先利其器(linux驱动开发)-鸿蒙HarmonyOS技术社区

从上图中可以看出单片机裸机程序是可以直接控制硬件的,而在linux应用程序中这一招就行不通了。linux必须通过驱动程序来控制操作硬件,OK,暂且先知道这么多,更详细的问题比如linux为什么要这样子做,我们先留着这些疑问,饭要一口一口吃。

总体架构图

 HDF驱动框架探路(一):工欲善其事,必先利其器(linux驱动开发)-鸿蒙HarmonyOS技术社区

1.应用程序

写应用程序的目的主要是为了测试驱动程序,测试的方法为调用glibc的open、read、write函数。

代码见下:

  1. #include <sys/types.h> 
  2. #include <sys/stat.h> 
  3. #include <fcntl.h> 
  4. #include <unistd.h> 
  5. #include <stdio.h> 
  6. #include <string.h> 
  7.  
  8. int main(int argc, char **argv) 
  9.     int fd; 
  10.     char buf[1024]; 
  11.     int len; 
  12.     int ret; 
  13.  
  14.     if (argc < 2) { 
  15.         printf("Usage: %s -w <string>\n", argv[0]); 
  16.         printf("       %s -r\n",argv[0]); 
  17.         return -1; 
  18.     } 
  19.  
  20.     fd = open("/dev/hello_linux_dri", O_RDWR); 
  21.     if (fd == -1) 
  22.     { 
  23.         printf("can not open file /dev/hello_linux_dri\n"); 
  24.         return -1; 
  25.     } 
  26.     printf("open /dev/hello_linux_dri success\n"); 
  27.     if ((0 == strcmp(argv[1], "-w")) && (argc  == 3)) 
  28.     { 
  29.         len = strlen(argv[2]) + 1; 
  30.         len = len < 1024 ? len : 1024; 
  31.         ret = write(fd, argv[2], len); 
  32.         printf("write driver : %d\n", ret); 
  33.     } else { 
  34.         len = read(fd, buf, 1024); 
  35.         printf("read driver : %d\n", len); 
  36.         buf[1023] = '\0'
  37.         printf("APP read : %s\n", buf); 
  38.     } 
  39.  
  40.     close(fd); 
  41.  
  42.     return 0; 

2.驱动程序总体逻辑

驱动程序属于模块写法:预先注册自己的的函数任务,以便服务于将来的某个请求,然后它的初始化函数就立即结束

2.1 环境确认

因为驱动程序是调用的内核头文件,所以首先需要确认头文件有没有,下面第一条命令是确认有没有,没有的话,使用第二条进行下载。

  1. apt-cache search linux-headers-$(uname -r) 
  2. sudo apt-get install linux-headers-$(uname -r) 

2.2 驱动框架代码搭建

代码见下图:

  1. #include <linux/module.h> 
  2. #include <linux/fs.h> 
  3. #include <linux/device.h> 
  4.  
  5. static int major = 0; 
  6. static int ker_val = 123; 
  7. static struct class *hello_for_class; 
  8. static ssize_t hello_read(struct file *file, char __user *buf, size_t size, loff_t *offset) 
  9.     printk("%s %s line %d\n",__FILE__,__FUNCTION__, __LINE__); 
  10.     return 4; 
  11.  
  12. static ssize_t hello_write(struct file *file, const char __user *buf, size_t size, loff_t *offset) 
  13.     printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__); 
  14.     return 4; 
  15. int __init hello_init(void) 
  16.     printk("hello_linux_dri init\n"); 
  17.     return 0; 
  18. void __exit hello_exit(void) 
  19.     printk("hello_linux_dri exit\n"); 
  20.     return
  21. module_init(hello_init); 
  22. module_exit(hello_exit); 
  23. MODULE_LICENSE("GPL"); 

上述就是驱动代码的一个基本框架

3.注册驱动

使用file_operations结构体来填充register_chrdev函数来注册驱动

  1. static struct file_operations hello_linux_fops = { 
  2.     .owner = THIS_MODULE, 
  3.     .read = hello_read, 
  4.     .write = hello_write, 
  5. }; 
  6. int __init hello_init(void) 
  7.     printk("hello_linux_dri init\n"); 
  8.     major = register_chrdev(0,"hello_linux_dri", &hello_linux_fops); 
  9.     return 0; 

4.注销驱动

使用unregister_chrdev函数来注销注册中的驱动信息

  1. void __exit hello_exit(void) 
  2.     printk("hello_linux_dri exit\n"); 
  3.     unregister_chrdev(major, "hello_linux_dri"); 
  4.     return

5.自动生成设备文件来使用驱动

5.1 生成设备文件

使用class_create和device_create来进行生成,代码如下:

  1. int __init hello_init(void) 
  2.     printk("hello_linux_dri init\n"); 
  3.     major = register_chrdev(0,"hello_linux_dri", &hello_linux_fops); 
  4.     hello_for_class = class_create(THIS_MODULE, "hello_class"); 
  5.     device_create(hello_for_class, NULL, MKDEV(major, 0), NULL"hello_linux_dri"); 
  6.  
  7.     return 0; 

5.2 撤销设备文件

使用device_destroy和class_destroy进行撤销,代码如下:

  1. void __exit hello_exit(void) 
  2.     printk("hello_linux_dri exit\n"); 
  3.  
  4.     device_destroy(hello_for_class, MKDEV(major, 0)); 
  5.     class_destroy(hello_for_class); 
  6.     unregister_chrdev(major, "hello_linux_dri"); 
  7.  
  8.     return

效果如下:

HDF驱动框架探路(一):工欲善其事,必先利其器(linux驱动开发)-鸿蒙HarmonyOS技术社区

文章相关附件可以点击下面的原文链接前往下载

https://harmonyos.51cto.com/resource/1513

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2010-02-24 10:39:48

2021-06-16 09:22:10

鸿蒙HarmonyOS应用

2012-11-09 17:15:29

遨游浏览器

2018-07-02 15:46:18

Python编辑器经验

2017-02-07 15:15:20

大数据数据分析数据挖掘

2018-12-11 14:25:19

JFrogKubernetesDevOps

2016-12-16 14:18:54

2014-04-30 13:50:00

VS2013VS2013技巧

2020-10-10 14:48:18

Python安装

2023-02-07 16:11:41

2010-10-27 09:33:18

MVC开发

2021-12-15 15:30:38

鸿蒙HarmonyOS应用

2021-05-06 15:15:13

Python工具代码

2021-03-03 14:50:55

安全自动化机器学习网络安全

2021-03-29 11:20:39

前端代码工作流

2021-02-11 09:12:14

开发IDEA后缀

2011-08-05 10:48:11

iPhone开发 Objective- Cocoa Touc

2021-11-30 14:52:41

鸿蒙HarmonyOS应用

2020-07-08 14:10:30

开发技能工具

2010-01-19 13:43:47

点赞
收藏

51CTO技术栈公众号