QNX----I2C驱动框架

I2C (interintegrated Circuit)是一种简单的串行协议,它以主从关系连接多个设备。多个主设备可以共享一个总线。在不同的事务中,同一设备可以同时充当主从设备。I2C规范定义了这些传输速度范围:

  • ≤ 100 Kbit/s
  • ≤ 400 Kbit/s
  • ≤ 3.4 Mbit/s

I2C框架由以下部分组成:

hardware/i2c/*   硬件接口

lib/i2c   资源管理器层

<hw/i2c.h> 定义硬件和应用程序接口的公共头文件

I2C总线最常见的应用是对从设备寄存器的低带宽、低速率访问,例如:编写音频编解码器、编程一个RTC程序、读取温度传感器数据等等。 通常,总线上只交换几个字节。可以将I2C主机实现为单线程资源管理器或专用应用程序。资源管理器接口的主要优点是:

1、它为应用程序开发人员提供了一个清晰、易于理解的思路。

2、它作为一个中介,在多个应用程序对一个或多个从设备之间进行访问,强制不同I2C接口之间的一致性。

3、对于专用的i2c总线应用程序,硬件访问库更有效;硬件接口定义了这个库的接口,有助于维护和代码可移植性。

1、硬件管理接口

typedef struct {
    size_t size;    /* size of this structure */
    int (*version_info)(i2c_libversion_t *version);
    void *(*init)(int argc, char *argv[]);
    void (*fini)(void *hdl);
    i2c_status_t (*send)(void *hdl, void *buf, unsigned int len, 
                         unsigned int stop);
    i2c_status_t (*recv)(void *hdl, void *buf, unsigned int len, 
                         unsigned int stop);
    int (*abort)(void *hdl, int rcvid);
    int (*set_slave_addr)(void *hdl, unsigned int addr, i2c_addrfmt_t fmt);
    int (*set_bus_speed)(void *hdl, unsigned int speed, unsigned int *ospeed);
    int (*driver_info)(void *hdl, i2c_driver_info_t *info);
    int (*ctl)(void *hdl, int cmd, void *msg, int msglen, 
               int *nbytes, int *info);
} i2c_master_funcs_t;

这是整个硬件接口函数,提供了10个接口函数,分别对10个接口函数进行介绍:

1、version_info函数来获取关于库版本的信息。这个函数的原型是:

   int version_info( i2c_libversion_t *version );

version参数是指向这个函数必须填充的i2c_libversion_t结构的指针。该结构定义如下:

typedef struct {
    unsigned char   major;
    unsigned char   minor;
    unsigned char   revision;
} i2c_libversion_t;

这个函数应该设置这个结构的成员如下:

version->major = I2CLIB_VERSION_MAJOR;
version->minor = I2CLIB_VERSION_MINOR;
version->revision = I2CLIB_REVISION;

2、init函数初始化主接口。该函数的原型是:

void *init( int argc, char *argv[]);

参数是在命令行上传递的。函数返回传递给所有其他函数的句柄,如果发生错误则返回NULL。这个函数主要根据命令行解析来进行I2C初始化。

3、fini函数清理驱动程序并释放与给定句柄关联的所有内存。该函数的原型是:

void fini(void *hdl);  

hdl init函数返回的句柄。

4、发送函数启动主发送。通信完成时将发送一个可选事件(可以释放数据缓冲区)。如果此函数失败,则未启动任何通信。

i2c_status_t send(
               void *hdl,
               void *buf,
               unsigned int len,
               unsigned int stop );

hdl :init函数返回的句柄;

buf:指向要发送的数据缓冲区的指针;

len:要发送的数据的长度(以字节为单位);

stop:如果这是非零的,函数将在发送完成时设置停止条件;

返回状态为:

I2C_STATUS_DONE:传输完成,并且没有错误。

I2C_STATUS_ERROR:传输错误

I2C_STATUS_NACK:没有ACK

I2C_STATUS_ARBL:失去了仲裁。

I2C_STATUS_BUSY:传输超时

I2C_STATUS_ABORT:传输终止

5、recv函数启动主接收。传输完成时将发送一个可选事件(可以使用数据缓冲区)。如果此函数失败,则未启动任何传输。

该函数的原型是:

i2c_status_t recv(
               void *hdl,
               void *buf,
               unsigned int len,
               unsigned int stop );

hdl :init函数返回的句柄;

buf:指向要接收的数据缓冲区的指针;

len:要接收的数据的长度(以字节为单位);

stop:如果这是非零的,函数将在发送完成时设置停止条件;

返回状态为:

I2C_STATUS_DONE:传输完成,并且没有错误。

I2C_STATUS_ERROR:传输错误

I2C_STATUS_NACK:没有ACK

I2C_STATUS_ARBL:失去了仲裁。

I2C_STATUS_BUSY:传输超时

I2C_STATUS_ABORT:传输终止

6、中止功能迫使主程序释放总线。当停止条件被发送时,它返回。该函数的原型是:

