当前位置: 首页 > news >正文

Regmap子系统:(寄存器映射)

文章目录

          • Regmap简述
          • Remap配置流程:
          • Remap示例(I2C操作OLED):

Regmap简述
  • Regmap野心很大,希望加入所有总线接口,目前已支持I2C、SPI、MMIO、SPMI等。
  • 当然Regmap框架不仅提供了一种统一接口,而且支持缓存(减少内存的开销)。
Remap配置流程:
  • 1配置regmap_config结构体
  • 2 Regmap初始化
  • 3调用Remap API函数进行读写操作
  • 4释放Regmap
    经过上面的步骤,我们就可以使用Regmap。

**1配置结构体:(一般在驱动程序中声明)

static struct regmap *xxx_regmap;

struct regmap_config{
	const char *name;
	int reg_bits;//寄存器地址的位数,必须初始化一个有效值
	int val_bits;//寄存器值的位数,必须初始化一个有效值
	bool (*writeable_reg)(struct device *dev, unsigned int reg);//回调函数,值为可写寄存器表
	bool (*readable_reg)(struct device *dev, unsigned int reg);//同上,针对每一个寄存器的读取操作
	bool (*volatile_reg)(struct device *dev, unsigned int reg);//回调函数,涉及缓存中读写寄存器会触发
	unsigned int max_register;//最大寄存器地址,防止越界
	const struct regmap_access_table* wr_table;//no support
};

**2结构体初始化:(一般在probe函数中)

由于Regmap仅仅只是一个统一的接口,其底层调用最终还是走的各个子系统协议。

例如要使用I2C子系统,那么我们需要将Regmap映射到I2C接口上(regmap_init_i2c函数),
这样操作regmap的时候实际上就是在操作i2c接口

struct regmap * regmap_init_i2c(struct i2c_client *i2c, //I2C客户端结构体
							const struct *regmap_config)//regmap配置结构体
struct regmap * regmap_init_spi(struct spi_device *spi,//spi设备结构体
							const struct *regmap_config);//regmap配置结构体

**3 Regmap读写操作(在桥梁函数里,即实际的设备操作)
最终目的是操作各个设备进行通信,linux内核提供了响应的接口函数供驱动开发者使用。

