在ubuntu下编写验证字符设备驱动

并移植到arm开发板上

1,准备工作

  1.   uname -r  查看电脑版本信息
  2. apt-get  install  linux-source  安装相应版本的linux内核

2,编写驱动程序

    Global CharDev.c

/* GlobalCharDev.c */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h> #include <asm/uaccess.h> #define DEV_NAME "GlobalChar" static ssize_t GlobalRead(struct file *, char *, size_t, loff_t *);
static ssize_t GlobalWrite(struct file *, const char *, size_t,loff_t *); static int char_major = ;
static int GlobalData = ; /* "GlobalChar"设备的全局变量 */ /* 初始化字符设备驱动的 file_operations 结构体 */
struct file_operations globalchar_fops =
{
.read = GlobalRead,
.write = GlobalWrite
}; /* 模块初始化 */
static int __init GlobalChar_init(void)
{
int ret; ret = register_chrdev(char_major, DEV_NAME, &globalchar_fops);/* 注册设备驱动,_driver_char_misc.c 第290行参考 */
if(ret < )
printk(KERN_ALERT "GlobalChar Reg Fail\n");
else
{
printk(KERN_ALERT "GlobalChar Reg Success\n");
char_major = ret;
printk(KERN_ALERT "Major = %d\n", char_major);
}
return ret;
} /* 模块卸载函数 */
static void __exit GlobalChar_exit(void)
{
unregister_chrdev(char_major, DEV_NAME); /* 注销设备驱动 */
return;
} /* 模块驱动读函数 */
static ssize_t GlobalRead(struct file *file, char *buf, size_t len, loff_t *off)
{
if (copy_to_user(buf, &GlobalData ,sizeof(int)))
{
/* 从内核复制 GlobalData 到用户空间*/
return -EFAULT;
}
return sizeof(int);
}
/* 模块驱动写函数 */
static ssize_t GlobalWrite(struct file *file, const char *buf, size_t len, loff_t *off)
{
if (copy_from_user(&GlobalData, buf, sizeof(int)))
{
/* 从用户复制 GlobalData 到内核 */
return -EFAULT;
}
return sizeof(int);
} module_init(GlobalChar_init);
module_exit(GlobalChar_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("dongjin");

  Makefile

ifneq ($(KERNELRELEASE),)
obj-m := GlobalCharDev.o
else # KERNELDIR ?= /lib/modules/$(shell uname -r)/build
KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r) //这两个都可以 PWD := $(shell pwd) default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:
rm -rf rm -rf *.ko *.mod* *.o* *.sy*
endif

  理解:

      pwd-->  驱动文件目录

      kerneldir -->  内核源码目录

      default -->  表示到内核源码目录中去编译pwd下的驱动文件

——————————————————————————————————————————————————————

make 编译

root@ubuntu:/home/arm/data/char_driver# make
make -C /usr/src/linux-headers-4.4.--generic M=/home/arm/data/char_driver modules
make[]: 正在进入目录 `/usr/src/linux-headers-4.4.--generic'
CC [M] /home/arm/data/char_driver/GlobalCharDev.o
Building modules, stage .
MODPOST modules
LD [M] /home/arm/data/char_driver/GlobalCharDev.ko
make[]:正在离开目录 `/usr/src/linux-headers-4.4.--generic'

出现Global CharDev.ko文件

2,insmod Global CharDev.ko  将模块加入内核

3,cat  /proc/devices  查看驱动设备

4,mknod  /dev/GlobalChar   c  247  0      根据相应的设备号,建立设备节点。

5,测试文件

/* GlobaiCharText.c 测试文件*/

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h> #define DEV_NAME "/dev/GlobalChar" int main()
{
int fd, num; /* 打开设备文件 */
fd = open(DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR);
if(fd < )
{
printf("Open Device Fail!\n");
return -;
} /* 读取当前设备数值 */
read(fd, &num, sizeof(int));
printf("The GlobalChar is %d\n", num); printf("Please input a numble written to GlobalChar: ");
scanf("%d", &num); /* 写入新的数值 */
write(fd, &num, sizeof(int)); /* 重新读取数值 */
read(fd, &num, sizeof(int));
printf("The GlobalChar is %d\n", num); close(fd);
return ; }

  gcc -o  GlobalCharText  GlobalCharText.c      编译出可执行文件

   执行:

root@ubuntu:/home/arm/data/char_driver# ./a.out
The GlobalChar is
Please input a numble written to GlobalChar:
The GlobalChar is

——————————————————————————————————————————————————————————————————————

通过NFS我们可以建立共享目录,将编写好的驱动加载到arm板,当然也需要配置环境变量。

1,驱动文件:需要将Make file中KERNLDIR 改成 自己下载内核的地址,如:

    KERNELDIR ?= /home/arm/linux-4.4

2,测试文件:理所当然我们需要使用交叉编译去编译出可执行文件。

注意:首先我们要知道自己制作的做小系统是采用静态编译还是动态编译,我的采用静态编译

  1,静态:

  2,动态:

需要在制作最小系统时,在  /lib  下加入所需的动态交叉编译库(所选交叉编译工具目录下的链接库),但是我在制作randisk的过程中,提示内存不足,暂没查找其原因。

如果在静态根文件系统内使用动态编译链所编译的elf,会提示:-sh:./test:no found  (这里 not found 指的是 链接库)

测试:

卸载:

