Linux驱动入门(二)操作硬件

发布者:GoldenHarmony最新更新时间:2025-01-16 来源: cnblogs关键字:Linux 手机看文章 扫描二维码
随时随地手机看文章

Linux驱动入门(二)操作硬件
一、通用做法
ioremap
iounmap
寄存器读写
二、gpiolib
gpio.h
gpiolib.c
三星平台提供的gpio-cfg
三、总结
一、通用做法
玩过单片机的朋友应该懂得如何操作寄存器

举个例子,例如现在想往寄存器地址0xFF223440写数据,在单片机编程中的做法如下

volatile unsigned int *reg = (unsigned int*)0xFF223440;
*reg = val;

在Linux中做法也是类似,只不过Linux不可以直接访问寄存器地址,而要经过映射后才能访问,下面开始介绍

ioremap
映射地址

/*
* cookie:表示要映射的地址
* size:表示要映射的地址范围
*/
ioremap(cookie,size)

例如上面要操作寄存器0xFF223440,在Linux的做法如下

volatile unsigned int *reg = ioremap(0xFF223440, 4);
*reg = val;

当然在映射前要先申请request_region(start,n,name)地址空间,不过这不是必须的

在映射完地址后,当驱动程序退出时,不再使用此地址,需要使用iounmap取消映射

iounmap
取消地址映射

/*
* cookie:映射后的地址
*/
iounmap(cookie)

例如上面的例子中,在驱动程序退出时,需要调用

iounmap(reg);

在取消映射后,如果先前有申请地址空间,那么就需要释放申请的地址空间release_region(start,n)

寄存器读写
在上面的例子中,读写寄存器通过直接访问指针,而内核中提供了一套宏定义来读写寄存器

readb(c) //读8位
readw(c) //读16位
readl(c) ///读32位

writeb(v,c) //写8位
writew(v,c) //写16位
writel(v,c) //写32位

二、gpiolib
上面介绍的是通用的做法,可以访问和设置任意的寄存器

内核中对于gpio的设置,提供了更加简便的方法-gpiolib

gpiolib是一套对gpio的操作函数,有了这些函数,就可以简化对gpio进行操作,而不需要直接通过寄存器来操作

当然gpiolib仅限于操作gpio,如果要操作非gpio相关的寄存器(例如lcd控制器,摄像头控制器等),那么还是要使用上面讲的通用方法,下面开始介绍gpiolib

gpio.h
对于每一款芯片,大多在移植的时候都有对应一个gpio.h文件

对于每一款芯片,大多在移植的时候都有对应一个gpio.h文件

以三星平台的S5PV210为例,gpio.h位于archarmmach-s5pv210includemachgpio.h

其中定义了一系列的gpio相关的宏

S5PV210_GPA0(_nr)
S5PV210_GPA1(_nr)
S5PV210_GPB(_nr)
...

可以使用这些宏定义,通过gpiolib提供的函数来操作gpio

gpiolib.c
gpiolib.c位于driversgpiogpiolib.c,其中定义了一系列的gpio操作函数,gpio的操作函数需要搭配gpio.h中的宏定义使用

int gpio_request(unsigned gpio, const char *label)
void gpio_free(unsigned gpio)
int gpio_direction_input(unsigned gpio)
int gpio_direction_output(unsigned gpio, int value)
int gpio_get_value(unsigned gpio)
void gpio_set_value(unsigned gpio, int value)
int gpio_to_irq(unsigned gpio)

gpio_request

申请gpio,在使用gpio前,应该先申请gpio,当然这并不是必须的

gpio_free

释放gpio,用于释放被申请了的gpio

gpio_direction_input

设置gpio为输入

gpio_direction_output

设置gpio为输出,并设置gpio高低电平

gpio_get_value

获取gpio的高低电平

gpio_set_value

设置gpio的高低电平

gpio_to_irq

获取gpio对应的外部中断

如果我们设置S5PV210的GPIOA0的第四个引脚为高电平,我可以这样做

/* 申请 */
gpio_request(S5PV210_GPA0(3), 'm_gpio');

/* 设置 */
gpio_direction_output(S5PV210_GPA0(3), 1);

/* 不需要时释放 */
gpio_free(S5PV210_GPA0(3));

