创建一个字符设备1.1

发布者:EternalWhisper最新更新时间:2025-02-17 来源: cnblogs关键字:字符设备  S5PV210 手机看文章 扫描二维码
随时随地手机看文章

在开始之前,我们先了解什么是内核模块。

内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间运行的程序

内核模块可以让操作系统内核需要的时候加载,不需要的时候由操作系统进行卸载。拓展了操作系统的功能,不会让操作系统变得很臃肿。

------------------------------------------------------------------------------------------------------------------------------------------------

内核模块与应用程序区别

     应用程序       驱动程序
运行   用户空间            内核空间
入口   main           module_init(初始化函数)
出口    无            module_exit(卸载函数)
编译        gcc -c                           Makefile
链接         ld            insmod
运行   ./                                  insmod

 

        由上面阐述可知,应用程序和驱动程序存在不同空间,操作的方法也不同。而且,又由于驱动是内核的一部分。

所以,我们在编写驱动程序的时候要非常仔细,像不做出错处理、忘记释放内存等动作在我们的驱动程序的编写中都是不允许的!

========================================================================================

                下面,我们来说下如何创建一个简单的字符设备驱动。

1. 我们在写驱动时,首先要查阅芯片厂商提供的源代码。看它如何创建,然后我们依葫芦画瓢地进行我们驱动的编写。如本人用的是三星公司的S5PV210 cortex-A8架构的芯片。

2. 创建一个设备初始化函数、设备退出函数   如下:

  int __init gec210_led_init(void)
  {
    printk('hello gec210 led drivern');

  return 0;

  }

  void __exit gec210_led_exit(void)
  {
    printk('exit gec210 led drivern');
  }

其中: 我们的加载指令insmod    卸载指令rmmod分别对应如下函数

  module_init(gec210_led_init); //insmod
  module_exit(gec210_led_exit); //rmmod

最后,我们需要加上设备的相关信息

  MODULE_AUTHOR('Mr.Jin_Fa');                                 作者
  MODULE_DESCRIPTION('S5PV210 LED driver');        功能描述
  MODULE_LICENSE('GPL');            设置宏定义,遵守GPL证书 如不写或写其他参数,编译可能会失败。

以上代码能实现最基本的加载、卸载驱动过程。 不过这里有几点需要注意的

  1)不能使用C语言的库函数
  printf memcpy memset .......

  2)使用GNU C语言,会跟ANSI C语言有所出入,如在初始化结构体的方法上。

  3)内核编程的时候不要使用浮点数,因为浮点数的运算需要库的支持 (本人之前在做ARM裸机开发的时候,就遇到过不支持浮点运算的问题

                   解决办法是 在Makefile上加上arm-linux-gcc 库的路径,并且在主函数那里加一个空的raise()函数)

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------

                    用于管理编译模块的Makefile的编写

obj-m +=led_drv.o    将led_drv.c文件编译为led_drv.o文件(通过查找下面的规则),然后将led_drv.o文件再链接成一个独立的module(led_drv.ko)
KERN_DIR=/home/gec/android-kernel-samsung-dev             定义了一个已经正确编译过的内核源代码的路径,编译过程中,要去内核源代码拿编译工具,使用相应的头文件。
PWD:=$(shell pwd)                                                                  指出当前路径

modules:                       // 目标moudules 的生成规则如下
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules             编译的时候,去内核源代码目录下,找编译工具(Makefile、Kbuild)和头文件;然后回到当前路径下,将驱动文件编译为一个module。

          

clean:         将过程文件和 .ko模块文件clean掉
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean

 

                   写完管理编译工具Makefile后 我们就可以编译我们的模块了

=================================================================================================

                    实现效果

gec@ubuntu:/mnt/hgfs/share/001/demo1$ make
make -C /home/gec/android-kernel-samsung-dev M=/mnt/hgfs/share/001/demo1 modules
make[1]: Entering directory `/home/gec/android-kernel-samsung-dev'            这里可以看到 Makefile进入我们制定的源代码路径找工具...
CC [M] /mnt/hgfs/share/001/demo1/led_drv.o                                                
Building modules, stage 2.
MODPOST 1 modules
CC /mnt/hgfs/share/001/demo1/led_drv.mod.o                                                 生成  .o 文件
LD [M] /mnt/hgfs/share/001/demo1/led_drv.ko                                                 连接成  .ko文件
make[1]: Leaving directory `/home/gec/android-kernel-samsung-dev'

 

 

编译完后,在ubuntu当中查看驱动信息

gec@ubuntu:/mnt/hgfs/share/001/demo1$ modinfo led_drv.ko
filename: led_drv.ko
license: GPL
description: S5PV210 LED driver
author: Mr.Jin_Fa
depends:
vermagic: 2.6.35.7-GEC210 preempt mod_unload ARMv7

 

然后愉快地上传到开发板看看...

  在开发板测试与卸载驱动
  [root@GEC210 /]# insmod led_drv.ko              //加载驱动
  [ 58.687003] hello gec210 led driver


  [root@GEC210 /]# lsmod                //显示当前的led_drv.ko是否加载成功
  led_drv 540 0 - Live 0xbf011000
  ...........


  [root@GEC210 /]# rmmod led_drv           //卸载驱动
  [ 102.104536] exit gec210 led driver

 

PS:  这里能正常运行是因为 我们开发板的内核版本、本地版本和 编译模块是一致的,这是保证模块和内核的兼容性,是一种安全措施。 

版本为:2.6.35.7-GEC210          2.6.35.7 为内核版本           -GEC210 为本地版本

 

如何写一个硬件相关的字符设备驱动,在《创建一个字符设备1.2》这篇细讲...


