字符设备驱动开发实验

  • 一、驱动框架
  • 二、Makefile
  • 三、测试程序
  • 四、过程总结

该实验与正点原子教程一致,先将该实验视频过一遍,然后根据文档进行实验。

一、驱动框架

(1)注册驱动

//include/linux/fs.h
static int __init xxx_init(void){ /* 注册模块 */int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops);return 0;
}
static void __exit xxx_exit(void){/* 卸载模块*/void unregister_chrdev(unsigned int major, const char *name);
}
module_init(xxx_init); //注册模块加载函数
module_exit(xxx_exit); //注册模块卸载函数

(2)操作函数集合

//include/linux/fs.h
/* 文件打开 */
static int xxx_open(struct inode *, struct file *){}
/* 文件释放 */
static int xxx_release(struct inode *, struct file *){}
/* 文件读 */
static ssize_t xxx_read(struct file *, char __user *, size_t, loff_t *){}
/* 文件写 */
static ssize_t xxx_write(struct file *, const char __user *, size_t, loff_t *){}
/* 文件操作函数集合 */
static struct file_operations  xxx_fops = {.owner   = THGIS_MODULE,.open    = xxx_open,.release = xxx_release,.read    = xxx_read,.write   = xxx_write,}

(3)数据操作

#include <asm/uaccess.h>long copy_to_user(void __user *to, const void *from, long n)long copy_from_user(void *to, const void __user *from, long n)

(4)开源协议

MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");

二、Makefile

三、测试程序

1 NAME 简短的指令、数据名称说明;

2 SYNOPSIS 简短的指令下达语法(Syntax)简介

3 Description 较为完整的说明,这部分最好仔细看看;

4 Options 针对SYNOPSIS 部分中,有列举的所有可用的选项和说明;

5 COMMANDS 当这个程序软件在执行的时候,可以在此程序中下达的指令;

6 FILES 这个程序或数据所使用或参考或连结到的某些档案;

7 SEE ALSO 可以参考的,跟这个指令或数据有相关的其他说明;

8 EXAMPLE 一些可以参考的范例;

9 BUGS 是否有相关的臭虫!

open:man 2 open

OPEN(2)                                Linux Programmer's Manual                               OPEN(2)NAMEopen, creat - open and possibly create a file or deviceSYNOPSIS#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);int creat(const char *pathname, mode_t mode);DESCRIPTIONGiven a pathname for a file, open() returns a file descriptor, a small, nonnegative integer foruse in subsequent system  calls  (read(2),  write(2),  lseek(2),  fcntl(2),  etc.).   The  filedescriptor  returned  by a successful call will be the lowest-numbered file descriptor not cur‐rently open for the process.By default, the new file descriptor is set to  remain  open  across  an  execve(2)  (i.e.,  theFD_CLOEXEC  file  descriptor  flag  described  in fcntl(2) is initially disabled; the O_CLOEXEC

write:man 2 write

WRITE(2)                               Linux Programmer's Manual                              WRITE(2)NAMEwrite - write to a file descriptorSYNOPSIS#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);DESCRIPTIONwrite()  writes  up  to  count bytes from the buffer pointed buf to the file referred to by thefile descriptor fd.The number of bytes written may be less than count if, for example, there is insufficient spaceon the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setr‐limit(2)), or the call was interrupted by a signal handler after having written less than countbytes.  (See also pipe(7).)For  a  seekable file (i.e., one to which lseek(2) may be applied, for example, a regular file)writing takes place at the current file offset, and the file offset is incremented by the  num‐ber  of  bytes  actually  written.  If the file was open(2)ed with O_APPEND, the file offset isfirst set to the end of the file before writing.  The adjustment of the  file  offset  and  theManual page write(2) line 1 (press h for help or q to quit)

read:man 2 read

READ(2)                                Linux Programmer's Manual                               READ(2)NAMEread - read from a file descriptorSYNOPSIS#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);DESCRIPTIONread()  attempts  to read up to count bytes from file descriptor fd into the buffer starting atbuf.If count is zero, read() returns zero and has no other  results.   If  count  is  greater  thanSSIZE_MAX, the result is unspecified.RETURN VALUEOn  success,  the  number  of bytes read is returned (zero indicates end of file), and the fileposition is advanced by this number.  It is not an error if this number  is  smaller  than  thenumber  of bytes requested; this may happen for example because fewer bytes are actually avail‐able right now (maybe because we were close to end-of-file, or because we are  reading  from  apipe,  or  from  a  terminal),  or because read() was interrupted by a signal.  On error, -1 isManual page read(2) line 1 (press h for help or q to quit)
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"static char usrdata[] = {"usr data!"};int main(int argc, char *argv[])
{int fd,retvalue;char *filename;char readbuf[100],writebuf[100];if(argc != 3){printf("Error Usage!\r\n");return -1;} filename = argv[1];fd = open(filename,O_RDWR);if(fd < 0){printf("Can't open file %s\r\n",filename);return -1;}if(atoi(argv[2]) == 1){retvalue = read(fd,readbuf,50);if(retvalue < 0){printf("read file %s failed! \r\n",filename);}else{printf("read data:%s\r\n",readbuf);}}if(atoi(argv[2]) == 2){memcpy(writebuf,usrdata,sizeof(usrdata));retvalue = write(fd,writebuf,50);if(retvalue < 0){printf("write file %s failed!\r\n",filename);}}retvalue = close(fd);if(retvalue < 0){printf("Can't close file %s\r\n",filename);return -1;}return 0;
}