从上面的操作函数中,可以看到,gpio-lib仅支持设置gpio为输入或者输出,但要知道,有些gpio是可以复用成其他功能的(例如摄像头接口的gpio等),下面是从S5PV210的datasheet中截图的

 

可以看到GPE0-0不仅可以设置为Input(输入模式)和Output(输出模式),还可以复用为CAM_A_PCLK(摄像头接口A的像素时钟引脚)

那么如果没有其他的支持,我们就需要使用通用的方式来配置寄存器,为此,三星平台再提供了一套操作gpio的函数

三星平台提供的gpio-cfg
文件位于archarmplat-samsungincludeplatgpio-cfg.h

其中的操作函数分为三类,第一类配置gpio,第二类设置gpio引脚状态,第三类设置gpio的驱动强度

配置gpio

#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0)) //输入
#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1)) //输出
#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x)) //复用功能

int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); //配置
unsigned s3c_gpio_getcfg(unsigned int pin); //获取配置

例如上述例子,如果要设置GPE0-0为摄像头接口A的像素时钟引脚,那么就这么配置

s3c_gpio_cfgpin(S5PV210_GPE0(0), S3C_GPIO_SFN(2));

设置引脚状态

#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00) //悬空
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01) //下拉
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02) //上拉

int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);

设置引脚驱动强度

#define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x00)
#define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x01)
#define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x10)
#define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x11)

s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);

三、总结
使用通用的方法可以设置任意寄存器,只是比较麻烦
使用gpiolib可以较为方便地配置gpio,但仅限于gpio,如果需要设置非gpio,还是需要使用通用地方法
内核提供的gpiolib只能配置gpio为输入或者输出,其他功能(例如复用引脚,设置上下拉等)无法通过gpiolib设置,三星平台提供了另一套函数设置


关键字:Linux 引用地址:Linux驱动入门(二)操作硬件

上一篇:Samsung_tiny4412(驱动笔记01)----linux 3.5,U-Boot,Busybox,SD卡启动环境搭建
下一篇:Linux驱动入门(三)Led驱动

推荐阅读最新更新时间:2026-03-22 11:32