//单个寄存器写一个值
static inline int regmap_write(struct regmap *map, unsigned int reg,unsigned int val)
//向单个寄存器写入多个数据
static inline int regmap_raw_write( struct regmap *map,unsigned int reg,//寄存器地址								const void *val, size_t val_len)//写入数据的地址//写入数据的长度
//向多个连续的寄存器中写入多个值
static inline int regmap_bulk_write(struct regmap *map, unsigned int reg,
const void *val, size_t val_count)
//同样还有读操作,以及其它操作
regmap_read、regmap_raw_read、regmap_bulk_read

**4 释放Regmap结构体

void regmap_exit(struct regmap *map)
Remap示例(I2C操作OLED):
  • 0 添加设备树节点:(其中使用OLED内部显示控制器为SSD1306驱动)
    在这里插入图片描述
  • 1 驱动绑定与解绑(sysfs、regmap、platform)
static struct regmap *oled_regmap;
static uint8_t diaplay_buffer[128][8]static int oled_write_cmd(uint8_t cmd){
	ret = regmap_write(oled_regmap,0x00,cmd); //DC=0 command
}
static int oled_write_data(uint8_t data){
	ret = regmap_write(oled_regmap,0x40,data); //DC=1 command
}
static void oled_on(void) {
	oled_write_cmd(0x8D); oled_write_cmd(0x14); oled_write_cmd(0xAF); 
}
static void oled_off(void) {
	oled_write_cmd(0x8D); oled_write_cmd(0x10); oled_write_cmd(0xAE); 
}

//xxxxxxxxxx省略代码xxxxxxxxxregmap提供读写寄存器函数xxxxxxxxxx

static const struct regmap_config oled_config = {//regmap配置结构体
	.reg_bits = 8, //寄存器 8 位
	.val_bits = 8, //数据 8 位
	.max_register = 255, //最大寄存器 255 个
	.cache_type = REGCACHE_NONE, //不使用 cache
	.volatile_reg = false,
};

static ssize_t oled_show(struct device *dev,struct device_attribute *attr,char *buf) {
	oled_off();return 1; 
}
static ssize_t oled_store(struct device *dev,struct device_attribute *attr,const char*buf, size_t count){
	oled_fill_screen(*buf);return count; 
}

static DEVICE_ATTR(oled, 0660, oled_show, oled_store); //定义文件属性
static int oled_probe(struct i2c_client *client, const struct i2c_device_id *id) {
	ret = device_create_file(&client->dev,&dev_attr_oled);//创建属性文件
	oled_regmap = regmap_init_i2c(client,&oled_config);
}
static int oled_remove(struct i2c_client *client){
device_remove_file(&client->dev,&dev_attr_oled);//删除属性文件
	regmap_exit(oled_regmap);
}

static const struct i2c_device_id oled_id[] = {
{ "test,oled", 0 },
}
static const struct of_device_id oled_of_match[] = {
{ .compatible = "test,oled"},
};
MODULE_DEVICE_TABLE(of, oled_of_match);

static struct i2c_driver oled_driver = {
.driver = {
.name = "test,oled",
.owner = THIS_MODULE, 
.of_match_table = oled_of_match,
},
.probe = oled_probe,
.remove = oled_remove,
.id_table = oled_id,
};
module_i2c_driver(oled_driver);

bb那么多的模型框架以及接口目的就是简化我们驱动开发,提高代码规范,到底还是内核抗下了所有

相关文章:

  • 用通俗易懂的方式讲解:lightGBM 算法及案例(Python 代码)
  • TC8:TCP_CONTROL_FLAGS_05-08
  • 2022年华为杯研究生数学建模竞赛ABCDEF题思路资料汇总贴
  • JavaScript原生之垃圾回收原理、标记清理原理
  • python解CCF-CSP真题《202209-2 何以包邮?》
  • 【面试必刷TOP101】面试官:如何删除有序链表中重复的元素?
  • U3DVR向量点乘与叉乘概念及几何模型公式应用
  • stm32串口发送数据包进行解析,实现人机交互
  • 【Django框架】——02 Django虚拟环境搭建
  • 【从零带你玩转Linux】目录文件相关操作指令
  • k8s-资源管理
  • 版本控制工具 之 Git
  • 机器学习笔记 - 使用 Pix2Pix 进行图像翻译
  • 【一起学数据结构与算法】深度学习栈
  • RHCSA知识点汇总
  • #Java异常处理
  • “大数据应用场景”之隔壁老王(连载四)
  • 3.7、@ResponseBody 和 @RestController
  • js
  • js对象的深浅拷贝
  • JS题目及答案整理
  • mockjs让前端开发独立于后端
  • socket.io+express实现聊天室的思考(三)
  • spark本地环境的搭建到运行第一个spark程序
  • 聊聊directory traversal attack
  • 我感觉这是史上最牛的防sql注入方法类
  • 你对linux中grep命令知道多少?
  • ​插件化DPI在商用WIFI中的价值
  • ​批处理文件中的errorlevel用法
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • (1)(1.13) SiK无线电高级配置(六)
  • (2)STL算法之元素计数
  • (c语言)strcpy函数用法
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (接口封装)
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • **CI中自动类加载的用法总结
  • ..回顾17,展望18
  • .a文件和.so文件
  • .net mvc部分视图
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .Net的C#语言取月份数值对应的MonthName值
  • .NET的微型Web框架 Nancy
  • .net通用权限框架B/S (三)--MODEL层(2)
  • @JSONField或@JsonProperty注解使用
  • [.net]官方水晶报表的使用以演示下载
  • [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [C++]类和对象(中)
  • [CCIE历程]CCIE # 20604