四、过程总结

(1)代码按照正点原子例程来敲的,编译的Makefile文件按照酷客开发板例程里敲的,后面再抽空研究Makefile吧,内容有点多,就暂时不深究了。

(2)编译应用程序的时候,电脑里没有arm-linux-gnueabihf-gcc这个命令,直接使用arm-linux-gcc进行编译,编译成功后,一样可以运行。

(3)modprobe这个指令有,但是depmod指令没有,busybox可能需要后期需要重新编译一下,把这个指令加进去,暂时使用insmod和rmmod指令。

(4)卸载的时候,发现卸载不了,最后发现是执行rmmod chrdevbase.ko卸载不了,执行rmmod chrdevbase指令可以卸载,卸载的时候,不加.ko。

(5)代码用vi写的,有点艰难。Linux下的VS Code还没搭建。
附上实验成功的截图:

                                                         记录自己的学习过程,2022.04.07

【吃灰板子捡起来】字符设备驱动开发实验相关推荐

  1. 【吃灰板子捡起来】LED驱动开发实验

    LED驱动开发实验 一.地址映射 二.内存访问 三.应用源码 四.驱动源码 五.实验总结 一.地址映射 #include <asm/io.h>#define ioremap(cookie, ...

  2. 【吃灰板子捡起来】新字符设备驱动开发实验

    新字符设备驱动开发实验 一.设备号 二.字符设备 三.设备节点 四.驱动源码 五.总结 一.设备号 定义:/fs/char_dev.c #include <linux/fs.h>/*** ...

  3. 【正点原子MP157连载】第二十章 字符设备驱动开发-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  4. 基于Cortex-A7架构的嵌入式linux ARM驱动开发<1>——字符设备驱动开发

    一.什么是字符设备 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的.比如我们最常见的点灯.按键.IIC.SPI, L ...

  5. 02_字符设备驱动开发

    目录 1 字符设备驱动简介 2 字符设备驱动开发步骤 2.1 驱动模块的加载和卸载 2.2 字符设备注册与注销 2.3 实现设备的具体操作函数 2.4 添加 LICENSE 和作者信息 3 Linux ...

  6. 虚拟字符设备驱动开发步骤

    目录 前言 字符设备驱动简介 内核驱动操作函数集合(file_operations结构体) 字符设备驱动开发步骤 .ko驱动模块的加载和卸载(module_init驱动入口.insmod驱动加载) 字 ...

  7. 【驱动】linux设备驱动·字符设备驱动开发

    Preface 前面对linux设备驱动的相应知识点进行了总结,现在进入实践阶段! <linux设备驱动入门篇>:http://infohacker.blog.51cto.com/6751 ...

  8. linux内核led驱动开发,从Linux内核LED驱动来理解字符设备驱动开发流程

    目录 博客说明 开发环境 1. Linux字符设备驱动的组成 1.1 字符设备驱动模块加载与卸载函数 1.2 字符设备驱动的file_operations 结构体中的成员函数 2. 字符设备驱动--设 ...

  9. 字符设备驱动开发的流程

    目录 1.字符设备驱动简介 2.字符设备驱动开发步骤 2.1驱动模块的加载和卸载 2.2字符设备注册与注销 2.3实现设备的具体操作函数 3.linux设备号 3.1设备号的组成 3.2设备号的分配 ...

最新文章

  1. Silverlight WCF RIA服务(二十三)Silverlight 客户端 4
  2. 面对不同用户,数据中心如何将服务做到极致
  3. Oracle的一些经典SQL面试题
  4. 机器学习-损失函数 (转)
  5. dll注入之SetWindowsHookEx(1)
  6. linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序
  7. 【CodeForces - 474D】Flowers (线性dp)
  8. Redis数据类型--列表类型
  9. python3-numpy数组广播 和 np.tile 扩展数组
  10. 字符串经典题之正则匹配字符串
  11. MongoDB开发环境搭建(windows)
  12. 向小伙伴讲讲搜索引擎?读完这个文章先
  13. 五、Google Code Prettify:实现代码高亮的JS库
  14. php生成黑链,网站被黑链接(进入黑网最有效办法)
  15. 【Steam】各种Steam致命错误-Steam需要在线进行更新什么意思。请确保你的网络连接正常,请重试。
  16. 计网 - TCP 的稳定性:滑动窗口和流速控制是怎么回事?
  17. 如何加速android模拟器,Android模拟器运行慢怎么办 Android模拟器如何加速【加速方法】...
  18. 电脑“减负”必备,分享一款优秀的重复文件查找工具
  19. php like 中文,punycode和中文转换 phpThe Twitter-clone/twitter-like sites collection
  20. UUID简介以及java代码获取UUID示例

热门文章

  1. 工程用到QOS 的CIR_CBS_EBS介绍
  2. “第九街市”的网上卖菜经
  3. MySQL ERROR 1153 解决办法
  4. pptx库ppt演示 python_python pptx
  5. 利用 telnet 调试 skynet
  6. 第七节 圣维南原理及其应用
  7. 风口之上,AI教育的一场“文火慢炖”
  8. 【电子技术基础(精华版)】直流稳压电路
  9. Docker生态会重蹈Hadoop的覆辙吗?
  10. 分屏视频怎么剪?手把手教你剪辑