Linux驱动入门(四)非阻塞方式实现按键驱动
一、注册字符设备 二、操作硬件 2.1 操作按键 2.2 通用方式实现 2.3 gpiolib实现 三、源码 3.1 通用方式实现 3.2 gpiolib实现 四、测试 本文目标:实现一个按键驱动,通过read函数非阻塞读取按键的状态 一、注册字符设备 首先第一步,先编写字符设备的框架,这一部分在Linux驱动入门(一)字符设备驱动基础中已经做了详细介绍,这里直接给出源码,不做过多的解释 #include linux/module.h #include linux/init.h #include linux/fs.h #include linux/cdev.h #include linux/slab.h #include linu
[单片机]
AR机器人公司发布机器人操作系统(ROS)硬件加速框架ROBOTCORE
Acceleraon RoboticsS.L.是一家位于巴斯克地区的机器人初创,专注于通过和为机器人设计定制大脑以加快其响应速度,公司发布了机器人操作系统(ROS)加速框架——ROBOTCORE™。ROS是机器人技术的标准。该公司为机器人提供半导体构建模块,通过硬件加速为高性能机器人创建定制计算架构,同时保持机器人和加速器的硬件无关性(支持流行的FPGA和GPU)。 ROBOTCORE™可帮助机器人工程师创建与ROS和ROS 2 API兼容的知识产权(IP)核心,以提高包括延迟和吞吐量在内的机器人性能。这些“机器人核心”使机器人速度更快,更具确定性且更加节能。ROBOTCORE™推出时支持超过10款开发板,包括非常流行的硬
[机器人]
1.6.1_NOR_FLASH原理和硬件操作
录制的视频使用的是MX29LV800BBTC型号NOR FLASH芯片,S3C2440开发板上的是MX29LV16,但实际上它们的操作方法是一样的。 NOR FLASH可以像内存一样读,但是不可以像内存一样写,需要做一些特殊的操作来写。 NOR FLASH与NAND FLASH的比较就不列了,大致就是NOR FLASH的价格比较贵,容量比较小,但是稳定,NAND FLASH虽然便宜容量也大,但是没那么稳定,有位反转和坏块的风险,通常用来存储一些不那么重用或者对准确度要求不那么高的数据,比如视频监控数据。 由于NOR FLASH可以像内存一样读,所以NOR FLASH有一个特点,就是可以excute in place(X
[单片机]
1.6.1_NOR_FLASH原理和<font color='red'>硬件</font><font color='red'>操作</font>
AS5048的硬件SPI操作源码
调了半天终于调通了,贴出来给有需要的朋友参考下,给stm32写的,硬件SPI: c文件: /** ****************************************************************************** * @file AS5048A.c * @author Lei Liu * @version V1.0 * @date 2018.03.16 * @brief ****************************************************************************** * @attention *
[单片机]
STM32硬件IIC操作
Stm32具有IIC接口,接口有以下主要特性 多主机功能:该模块既可做主设备也可做从设备 主设备功能 C地址检测 产生和检测7位/10位地址和广播呼叫 支持不同的通讯速度 状态标志: 发送器/接收器模式标志 字节发送结束标志 总线忙标志 错误标志 2个中断向量 可选的拉长时钟功能 具单字节缓冲器的DMA 虽然很多人说STM的硬件IIC不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢, IIC借口一共有九个寄存器,比较重要的几个寄存器分别如下 1. CR1 由这几个位我们可以正常产生标准IIC的START条件STOP条件,ACK与NOACK CR2 控制IIC的通行频率 这两位检测IIC总线
[单片机]
STM32<font color='red'>硬件</font>IIC<font color='red'>操作</font>
嵌入式操作系统的通用硬件抽象层设计
引言   为了便于操作系统在不同硬件结构上进行移植,美国微软公司首先提出了将操作系统底层与硬件相关的部分单独设计成硬件抽象层HAL(Hardware Abstraction Layer)的思想。硬件抽象层的引入大大推动了嵌入式操作系统的通用程度,为嵌入式操作系统的广泛应用提供了可能。然而,目前BSP形式的硬件抽象层仅仅能够解决有限的几种操作系统在同样有限的BSP所支持的硬件平台上的移植,而对绝大多数需要根据不同嵌入式应用而专门定制的嵌入式操作系统来说能起的作用则非常有限。 1 硬件抽象层原理 1.1 硬件抽象层概念   嵌入式系统是一类特殊的计算机系统。它自底向上包括3个主要部分:硬件环境、嵌入式操作系统和嵌入式应用程序。
[应用]
51单片机入门 - 按键驱动程序设计实验
独立按键原理是这样的:按键没按下的时候,相应端口是高电平状态,而当按键按下的时候,相应的端口则是低电平。所以可以根据这个现象,实现相应的功能。 还有一点应该注意的是:按键在闭合和断开时,触点会存在抖动现象。 在实际情况下,我们需要的是稳定闭合的那部分状态。所以可以采用延时的方法来解决这个问题,具体的过程就是先看看有没有键按下,有键按下了,再延迟一段时间,再看看有没有键按下, 这时候如果还是有键按下的话那就真的是有键按下了。 而这个抖动的时间大概是10ms,所以只要用一个延时10ms的子函数就行。 上面代码的第66行那个判断按键是否松开也是必要的,虽然在这个程序中
[单片机]
51单片机<font color='red'>入门</font> - 按键<font color='red'>驱动</font>程序设计实验
恒流AC-DC LED驱动器快速入门及特性介绍
MB39C601是反激式开关调节控制器IC。它根据 LED 负载来控制开关导通时间或控制开关频率,从而实现对LED电流的调节。它非常适合用于常规照明应用,如商铺和住宅照明灯泡等。MB39C601是反激式开关调节控制器。它根据LED负载来控制开关导通时间或控制开关频率,从而实现对LED电流的调节。    一、MB39C601:恒流AC-DC LED驱动 器快速入门指南   MB39C601是一款恒流AC-DCLED驱动器,驱动功率5W~25W,支持世界范围85V~265VAC电压输入。该芯片支持可控硅调光,并带主动PFC,具有高效率、高PF值、低EMI等特点。适用于室内 LED照明 ,如LED灯泡,LED灯管,PAR灯,吸顶灯等。
[电源管理]
恒流AC-DC 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