在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 = 0;
static int GlobalData = 0; /* "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 < 0 )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)/buildKERNELDIR ?= /usr/src/linux-headers-$(shell uname -r)       //这两个都可以PWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean: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.0-31-generic M=/home/arm/data/char_driver modules
make[1]: 正在进入目录 `/usr/src/linux-headers-4.4.0-31-generic'
  CC [M]  /home/arm/data/char_driver/GlobalCharDev.oBuilding modules, stage 2.MODPOST 1 modulesLD [M]  /home/arm/data/char_driver/GlobalCharDev.ko
make[1]:正在离开目录 `/usr/src/linux-headers-4.4.0-31-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 < 0){printf("Open Device Fail!\n");return -1;}/* 读取当前设备数值 */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 0;}

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

   执行:

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

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

通过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

解决驱动卸载问题

转载于:https://www.cnblogs.com/chu-yi/p/10671865.html

tiny4412--linux驱动学习(2)相关推荐

  1. linux uart寄存器 代替 printk,Linux驱动学习之设备树(设备树下的LED驱动实验),...

    Linux驱动学习之设备树(设备树下的LED驱动实验), 概念 Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离.相当于从驱动代码分离出来的配置文件,比如串口的波特率通过设 ...

  2. Linux驱动学习--USB接口wifi/BT芯片开发之BT开发(BlueDroid框架)

    目录 一.引言 二.整体框架分析(结合实际芯片分析) 三.内核中的相关配置 四.厂家驱动分析 五.蓝牙BlueDroid协议 一.引言 之前我们简单分析过BlueDroid框架,今天来结合源码,挑重点 ...

  3. IMX6ULL嵌入式Linux驱动学习笔记(二)

    IMX6ULL嵌入式Linux驱动学习 一.字符设备驱动 二.驱动模块的加载与卸载 三.字符设备的注册与注销 四.设备号 五.file_operations的具体实现 六.字符设备驱动框架 七.编写应 ...

  4. Linux 驱动学习笔记 - beep(九)

    Linux 驱动学习笔记 - beep(九) 本系列均为正点原子 Linux 驱动的学习笔记, 以便加深笔者记忆.如读者想进一步学习,可以到正点原子官网中下载资料进行学习. 添加 pinctrl 节点 ...

  5. linux按键检测程序,Tiny4412 Linux驱动之按键(使用查询方式) | 技术部落

    前几天在TIny4412开发板上做了LED点灯的Linux驱动,其实挺简单,GPIO驱动,今天再看一下按键的驱动,毕竟按键用的还是比较广泛的,本文使用查询的方式获取按键值,后面会有文章使用中断的方式进 ...

  6. 讯为4412开发板Linux驱动学习笔记

    驱动理论专题一 Linux驱动程序的基本认识 有了内存管理单元,就有虚拟地址,物理地址. 驱动理论专题二 学会查看原理图 以LED2为示例 通过原理图查看到KP_COL0,赋予高电平则能点亮LED2, ...

  7. Linux驱动学习笔记

    驱动学习笔记 1.字符设备驱动 Linux 驱动有两种运行方式 第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启 动的时候就会自动运行驱动程序. 第二种就是将驱动编译成模块(Li ...

  8. (学习)linux驱动学习知识积累(一)

    一.基础知识扫盲 1.dev_t结构体 在内核中,dev_t结构体用来保存设备编号信息,在linux/type.h中定义,是一个32位的数,12位表示主设备号+20位的次设备号 int MAJOR(d ...

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

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

  10. Linux驱动学习体会(2012年12月4日)

    分析Linux驱动最好是先了解核心代码,然后从具体设备分析入手,然后从下至上,了解整个框架,再从上到下分析,理解透彻.

最新文章

  1. ASP.NET之SOAP的发送、接收与处理类 [转载]
  2. 10张图22段代码,万字长文带你搞懂虚拟内存模型和malloc内部原理
  3. redis 关系数据库怎么转换 和_redis数据库设计(转)
  4. 因为这几个TypeScript代码的坏习惯,同事被罚了500块
  5. opencv-api drawKeypoints drawMatches
  6. 别担心!人工智能不会抢你的工作
  7. vivadohlsdsp_FPGA硬件加速学习vivado hls-----------------卷积加速
  8. J1939 入门教程
  9. openg显示Bmp图片
  10. 计算机组成原理6-20,计算机组成原理课后题6.20PPT课件
  11. excel统计填充色单元格数
  12. 【Excel VBA】银行卡信用卡卡号校验功能函数
  13. [ExtJS] Tpl模板中的extjs控件无法失焦处理
  14. Angular动态绑定HTML文本
  15. 程序复杂性度量方法-McCabe
  16. 网络七层协议OSI(Open System Interconnection)
  17. win 10网络适配器没有无线网络连接
  18. POE网络红外对射说明和应用
  19. 2016年寒假读书笔记
  20. 高冷的苹果编辑如何一步步成“猫奴”?

热门文章

  1. Asp.Net 设计模式 之 “简单工厂”模式
  2. 2017 ACM-ICPC西安网赛B-Coin
  3. 让执行程序引用特定目录下的Dll
  4. Linux下nginx安装与配置
  5. TigerDLNA for ios 集成Tlplayer
  6. php归档函数(按时间)实现
  7. koa --- 使用Github OAuth登录
  8. 算法 --- 顺序查找、二分查找的js实现
  9. 结对编程作业——毕设导师智能匹配
  10. Laravel中数据库的操作