刚刚结束对传感器HMC5883L的驱动书写及调试工作,虽然之前对相关的各种知识点都有接触,但是在真正从头书写驱动的时候还是遇到了很多不大不小的麻烦,在这里自行总结一下,也是作为以后驱动书写的一个经验教训,更是对以往所学内核驱动相关知识的复习和总结。事实证明,看了多少书,也不如亲自动手实践学的快,记得牢。
root@arm:/home/debian# i2cdetect -l i2c-0 i2c OMAP I2C adapter I2C adapter i2c-1 i2c OMAP I2C adapter I2C adapter然后,在代码中可以这样使用:
struct i2c_adapter *adap; int adap_nr = 1; // 总线号为1 adap = i2c_get_adapter(adap_nr);
static int hmc5883l_probe(struct i2c_client *client, struct i2c_device_id *id) { ... i2c_set_clientdata(client, dev); dev->client = client; ... }驱动未写,调试先行。如果在开始着手书写驱动前就能直接的通过工具的简单应用对器件进行调试查看的话,会对驱动的书写有很大的帮助。所以这里要说一下关于I2C在shell中的几个调试命令i2cdetect, i2cdump, i2cget, i2cset。首先是i2cdetect,一般用来探测和罗列总线(上边就演示了一下),一般使用方法是:罗列总线->探测有效设备
i2cdetect -l //罗列现有I2C适配器信息 i2cdetect -y -r 1 // 查看总线号为1的I2C适配器上挂载的所有设备,如果设备真实有效,则地址会显示出来,而不是UU,UU代表也许有实际设备,但设备可能是忙状态
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --这里就可以看到,设备从地址为0x68和0x1e的设备有实际有效的硬件连接,分别是HMC5883L和AD0接地(不连)的MPU6050。0x54 55 56 57为EEPROM,设备忙。
root@arm:/home/debian# i2cdump -y 1 0x1e No size specified (using byte-data access) 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: 10 20 03 01 21 01 4b ff 50 03 48 34 33 00 00 3c ? ??!?K.P?H43..< 10: 00 00 00 00 00 00 00 00 00 00 00 94 09 04 e8 10 ...........????? 20: 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ........?....... 30: 00 00 00 14 11 55 56 00 a0 00 07 00 00 00 00 00 ...??UV.?.?..... 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 80: 10 20 03 01 21 01 4b ff 50 03 48 34 33 00 00 3c ? ??!?K.P?H43..< 90: 00 00 00 00 00 00 00 00 00 00 00 94 09 04 e8 10 ...........????? a0: 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 ........?....... b0: 00 00 00 14 11 55 56 00 a0 00 07 00 00 00 00 00 ...??UV.?.?..... c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................然后是i2cget和i2cset,分别是对寄存器进行获取和写入。用法为i2cget -y 总线号 设备地址 寄存器地址 模式和i2cset -y 总线号 设备地址 寄存器地址 数值 模式。模式默认为b(byte)即读取8bit数据,i2cget可用模式有b/w/c,i2cset可用模式有b/w/c/i/s,其中w为word(16bit),i和s分别为I2C和SMBUS的block数据。