int abort(
      void *hdl,
      int rcvid );

hdl:  init函数返回的句柄。

rcvid:客户端的接收ID。

7、set_slave_addr函数指定目标从地址。该函数的原型是:

int set_slave_addr(
      void *hdl,
      unsigned int addr,
      i2c_addrfmt_t fmt );

hdl:  init函数返回的句柄。

addr: 目标从地址。

fmt:地址的格式; I2C_ADDRFMT_7BIT 和I2C_ADDRFMT_10BIT

8、set_bus_speed函数指定总线速度。如果请求的总线速度无效,该函数将返回一个失败,并保持总线速度不变。该函数的原型是:

int set_bus_speed(
      void *hdl,
      unsigned int speed,
      unsigned int *ospeed );

hdl

init函数返回的句柄。

speed

总线的速度。

ospeed

NULL或指向函数应该存储实际总线速度的位置的指针。

9、driver_info函数返回有关驱动程序的信息。该函数的原型是:

int driver_info(
      void *hdl,
      i2c_driver_info_t *info );

hdl

init函数返回的句柄

info

一个指向i2c_driver_info_t结构的指针,函数应该在该结构中存储信息:

typedef struct {

uint32_t    speed_mode;

uint32_t    addr_mode;

uint32_t    reserved[2];

} i2c_driver_info_t;

10.ctl函数处理一个驱动程序特定的devctl()命令。该函数的原型是:

int ctl(

void *hdl,

int cmd,

void *msg,

int msglen,

int *nbytes,

int *info );

hdlinit函数返回的句柄;

cmd:设备命令;

msg一个指向消息缓冲区的指针。该函数可以更改缓冲区的内容;

msglen:消息缓冲区的长度,以字节为单位;

nbytes:返回的字节数。这个不能大于msglen;

Info指向函数可以存储devctl()返回状态信息的位置指针;

2、硬件访问接口

资源管理器接口使用此函数访问特定于硬件的函数。它必须得到执行;

int i2c_master_getfuncs(i2c_master_funcs_t *funcs, int tabsize);

硬件访问接口流程如下:

    #include <hw/i2c.h>
    i2c_master_funcs_t  masterf;
    i2c_libversion_t    version;
    i2c_status_t        status;
    void *hdl;
    i2c_master_getfuncs(&masterf, sizeof(masterf));//初始化硬件接口
    masterf.version_info(&version);
    if ((version.major != I2CLIB_VERSION_MAJOR) ||
        (version.minor > I2CLIB_VERSION_MINOR))
    {
        /* error */
        ...
    }
    hdl = masterf.init(...); //调用初始化函数
    masterf.set_bus_speed(hdl, ...); //设置总线速度
    masterf.set_slave_addr(hdl, ...); //设置从地址
    status = masterf.send(hdl, ...);//发送数据
    if (status != I2C_STATUS_DONE) {
        /* error */
        if (!(status & I2C_STATUS_DONE))
            masterf.abort(hdl);
    }
    status = masterf.recv(hdl, ...);//接收数据
    if (status != I2C_STATUS_DONE) {
        /* error */
        ...
    }
    masterf.fini(hdl);//完成I2C传输后,清理驱动程序并释放与给定句柄关联的所有内存

3、共享库的接口

当I2C主设备专用于单个应用程序使用时,可以将硬件接口代码编译为库并将其链接到应用程序。

为了提高代码的可移植性,应用程序应该调用i2c_master_getfuncs()来访问特定于硬件的函数。通过功能表访问硬件库,应用程序更容易加载和管理多个硬件库。

资源管理器接口以类似的方式使用硬件库。

4、资源管理器设计

资源管理器层实现为静态链接到硬件库的库,提供了一个单线程管理器,libi2c-master。

在启动时,resmgr层执行以下操作:

i2c_master_getfuncs(&masterf)
masterf.init()
masterf.set_bus_speed()

然后,资源管理器让自己在后台运行,下面是资源管理器处理这些devctl()命令:

  • DCMD_I2C_DRIVER_INFO calls masterf.driver_info().
  • DCMD_I2C_SET_BUS_SPEED and DCMD_I2C_SET_SLAVE_ADDR only update the state of the current connection.
  • DCMD_I2C_SEND, DCMD_I2C_RECV, DCMD_I2C_SENDRECV, DCMD_I2C_MASTER_SEND, and DCMD_I2C_MASTER_RECV result in the following:
  • if (bus_speed has changed)
  • masterf.set_bus_speed()
  • masterf.set_slave_address()
  • masterf.send() or masterf.recv()

资源管理器线程一直占用,直到传输完成并回复客户端,可以通过向资源管理器发送SIGTERM来终止它。

5、实例程序分析

1、首先在startup 对I2C进行硬件初始化,包括基地址、中断向量、时钟等等,这部分和硬件相关。

2、首先驱动从build 文件里进行加载,在dev生成设备节点,/dev/i2c1 等等