1,删除  /dev  下的设备节点

  rm /dev/GlobalChar

2,卸载驱动

  rmmod  GlopbalCharDev.ko 

出现问题:

——————————————————————————————————————————————————————

参考:

http://tieba.baidu.com/p/3645403366

https://blog.csdn.net/Ultraman_hs/article/details/53239455

解决移植到arm上不兼容的问题

https://blog.csdn.net/zqj6893/article/details/48439711

解决驱动卸载问题

tiny4412--linux驱动学习(2)的更多相关文章

  1. linux 驱动学习笔记01--Linux 内核的编译

    由于用的学习材料是<linux设备驱动开发详解(第二版)>,所以linux驱动学习笔记大部分文字描述来自于这本书,学习笔记系列用于自己学习理解的一种查阅和复习方式. #make confi ...

  2. linux驱动学习(二) Makefile高级【转】

    转自:http://blog.csdn.net/ghostyu/article/details/6866863 版权声明:本文为博主原创文章,未经博主允许不得转载. 在我前一篇写的[ linux驱动学 ...

  3. Linux驱动学习步骤(转载)

    1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...

  4. 树莓派linux驱动学习之hello world

    最近想学习一下linux驱动,看了一些书和教学视频,大概了解了一下,不过要想深入,肯定需要实践.手上有几块linux的板子,最终选择了树莓派作为我的实验平台,资料比较丰富,接口也比较简单. 程序员的入 ...

  5. Linux驱动学习1.hello world;

    最近项目需要使用Linux系统开发,借此机会学习一下Linux驱动开发 hello word代码hello.c #include <linux/module.h> #include < ...

  6. 【Linux驱动学习】SD卡规范学习

    摘要: 学习SD卡的相关规范,包括定义,硬件特性,数据传输,命令系统等.不涉及代码. 文章针对Linux驱动开发而写,以助于理解SD卡驱动,不会涉及过多硬件内容. 纲要: 1. SD卡介绍 2. SD ...

  7. linux驱动学习_1

    目前项目需要,需要做linux驱动了,记录一下 学习驱动,大家一定都会写一个hello world代码,网上也有很多范例,但是记录一下遇到的问题. 1.make之后,使用insmod加载,终端没有打印 ...

  8. Linux驱动学习之常用的模块操作命令

    1.常用的模块操作命令 (1)lsmod(list module,将模块列表显示),功能是打印出当前内核中已经安装的模块列表 (2)insmod(install module,安装模块),功能是向当前 ...

  9. Linux驱动学习之驱动开发准备工作

    一.开启驱动开发之路 1.驱动开发的准备工作 (1)正常运行linux系统的开发板.要求开发板中的linux的zImage必须是自己编译的,不能是别人编译的.原因在于在安装模块的时候会进行安全性校验 ...

  10. Linux驱动学习之什么是驱动?

    一.什么是驱动? 1: 驱动一词的字面意思 2: 物理上的驱动 3: 硬件中的驱动 4: linux内核驱动.软件层面上的驱动广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序. ...

随机推荐

  1. VC工程产生文件后缀名解释

    [原文出自http://hi.baidu.com/zj0932zj/blog/item/b55f33cc7753c01700e92870.html ] .APS:存放二进制资源的中间文件,VC把当前资 ...

  2. centos7 lnmp环境部署

    搭建版本 版本组合 php5.6+apache/2.4.6(centos7)+mysql5.7.24 因为新系统不能确认哪些指令已经搭建  所以安装前需要确认下是否拥有 检测是否已经安装过Vim rp ...

  3. java-网络通信-索引

           HTTP协议 关于HTTP协议,一篇就够了 HTTP与HTTPS的区别 HTTP Keep-Alive模式 HTTP长连接和短连接 HTTP的长连接(持久连接)和短连接 HTTP的长连接 ...

  4. SAP S/4 HANA 1709 Fully Activated Appliance

    SAP S4HANA 1709 Fully Activated Appliance:简单来说比IDES版本功能更加强大,内置三个集团,分别用于测试不同业务.内置官方的BP内容 安装需要500G SSD ...

  5. 代码:PC CSS(工作中用)

    常规内容区域的:标题和文字 2016-5-23 .p16{font-size:16px;color:#333;}/* 16号#333的标题 */ .p12-gray{font-size:16px;co ...

  6. video.js使用

    //引入video.js html <video id="my-player" className="video-js my-player-wrap vjs-big ...

  7. c#控件 menuStrip(转)

    一.概述 菜单通过存放按照一般主题分组的命令将功能公开给用户. MenuStrip 控件是此版本的 Visual Studio 和 .NET Framework 中的新功能.使用该控件,可以轻松创建  ...

  8. (ZT)算法杂货铺——k均值聚类(K-means)

    https://www.cnblogs.com/leoo2sk/category/273456.html 4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先 ...

  9. <Dare To Dream>第五次作业:团队项目需求改进与系统设计

    任务1完成情况: a.分析<家教服务管理系统需求规格说明书>初稿的不足: uml建模不完整,无类图.流程图,仅有的用例图也不规范. b.功能分析的四个象限: c. 团队项目的WBS: d. ...

  10. VS code自定义用户代码片段snippet

    打开VS code,“文件-首选项-用户代码片段-选择新建全局代码片段文件 “ 属性介绍:prefix   就是你自定义的快捷键 body    就是你自定义的代码片段 description 就是这 ...