关于i2c_register_board_info()函数

本文介绍了Linux系统中I2C设备的两种注册方法:通过i2c_register_board_info()函数进行静态注册,以及使用i2c_new_probed_device()函数进行动态注册。静态注册在板级初始化函数中完成,动态注册则适用于某些特定场景。
i2c_register_board_info()函数用于往__i2c_board_list这条链表添加一条i2c设备信息,在i2c adapter注册的时候,会扫描__i2c_board_list链表,然后调用i2c_new_device()函数来注册i2c设备,注意,要先于i2c adapter注册之前就添加好i2c设备信息,否则会出现调用了i2c_register_board_info()函数,而设备不能注册的情况。

i2c_register_board_info()函数如下:
int __init
i2c_register_board_info(int busnum,
	struct i2c_board_info const *info, unsigned len)
{
	int status;

	down_write(&__i2c_board_lock);

	/* dynamic bus numbers will be assigned after the last static one */
	if (busnum >= __i2c_first_dynamic_bus_num)
		__i2c_first_dynamic_bus_num = busnum + 1;

	for (status = 0; len; len--, info++) {
		struct i2c_devinfo	*devinfo;

		devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
		if (!devinfo) {
			pr_debug("i2c-core: can't register boardinfo!\n");
			status = -ENOMEM;
			break;
		}

		devinfo->busnum = busnum;
		devinfo->board_info = *info;
		list_add_tail(&devinfo->list, &__i2c_board_list);
	}

	up_write(&__i2c_board_lock);

	return status;
}
注册i2c总线流程如下:
i2c_add_numbered_adapter()->i2c_register_adapter()

在i2c_register_adapter()函数中调用了i2c_scan_static_board_info()函数,代码如下:
static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
	struct i2c_devinfo	*devinfo;

	down_read(&__i2c_board_lock);
	list_for_each_entry(devinfo, &__i2c_board_list, list) {
		if (devinfo->busnum == adapter->nr
				&& !i2c_new_device(adapter,
						&devinfo->board_info))
			dev_err(&adapter->dev,
				"Can't create device at 0x%02x\n",
				devinfo->board_info.addr);
	}
	up_read(&__i2c_board_lock);
}

i2c_scan_static_board_info()函数先扫描__i2c_board_list,然后调用i2c_new_device()函数来注册i2c设备。这就是静态注册i2c设备的方法,一般在板级的初始化函数中调用i2c_register_board_info()函数来完成i2c设备信息的添加。

除了这种方法外,Linux还提供了另外的方法来注册i2c设备。例如:

static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };

static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
{
	(...)
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	(...)
	i2c_adap = i2c_get_adapter(2);
	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
	isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c);
	i2c_put_adapter(i2c_adap);
	(...)
}
来自Documentation/i2c/instantiating-devices。
<think>好的,用户现在想了解I2C_CHIP_ADDR在I2C通信中的作用和定义。我需要先回顾之前的问题和回答,看看有没有相关的信息可以引用。用户之前询问过如何在A2B总线上传输I2C和TDM信号,我提到过I2C_CHIP_ADDR用于定义从节点I2C设备的地址。现在需要更详细地解释这个寄存器的定义和用法。首先,我需要明确I2C_CHIP_ADDR的基本概念。在I2C协议中,每个从设备都有一个唯一的地址,主设备通过这个地址与从设备通信。I2C_CHIP_ADDR应该就是用来存储这个地址的寄存器。根据用户提供的引用[1],提到了i2c_register_board_info函数,这可能与设备地址的静态声明有关,但需要结合其他信息。引用[3]中有一个构造函数的例子,里面提到了SDAPin、SCLPin、INTPin等,但没有直接提到I2C_CHIP_ADDR。不过构造函数中的参数可能涉及到地址的设置,可能需要进一步分析。不过用户提供的引用可能更多是示例,需要结合通用I2C知识。接下来,我应该解释I2C_CHIP_ADDR的作用,比如在A2B总线中如何配置从节点的I2C设备地址,确保主节点能够正确寻址。还要提到地址的格式,比如7位或10位,以及如何通过寄存器配置。例如,在A2B系统中,主节点需要知道每个从节点的I2C设备地址,才能正确发送控制命令,这可能涉及到寄存器的写入和读取操作。 同时,用户可能想知道如何在实际代码中使用这个寄存器,比如如何设置地址值,是否需要考虑读写位的处理。例如,在I2C通信中,地址通常左移一位,最低位表示读写操作,但寄存器中的地址可能只存储7位或10位的部分,需要根据具体硬件手册来确定。另外,需要参考用户之前的问题中提到的A2B总线配置流程,其中第4步是I2C地址绑定,写入I2C_CHIP_ADDR建立设备映射表。这说明在A2B系统中,这个寄存器用于将从节点的物理地址与逻辑地址映射,方便主节点管理多个设备。 可能还需要提到地址冲突的问题,如何确保每个从设备的地址唯一,避免通信错误。例如,在初始化时,通过配置不同的I2C_CHIP_ADDR值来区分不同的设备。最后,生成相关问题需要考虑用户可能遇到的后续问题,比如地址配置错误的影响,如何调试,或者与其他总线的对比等。需要确保问题与当前主题相关,帮助用户深入理解。</think>### I2C_CHIP_ADDR的定义及作用 #### 1. **基本定义** 在I2C通信协议中,`I2C_CHIP_ADDR`是用于标识从设备(如传感器、EEPROM等)的**7位或10位地址值**。该地址通过硬件电路固化在设备中,或通过软件配置寄存器实现动态调整[^1][^3]。例如在引用[3]的构造函数中,地址参数可能通过`_pI2CBus->begin(_SDAPin, _SCLPin)`与物理设备绑定。 #### 2. **地址格式** - **7位地址**:标准模式地址范围$0x08$~$0x77$ - **10位地址**:扩展模式地址范围$0x780$~$0x7FE$ 实际传输时地址值需左移1位,最低位表示读写方向(R/W#)[^2]。例如地址$0x50$的写操作实际发送$0xA0$。 #### 3. **在A2B系统中的特殊作用** 在A2B总线架构中,`I2C_CHIP_ADDR`寄存器用于**地址映射**: - 主节点通过写入该寄存器,将物理I2C设备与总线节点关联 - 从节点收到A2B数据帧后,根据`I2C_CHIP_ADDR`值判断是否响应请求[^1] ```c // 示例:配置从节点地址为0x50 #define SLAVE_ADDR 0x50 i2c_write_reg(A2B_CTRL_BASE, I2C_CHIP_ADDR, SLAVE_ADDR << 1); ``` #### 4. **关键应用场景** 1. **多设备管理**: 当总线挂载多个I2C设备时,需为每个设备分配唯一地址: ```mermaid graph TD 主设备 -->|0x50| 温度传感器 主设备 -->|0x68| 陀螺仪 主设备 -->|0x1D| 加速度计 ``` 2. **动态地址分配**: 部分设备支持通过引脚(如AD0)修改地址,此时需重新配置`I2C_CHIP_ADDR`[^3]: $$ \text{最终地址} = \text{基地址} + \text{AD0引脚电平} $$ 3. **错误检测**: 若从设备未返回ACK信号(如引用[2]中的`I2C_Get_Ack`函数),可能因地址配置错误导致通信失败。 #### 5. **配置流程** 1. 初始化I2C控制器:设置时钟频率、引脚模式等 2. 写入`I2C_CHIP_ADDR`寄存器指定目标设备地址 3. 发送START信号并检测ACK响应 4. 执行数据传输(读/写操作) 5. 发送STOP信号结束通信[^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值