3、编写I2C驱动,其中init.c解析build加载参数,如I2C基地址地址、 中断号等等,并在lib.c 对所有的I2C驱动进行封装,调用i2c_master_getfuncs函数实现。

QNX----I2C驱动框架相关推荐

  1. Linux I2C驱动框架(超详细)

    Linux I2C驱动框架 文章目录 Linux I2C驱动框架 一.几个重要的对象 1.I2C总线 2.I2C驱动 3.I2C设备 4.I2C设配器 小结 二.内核源码分析 1.注册I2C驱动 2. ...

  2. 【linux驱动开发】i2c驱动框架之温湿度传感器htu21d

    文章目录 一.linux内核i2c驱动框架 1.1 i2c适配器 1.2 i2c设备驱动 1.3 i2c设备驱动匹配过程 二.温湿度传感器htu21d 三.htu21d设备驱动编写 3.1 修改设备树 ...

  3. I2C驱动框架分析(3):DW_I2C驱动分析

    I2C驱动框架分析(1):I2C重要概念与数据结构 I2C驱动框架分析(2):I2C框架源码分析 I2C驱动框架分析(3):DW_I2C驱动分析 第三章:DW_I2C驱动 其驱动文件在drivers/ ...

  4. Linux i2c驱动框架分析 (二)

    Linux i2c驱动框架分析 (一) Linux i2c驱动框架分析 (二) Linux i2c驱动框架分析 (三) 通用i2c设备驱动分析 i2c core i2c核心(drivers/i2c/i ...

  5. linux i2c核心,总线与设备驱动,Linux2.6.37 I2C驱动框架分析(一)

    最近工作中又使用到了I2C,所以借S3C2440开发板GT2440为硬件平台温习一遍I2C驱动体系. linux内核中IIC驱动的体系框架 linux内核中IIC部分驱动代码位于:/drivers/i ...

  6. Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析 (iic驱动框架,i2c驱动框架)...

    转载于 : http://blog.csdn.net/zqixiao_09/article/details/50917655 关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸 ...

  7. i.MX6ULL驱动开发 | 11 - Linux I2C 驱动框架

    Linux I2C 主机设备驱动分为两部分: I2C总线控制器驱动:SOC的I2C控制器外设驱动 I2C设备驱动:基于I2C总线控制器驱动编写,针对具体的I2C从机设备 一.I2C总线控制器驱动 基于 ...

  8. Linux下I2C驱动框架全面解析

    I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...

  9. Linux的 i2c 驱动框架分析

    1.基本概念 总线设备驱动模型,是Linux 内核的一个基础,基本理论可以说按照大企业的分工原则,每个人只要负责自己的事情,向其他部门给出标准的接口调用,后勤部就负责后勤工作,厨房有可能跟后勤部产生工 ...

  10. 05-SA8155 QNX I2C框架及代码分析

    1. 描述 本文主要描述QNX I2C Drvier的相关内容,并以SA8155处理器为例讲解. I2C 是经常用到的一种总线协议,它只占用两个IO口资源,分别是SCL时钟信号线与SDA数据线, 两根 ...

最新文章

  1. 韩国为三星芯片数据硬刚美国,后者此前警告:不交就等着,后手有的是
  2. mysql通用查询日志_MySQL通用查询日志(GeneralQueryLog)_MySQL
  3. C++操作SQLite数据库
  4. 类与接口(二)java的四种内部类详解
  5. html页面跨域提交数据,前端跨域的整理
  6. Adobe Flash Player 10 插件无法注册
  7. 2009年4月21日 博客更新公告,敬请关注!
  8. java 反射机制及其应用
  9. 「leetcode」235. 二叉搜索树的最近公共祖先:【递归】【迭代】详解
  10. 来几个有趣的Linux指令 (转自Chinaitlab)
  11. Oracle 数据库生成2021年节假日表SQL
  12. 嵌入式开发好用的工具集合
  13. allegro如何编辑铜皮
  14. 用v-modle做一个简单的计算器
  15. 学习系列之天眼查爬虫
  16. AutoCAD2018打印eps文件
  17. [乐意黎原创] 最高学历与最高学位
  18. 上半年要完成的博客51
  19. 计算机应用编程师职业指导,计算机应用个人职业生涯规划书.doc
  20. [转]中国将建口径8米巨型太阳望远镜

热门文章

  1. oracle关闭的四种模式
  2. 中国高等职业院校网球锦标赛
  3. 2019计算机考研普通院校,2019计算机考研:明确自己与目标院校的差距
  4. mysql查询不重复数据
  5. SAP你需要了解的那些事
  6. mt6765和骁龙665哪个好_联发科P60和骁龙636哪个好?骁龙636与联发科P60区别对比详细评测...
  7. Vue中自定义标签及其使用
  8. OpenMP-CODE
  9. 闭式冷却塔的防冻问题
  10. 2017年软上半年软考网络工程师级别考前冲刺之第二天-朱小平-专题视频课程