关键字:字符设备  S5PV210 引用地址:创建一个字符设备1.1

上一篇:input子系统
下一篇:创建一个字符设备1.2

推荐阅读最新更新时间:2026-03-24 11:54

迅为4412开发板Linux字符设备控制(二)
17.3 字符类 Buzzer 蜂鸣器 和 led 灯类似,蜂鸣器的设备节点也是在/dev 目录下,如下图所示。 蜂鸣器的硬件和 led 灯类似,如下图所示。 如上图所示。 原理图很容易理解,如果网络 MOTOR_ PWM 为高电平,则 L9014 导通,蜂鸣器响,如果网络MOTOR_PWM 为低电平,则 L9014 截止,蜂鸣器则不响。 操作方式和 led 小灯类似。 蜂鸣器测试例程 编写简单的 buzzertest.c 文件测试蜂鸣器。 首先添加头文件,如下图所示,下面新加了几个库文件,一般常用的就是下面几个,写代码的时候, 为了方便,可以直接都添加上。 然后 main 函数如下图所示。 如上图
[单片机]
迅为4412开发板Linux<font color='red'>字符</font><font color='red'>设备</font>控制(二)
创建一个字符设备1.2
          本文接着《创建一个字符设备1.1》讲如何创建字符设备模型、怎么创建设备文件 =============================================================================================     创建字符设备流程 1.定义一个cdev   2.申请设备号     .静态注册     .MKDEV     .register_chrdev_region     .动态注册     .alloc_chrdev_region   3.定义file_operations,并且初始化   4.cdev初始化   
[单片机]
字符设备驱动(1)驱动代码完整源码:charButtons.c
内核版本:Linux3.0.8 开发板:基于三星S5PV210处理器的Tiny210开发板 驱动名称:charButtons.c 驱动描述:按键触发中断,中断处理程序执行相应的简单LED点亮操作 方案1注册字符设备使用新的接口实现(需要好几个函数来实现。貌似更复杂) 方案2注册字符设备使用老的接口实现(貌似老接口更简单) /***************************************************************************** 简 述:简单字符型驱动程序,手动静态分配设备号,手动创建设备节点 ********************************
[单片机]
ARM Linux字符设备驱动程序
1、主设备号和次设备号(二者一起为设备号): 一个字符设备或块设备都有一个主设备号和一个次设备号。主设备号用来标识与设备文件相连的驱动程序,用来反 映设备类型。次设备号被驱动程序用来辨别操作的是哪个设备,用来区分同类型的设备。 linux内核中,设备号用dev_t来描述,2.6.28中定义如下: typedef u_long dev_t; 在32位机中是4个字节,高12位表示主设备号,低12位表示次设备号。 可以使用下列宏从dev_t中获得主次设备号:                    也可以使用下列宏通过主次设备号生成dev_t: MAJOR(dev_t dev); MKDEV(int major,int
[单片机]
ARM Linux<font color='red'>字符</font><font color='red'>设备</font>驱动程序
字符设备的另一种写法
对于前面的使用register_chrdev函数注册字符设备驱动程序的方法其实是尚未升级到2.6内核版本的驱动代码。使用这种方式虽然理解起来简单(可以简单理解为一主设备号为下标将驱动的file_operations结构体放入名为chrdevs的数组中,而当应用层调用open函数时,会通过字符设备的主设备号从chrdevs数组中找出file_operations结构体的open函数调用),但是有个缺点就是对于同一个主设备号的,不同的256个次设备号都可以调用同一个open,这样造成可用的设备驱动最多只能有256个。所以在2.6内核版本之后,有一个dev_t类型,它用于保存设备编号,它是一个32位的数,其中12位被用于主设备号,其余2
[单片机]
<font color='red'>字符</font><font color='red'>设备</font>的另一种写法
字符设备驱动程序--LED驱动
编写驱动程序需要编写那些代码: 1、硬件相关的驱动程序 2、Makefile的编译程序 3、还需要编写一个相关的测试程序 比如说:一个摄像头驱动程序 1、驱动程序的编写,需要编写一些硬件相关的操作,编译Makefile 2、安装、运行、卸载驱动程序(insmod ***、。./*** 、remod *** )。 3、使用这个驱动程序:需要一个测试程序,如QQ(测试程序)打开摄像头。 编写驱动程序框架: APP:(测试程序) open read write ......... -----------------------------------------------------
[单片机]
字符设备驱动程序按键驱动---中断方式
中断函数:包含#include linux/irq.h request_irq(irq,handle,irqflag,name,dev_id) { 1,分配一个irqaction结构体 2、把这个结构体放到irq_desc (action链表)中 3、设置引脚 4、使能中断 } free_irq(irq,dev_id) { 1、irqaciton出链 2、禁止中断 } ----------------------------------------------------------------------------------------------------------------------
[单片机]
从Linux内核LED驱动来理解字符设备驱动开发流程
开发环境 环境说明 详细信息 备注信息 操作系统 Ubunut 18.04.3 LTS 开发板 S3C2440(JZ2440-V3) kernel版本 linux-3.4.2 官网地址 busybox版本 busybox-1.22.1 官网地址 编译器 arm-linux-gcc-4.4.3 下载地址 编译器路径 /opt/FriendlyARM/toolschain/4.4.3/bin 绝对路径 1. Linux字符设备驱动的组成 引自宋宝华《Linux设备驱动开发详解--基于最新的Linux 4.0内核》P138内容: 在Linux中,字符设备驱动由如下几个部分组成。 1. 字符设备
[单片机]
从Linux内核LED驱动来理解<font color='red'>字符</font><font color='red'>设备</font>驱动开发流程
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved