字符设备驱动代码的编写

简介: 传统方法,优点简单缺点就是不易宽展,硬件更换了板子都要重新写代码重新比编译,硬件的每次改动都要重新修改软件版本增加工作量。

字符设备驱动框架


linux/cdev.h


  cdev结构体:  操作方法集    设备号(主设备号+次设备号)    
  围绕cdev结构体进行的一系列操作:
  0.申请/注册设备号    
  1.分配cdev结构体    
  2.初始化结构体    
  3.添加cdev到内核 


编写驱动程序的三种方法

一:传统方法,优点简单缺点就是不易宽展,硬件更换了板子都要重新写代码重新比编译,硬件的每次改动都要重新修改软件版本增加工作量。


二: 总线设备驱动模型,将驱动分为两部分,device和driver两部分挂在platform总线上,device负责指定资源,如管脚等。对于相同的硬件操作driver部分都是相同的,硬件只需要编写相应的device代码来指定硬件资源即可。这种方法稍微复杂,但是易扩展,冗余代码多且以代码的形式出现。


三: 设备树。仍然是分为两部分,一是xxx_driver.c跟总线设备驱动模型一样,二是设备树文件xxx.dts文件来指定文件,内核根据这个文件来构造xxx_device文件,运行时去读取解析xxx.dts文件。优点是比传统方法稍复杂,容易扩展,没有冗余代码,不需要重新编译内核或者驱动只需要提供不一样的设备树文件。


字符设备驱动代码的编写*


#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#define BASEMINOR 0
#define COUNT     3
#define NAME      "cdev_demo"
dev_t devno = 0;
struct cdev *cdevp = NULL;
int demo_open(struct inode *inode, struct file *filp){
  printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__); 
  return 0;
  }
  int demo_release(struct inode *inode, struct file *filp){ 
  printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__); 
  return 0;
  }
  struct file_operations fops = { .owner    = THIS_MODULE,  .open     = demo_open,  .release  = demo_release,};
  int __init demo_init(void){ int ret = 0;  
  //0.申请设备号-内核分配主设备号,次设备好从0开始,共三个(0,1,2)  
  ret = alloc_chrdev_region(&devno,BASEMINOR,COUNT, NAME);  
  if(ret < 0)
  {   
  printk(KERN_ERR "alloc_chrdev_region failed...\n");   
  goto err0;  
  } 
  printk(KERN_INFO "---major:%d---\n",MAJOR(devno));  
  //1.分配cdev结构体 
  cdevp = cdev_alloc(); 
  if(cdevp == NULL)
  {   
  printk(KERN_ERR "cdev_alloc failed...\n");    
  ret = -ENOMEM;    
  goto err1;      
  } 
  //2.初始化cdev结构体  
  cdev_init(cdevp, &fops);
  //3.将cdev结构体添加到内核中,由内核对驱动进行统一的管理  
  ret = cdev_add(cdevp, devno, COUNT);  
  if(ret < 0){    
  printk(KERN_ERR "cdev_add failed...\n");    
  goto err1;  
  } 
  printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__); 
  return 0;err1:  
  unregister_chrdev_region(devno, COUNT);err0:  
  return ret;}void __exit demo_exit(void){  
  cdev_del(cdevp);  
  unregister_chrdev_region(devno, COUNT); 
  printk(KERN_DEBUG "---%s---%s---%d---\n",__FILE__,__func__,__LINE__);
  }
  module_init(demo_init);module_exit(demo_exit);MODULE_LICENSE("GPL");


相关文章
|
机器学习/深度学习 安全
深度学习McCulloch-Pitts模型
深度学习McCulloch-Pitts模型
483 0
|
数据采集 机器学习/深度学习 监控
Arm Coresight 介绍
Coresight 是 ARM 架构上的一款嵌入式系统监控和调试工具,能够为系统管理员和开发人员提供便捷的系统监控和调试功能。该平台可以实时追踪和分析处理器上的活动,以深入了解潜在的性能瓶颈和问题。本文将介绍Coresight的概念、优势及其安装、配置、故障排除和调试等方面的内容,并探讨其未来发展方向和重要性。
2528 1
|
应用服务中间件 nginx
Nginx rewrite(URL)地址重定向
Nginx rewrite(URL)地址重定向
951 0
|
数据可视化 BI
帆软BI开发-Day2-趋势图的多种变形
帆软BI开发-Day2-趋势图的多种变形
517 0
|
存储 NoSQL Apache
Apache Cassandra 简介
Apache Cassandra 是一个开源的、分布式、无中心、弹性可扩展、高可用、容错、一致性可调、面向行的数据库,它基于 Amazon Dynamo 的分布式设计和 Google Bigtable 的数据模型,由 Facebook 创建,在一些最流行的网站中得到应用。
24372 2
|
前端开发 JavaScript API
React团队回应用Vite替换Create React App的建议
React团队回应用Vite替换Create React App的建议
389 0
|
开发工具 Android开发 开发者
Android开发环境搭建
如何搭建Android开发环境,包括下载和安装Android Studio、配置SDK、创建新的Android工程项目等。
447 0
Android开发环境搭建
|
开发者 Python
基于Python的日志管理与最佳实践
日志是开发和调试过程中的重要工具,然而,如何高效地管理和利用日志常常被忽略。本文通过Python中的logging模块,探讨如何使用日志来进行调试、分析与问题排查,并提出了一些实际应用中的优化建议和最佳实践。
|
安全 数据挖掘 API
快手小店详情API接口的获取与应用
在数字化时代,电商平台竞争激烈,API接口作为连接不同系统和服务的桥梁,已成为电商生态中不可或缺的一部分。本文详细介绍快手小店详情API接口的获取与应用,帮助开发者和企业提升业务效率和用户体验。涵盖API接口定义、主要应用场景、注册与认证流程、调用方法及实际应用案例,提供最佳实践建议。
548 1
|
机器学习/深度学习 人工智能 算法
AI Native应用中基于用户反馈的动态模型微调机制
【8月更文第1天】在AI Native应用程序中,用户体验和满意度是衡量产品成功的关键指标之一。为了提高这些指标,本文介绍了一种基于用户反馈的动态模型微调机制。这种方法允许模型在运行时根据用户的实际行为和偏好进行自我调整,从而不断优化其性能。
1787 5