MS1112驱动开发(i2c框架)

2024-06-17 1371阅读

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习

擅长领域:驱动开发,嵌入式软件开发,BSP开发

作者主页:一个平凡而乐于分享的小比特的个人主页

文章收录专栏:IMX8MP,本专栏记录imx8mp开发板,学习开发过程中的问题及解决方法记录

欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

MS1112驱动开发(i2c框架)

ms1112驱动代码及测试程序在ms1112驱动,如有需要自行下载

1.不带sysfs

1.1 时序图

根据MS1112数据芯片手册的写时序和读时序,编写MS1112驱动

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

1.2 驱动函数

写函数:

/*
 * @description	: 向ms1112多个寄存器写入数据
 * @param - dev:  ms1112设备
 * @param - reg:  要写入的寄存器首地址
 * @param - buf:  要写入的数据缓冲区
 * @param - len:  要写入的数据长度
 * @return 	  :   操作结果
 */
static s32 ms1112_write_regs(struct ms1112_dev *dev, u8 reg, u8 *buf, u8 len)
{
	u8 b[256];
	int ret;
	struct i2c_msg msg;
	
	struct i2c_client *client = (struct i2c_client *)dev->private_data;
	printk("write I2C device address: 0x%x\n", client->addr);
	
	memcpy(&b[0],buf,len);		/* 将要写入的数据拷贝到数组b里面 */
		
	msg.addr = client->addr;	/* ms1112地址 */
	msg.flags = 0;				/* 标记为写数据 */
	msg.buf = b;				/* 要写入的数据缓冲区 */
	msg.len = len;			/* 要写入的数据长度 */
	ret = i2c_transfer(client->adapter, &msg, 1);
	printk("write:%d\n",ret);
          	if(ret == 1) {
                	ret = 0;
        	} else {
                	ret = -EREMOTEIO;
        	}
        	return ret;
}

读函数:

/*
 * @description	: 从ms1112读取多个寄存器数据
 * @param - dev:  ms1112设备
 * @param - reg:  要读取的寄存器首地址
 * @param - val:  读取到的数据
 * @param - len:  要读取的数据长度
 * @return 		: 操作结果
 */
static int ms1112_read_regs(struct ms1112_dev *dev, u8 reg, void *val, u8 len)
{
	int ret;
	struct i2c_msg msg[1];
	struct i2c_client *client = (struct i2c_client *)dev->private_data;
	/* msg[1]读取数据 */
	msg[0].addr = client->addr;			/* ms1112地址 */
	msg[0].flags = I2C_M_RD;			/* 标记为读取数据*/
	msg[0].buf = val;					/* 读取数据缓冲区 */
	msg[0].len = len;					/* 要读取的数据长度*/
	ret = i2c_transfer(client->adapter, msg, 1);
	printk("read:%d\n",ret);
	if(ret == 1) {
		ret = 0;
	} else {
		ret = -EREMOTEIO;
	}
	return ret;
}

1.3 运行测试

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

会看到加载ms1112.ko驱动后,会在/dev/目录下生成ms1112设备,我们用应用程序对/dev/ms1112设备进行操作,读取电压值与测得的电压值相差不大

2.不带sysfs

不带sysfs和带sysfs的ms1112驱动大体相似,只需稍作修改

2.1 修改部分

主要修改如下:

static int ms1112_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
        int rv=0;
.....
        /* 5、创建sysfs文件初始化*/
        if(device_create_file(ms1112dev.device,&dev_attr_ms1112))
        {
                rv=-ENOMEM;
                goto undo_device;
        }
        printk("%s deiver init sysfs successfully!\n",MS1112_NAME);
        /* 6、保存私有数据*/
        ms1112dev.private_data = client;
        dev_set_drvdata(ms1112dev.device,&ms1112dev);
.....
}
static ssize_t ms1112_show(struct device *dev, struct device_attribute *attr, char *buf)
{
        struct ms1112_dev *ms_dev = (struct ms1112_dev *)dev_get_drvdata(dev);
        ms1112_write_reg(&ms1112dev, MS1112_CFG_REG, MS1112_DEFAULT_CONFIG);
        ms1112_readdata(ms_dev);
        printk("dev->value: %d\n", ms_dev->value);
        return sprintf(buf, "adc=%d\n", ms_dev->value);
}
static ssize_t ms1112_store(struct device *dev,struct device_attribute *attr,const char *buf,size_t count)
{
        return count;
}
DEVICE_ATTR(ms1112,0644,ms1112_show,ms1112_store);

2.2 运行测试

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

测得电压与通过adc采样值算出的电压相近

3.遇到问题及解决方法

3.1驱动程序读出的adc值与测试程序不符

驱动读adc值函数:

MS1112驱动开发(i2c框架)

测试程序:

MS1112驱动开发(i2c框架)

运行结果:

MS1112驱动开发(i2c框架)

然后我用逻辑分析仪抓波形,发现驱动程序没问题,是测试程序的问题

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

int16_t类型的数据不应该超过32767啊

问题解决

是我驱动程序写的不规范,导致的,具体原因:

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

驱动程序的读adc函数,返回的是0,并没有对错误做处理,导致测试程序read()函数返回0,直接执行,这是不符合系统调用read函数规范的

我做了如下修改:

MS1112驱动开发(i2c框架)

MS1112驱动开发(i2c框架)

最终,测试程序的adc值与驱动相符。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]