嵌入式[基础] Linux下IIC设备驱动描述

2023年 10月 15日 25.7k 0

IIC特点

  • IIC是一种半双工基础协议
  • IIC一次传输8bit,高位在前,低位在后
  • 总线空闲状态时 数据线为高电平
  • IIC总线架构分析

    image.png

    设备驱动层组件 linux*/drivers/i2c/i2c-dev.c

  • 提供用户层相关接口
  • 统一封装发送格式,但不关心数据的发送形式
  • 设备核心层组件 linux*/drivers/i2c/i2c-core.c

  • 注册I2C总线
  • 为驱动层提供编程接口
  • 设备总线驱动层组件 linux*/drivers/i2c/busses/i2c-xxx.c 不同芯片实现不同

  • 初始化硬件相关接口如IIC控制器
  • 实现数据发送形式,如高位发送,不关心具体发送的数据
  • 这三个文件的目的是为了相互配合实现操作相应的外围设备

    IIC核心层分析

    核心层文件 i2c-core-base.c

    postcore_initcall(i2c_init); i2c注册函数

    i2c_init函数分析

    
    
    /* 注册i2c设备,最终形成一个i2c的驱动链表 */
    static int __init i2c_init(void)
    {
        // 注册一根i2c物理总线
        retval = bus_register(&i2c_bus_type); ----|
                                                  |
        struct bus_type i2c_bus_type = { dev_groups = i2c_groups;
    
    	/* Keep track of adapters which will be added or removed later */
    	res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
    	if (res)
    		goto out_unreg_class;
    
    	/* Bind to already existing adapters right away */
    	/* 绑定适配器,绑定具体操作的哪一台设备,搜索I2C总线的设备链表,
               每搜索到一个设备,都会调用i2cdev_attach_adapter */
            i2c_for_each_dev(NULL, i2c_dev_attach_adapter);
    
    	return 0;
    
    out_unreg_class:
    	class_destroy(i2c_dev_class);
    out_unreg_chrdev:
    	unregister_chrdev_region(MKDEV(I2C_MAJOR, 0), I2C_MINORS);
    out:
    	pr_err("Driver Initialisation failedn");
    	return res;
    }
    
    static int i2cdev_attach_adapter(struct device *dev)
    {
    	struct i2c_adapter *adap;
    	struct i2c_dev *i2c_dev;
            
            /* 判断是否是适配器,如果不是则返回 */
    	if (dev->type != &i2c_adapter_type)
    		return NOTIFY_DONE;
                    
    	i2c_dev = get_free_i2c_dev(adap);
            /* 初始化一个i2c设备链表节点 */
            device_initialize(&i2c_dev->dev);
            /* 设置i2c设备名称 /dev/i2c-0 dev/i2c-1... */
    	i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr);
    	i2c_dev->dev.class = i2c_dev_class;
    	i2c_dev->dev.parent = &adap->dev;
    	i2c_dev->dev.release = i2cdev_dev_release;
    }
    

    iic开发涉及到的设备层的重要函数

    int i2c_master_send(const struct i2c_client *client,
    				  const char *buf, int count) 发送函数 字节发送
    int i2c_master_recv(const struct i2c_client *client,
    				  char *buf, int count) 接收函数 字节接收
    int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); 传输一个i2c数据包
    int i2c_register_board_info(int busnum, struct i2c_board_info const *info,
    			unsigned n); 注册i2c板级信息,如i2c的oled屏幕名称
    
    int i2c_add_adapter(struct i2c_adapter *adap); 注册/控制器
    void i2c_del_adapter(struct i2c_adapter *adap); 注销/控制器
    int i2c_add_numbered_adapter(struct i2c_adapter *adap);
    
    注册/注销i2c驱动
    int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
    void i2c_del_driver(struct i2c_driver *driver);
    
    注册/注销i2c设备
    

    相关文章

    服务器端口转发,带你了解服务器端口转发
    服务器开放端口,服务器开放端口的步骤
    产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
    如何使用 WinGet 下载 Microsoft Store 应用
    百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
    百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

    发布评论