汽车电子 CIS 学习(一) 之 UART PORT

  • 二、车机目录介绍
  • 三、port_driver、proto_driver、vdev_driver注册代码分析
    • 3.1 cis_register_port_driver 注册代码分析
    • 3.2 cis_register_proto_driver 注册代码分析
    • 3.3 cis_attach 绑定代码分析
    • 3.4 cis_register_vdev_driver 注册代码分析
    • 3.5 cis_attach 触发绑定的时间

在前文 《汽车电子 CIS 学习(一) 之 四大结构体》 中,主要是对车机CIS 中的四大结构体进行了在概的描述。

二、车机目录介绍

如下是CIS 代码的目录结构,

  1. 一级目录 /cis/
    在第一级目录中,主要是CIS的架构实现的通用代码,
    主要代码为, cis_core.c , cis_log.c , cis_uart.c , cis_protp,cis_common_proto.c

  2. 二级目录 /cis/vdev
    主要是实现具体的通用功能 cis_pa.c,cis_key.c,cis_can.c 等。

  3. 二级目录 /cis/10001h
    该目录主要是包括了具体车厂的实现代码。

三、port_driver、proto_driver、vdev_driver注册代码分析

3.1 cis_register_port_driver 注册代码分析

在 port 注册函数中,主要就是将 port_st 的结构体信息赋值给 cis_port_st[index] 全局数组。
后续使用port的时候,就根据该全局数组来进行遍历。

/* port register */
int cis_register_port_driver(struct cis_port_struct *port_st)
{index = CIS_ARRAY_INDEX_ALIGN(port_st->port_type);cis_port_st[index].port_type = port_st->port_type;cis_port_st[index].port_attr = port_st->port_attr;cis_port_st[index].port_drv  = port_st->port_drv;
}

3.2 cis_register_proto_driver 注册代码分析

如同前面的 port 数组一样,proto 也是上将结构体信息保存在 cis_proto_st[index] 全局数组中。

/* protocol register */
int cis_register_proto_driver(struct cis_proto_struct *proto_st)
{index = CIS_ARRAY_INDEX_ALIGN(proto_st->proto_type);cis_proto_st[index].proto_type = proto_st->proto_type;cis_proto_st[index].proto_fmt  = proto_st->proto_fmt;cis_proto_st[index].proto_drv  = proto_st->proto_drv;cis_proto_st[index].proto_send = proto_st->proto_send;
}

3.3 cis_attach 绑定代码分析

attach 的目的,就是将 port 程 proto 关连起来。
我们来看下attach 的代码:
在cis_attach_param 包括,我们当前要注册的 port 和 proto 的相关信息。

//绑定端口和协议
cis_attach(&cis_attach_param);struct cis_attach_struct cis_attach_param = {.port_id = CIS_PORT_ID_UART0,          // 1.type.port_type = CIS_PORT_TYPE_UART,  // 1.type.proto_type = CIS_PROTO_TYPE_SGM, // 1.port_attr = &cis_port_param,------>+  struct cis_port_attribute cis_port_param = {+     .name = "/dev/ttyHSL2",      // uart 2+     .termios = {+         .c_cflag = B38400,     // rate 38400+     },+    };+<-------};

绑定端口和协议的目的就是,
在全局数组 cis_attach_st[index] 中将 端口port 和协议 proto的属性和方法关连起来,
这样通过 索引 index 就能找到对应的 port 和 proto 所有的信息。

在cis_attach 函数中:
(1) 首先解析到分绑定的 port 和 proto 各自的 index。
(2) 判断该cis_attach_st 全局数组中该 index 的对应的状态,如果已经处于绑定状态则直接返回。
(3) 接下来,经过一系列的检查,检测传递的参数是否正确(包括 type,attr, port_drv,proto_fmt,proto_drv 等等)
(4) 将port 和 proto 的放在 cis_attach_st[index] 全局数组中。
(5)更port 端口的attr 到 cis_attach_st 全局数组中。
(6)调用 proto 的start 函数,正式开始进入正事,在start 函数中会创建一个 kthread线程。
(7)更新全局数组的绑定状态 cis_attach_st[id_index].state = CIS_ATTACH_DONE;

int cis_attach(struct cis_attach_struct *attach_st)
{id_index = CIS_ARRAY_INDEX_ALIGN(attach_st->port_id);  // val - 1 = 1 - 1 =0port_index = CIS_ARRAY_INDEX_ALIGN(attach_st->type.port_type);proto_index = CIS_ARRAY_INDEX_ALIGN(attach_st->type.proto_type);//#5.3 如果已经绑定过了,则直接返回if (cis_attach_st[id_index].state == CIS_ATTACH_DONE)return CIS_OK;//#5.4 判断 port_type 是否是支持的类型:  UART | USBif ((cis_port_st[port_index].port_type == CIS_PORT_TYPE_UART) || (cis_port_st[port_index].port_type == CIS_PORT_TYPE_USB)) {// 判断该类型的属性 (端口号 及 波特率)if (!cis_port_st[port_index].port_attr) {printk(KERN_ERR"ERR:%s port_attr is NULL!\n", __func__);return CIS_ERR;}}//#5.5 判断该type 的驱动函数if (!cis_port_st[port_index].port_drv) {printk(KERN_ERR"ERR:%s port_drv is NULL!\n",__func__);return CIS_ERR;}/* proto */if (!cis_proto_st[proto_index].proto_fmt) {printk(KERN_ERR"ERR:%s proto_fmt is NULL!\n",__func__);return CIS_ERR;}if (!cis_proto_st[proto_index].proto_drv) {printk(KERN_ERR"ERR:%s proto_drv is NULL!\n",__func__);return CIS_ERR;}if (!cis_proto_st[proto_index].proto_send) {printk(KERN_ERR"ERR:%s proto_send is NULL!\n",__func__);return CIS_ERR;}/* need to handle again *///#5.6 将所有的参数 都统一存放在 cis_attach_st[] 数组中// port口 ID / port口 TYPE / 对应的协议 proto TYPEcis_attach_st[id_index].port_id         = attach_st->port_id;cis_attach_st[id_index].type.port_type  = attach_st->type.port_type;cis_attach_st[id_index].type.proto_type = attach_st->type.proto_type;// port口 attr / 对应的port口的驱动函数cis_attach_st[id_index].port_attr         = cis_port_st[port_index].port_attr;cis_attach_st[id_index].port_drv       = cis_port_st[port_index].port_drv;// proteo协议的格式 / 协议的驱动 / 协议 send 函数cis_attach_st[id_index].proto_fmt        = cis_proto_st[proto_index].proto_fmt;cis_attach_st[id_index].proto_drv        = cis_proto_st[proto_index].proto_drv;cis_attach_st[id_index].vdev_drv.send    = cis_proto_st[proto_index].proto_send;//#5.7 更新attr属性if ((cis_port_st[port_index].port_type == CIS_PORT_TYPE_UART) || (cis_port_st[port_index].port_type == CIS_PORT_TYPE_USB)) {cis_update_port_attribute(attach_st);------>index = CIS_ARRAY_INDEX_ALIGN(attach_st->port_id);//#5.8 获得波特率 及 对应的name//.c_cflag = B38400cis_attach_st[index].port_attr->termios.c_cflag |= attach_st->port_attr->termios.c_cflag; //.name = "/dev/ttyHSL2"memcpy(cis_attach_st[index].port_attr->name, attach_st->port_attr->name, strlen(attach_st->port_attr->name));<-----}if (!cis_attach_st[id_index].proto_drv->start) {printk(KERN_ERR"ERR:%s proto_start is NULL!\n", __func__);return CIS_ERR;}//#5.8 start attach protocis_attach_st[id_index].proto_drv->start(&cis_attach_st[id_index]);//#5.9 更新状态为 CIS_ATTACH_DONEcis_attach_st[id_index].state = CIS_ATTACH_DONE;return CIS_OK;
}

3.4 cis_register_vdev_driver 注册代码分析

前面讲了,虚拟设备其实就是 搭载在 port 端口上 且 使用 该proto 协议的 设备。
因些,注册虚拟设备的前提是 已经有绑定成功的 port 和 proto 。

如下,注册代码中,注册虚拟函数主要就是,
将虚拟设备的 类型vdev_type 和 接收函数vdev_recv 这两个信息 和 cis_attach_st 绑定起来。

这样,当协议proto 的recv 函数接收并解析到数据后,就可能通过 该vdev_recv 函数来将数据传递给对应的 虚拟函数 进行处理。

//# 注册虚拟函数, 将操作函数赋值给cis_attach_st.vdev_drv
/*  virtual device register */
int cis_register_vdev_driver(struct cis_vdev_struct *vdev_st)
{id_index = CIS_ARRAY_INDEX_ALIGN(vdev_st->port_id);vdev_index = CIS_ARRAY_INDEX_ALIGN(vdev_st->vdev_type);cis_attach_st[id_index].type.vdev_type[vdev_index] = vdev_st->vdev_type;cis_attach_st[id_index].vdev_drv.recv[vdev_index]  = vdev_st->vdev_recv;
}

3.5 cis_attach 触发绑定的时间

目前代码中,cis_attach 是在 cis_init_task 中调用的:

static DECLARE_WORK(cis_init_work, cis_init_task);static void cis_init_task(struct work_struct *work)
{cis_attach(&cis_attach_param);

cis_init_task 是一个work, 名字为 cis_init_work.

接下来,我们来看下 cis_init_work调用的场景。

static int __init cis_io_init(void)
{if (cis_proc_create())return CIS_ERR;schedule_work(&cis_init_work);return CIS_OK;
}
late_initcall(cis_io_init);

可以看出 触发绑定的时间为 系统开机的过程,初始化时才会触发的。

汽车电子 CIS 学习(二) 之port_driver、proto_driver、vdev_driver注册代码分析相关推荐

  1. 微信公众平台开发(二) 微信公众平台示例代码分析

    http://www.cnblogs.com/mchina/archive/2013/06/07/3120592.html 微信公众平台开发(二) 微信公众平台示例代码分析 一.摘要 微信公众平台提供 ...

  2. NLP-生成模型-2017-Transformer(二):Transformer各模块代码分析

    一.WordEmbedding层模块(文本嵌入层) Embedding Layer(文本嵌入层)的作用:无论是源文本嵌入还是目标文本嵌入,都是为了将文本中词汇的数字表示转变为向量表示, 由一维转为多维 ...

  3. PCIe学习笔记之MSI/MSI-x中断及代码分析

    本文基于linux 5.7.0, 平台是arm64 1. MSI/MSI-X概述 PCIe有三种中断,分别为INTx中断,MSI中断,MSI-X中断,其中INTx是可选的,MSI/MSI-X是必须实现 ...

  4. 微信公众平台开发(PHP)(二) 微信公众平台示例代码分析

    一.摘要 微信公众平台提供了一个简单的php示例代码,在做进一步开发之前,我们有必要将其详细了解一下. 二.获取代码 微信官网:http://mp.weixin.qq.com/mpres/htmled ...

  5. 学习笔记-第十四章 恶意代码分析实战

    第十四章 恶意代码的网络特征 1.网络应对措施. 网络行为的基本属性包括IP地址,TCP端口,以及流量内容等,网络和安全 设备可以利用它们,来提供网络应对措施.根据IP地址和端口,防火墙和路由器可以限 ...

  6. linux v4l2系统详解,Linux摄像头驱动学习之:(一)V4L2_框架分析

    这段时间开始搞安卓camera底层驱动了,把以前的的Linux视频驱动回顾一下,本篇主要概述一下vfl2(video for linux 2). 一. V4L2框架: video for linux ...

  7. Mybatis底层原理学习(二):从源码角度分析一次查询操作过程

    在阅读这篇文章之前,建议先阅读一下我之前写的两篇文章,对理解这篇文章很有帮助,特别是Mybatis新手: 写给mybatis小白的入门指南 mybatis底层原理学习(一):SqlSessionFac ...

  8. C#多线程学习(二) 如何操纵一个线程

    C#多线程学习(二) 如何操纵一个线程 原文链接:http://kb.cnblogs.com/page/42529/ [1] C#多线程学习(二) 如何操纵一个线程 [2] C#多线程学习(二) 如何 ...

  9. spring security 学习二

    spring security 学习二 doc:https://docs.spring.io/spring-security/site/docs/ 基于表单的认证(个性化认证流程): 一.自定义登录页 ...

最新文章

  1. 推荐15个国外使用 CSS3 制作的漂亮网站
  2. 对象包装器和自动装箱
  3. 干货|亲测有效的N倍学习效果笔记法
  4. python的os模块使用_Python之os模块的常见用法
  5. Python基础——6面向对象编程
  6. springboot,hibernate,exception no session 问题解决
  7. base,override,virtual
  8. This project references NuGet package(s) that are missing on this computer
  9. GPS模拟器与Windows Mobile模拟器
  10. 计算机科学cs50_世界顶尖CS大学提供500门免费计算机科学课程
  11. ddr4 dqs 频率_你好,请问你知道DDR3中是DQS是什么意思吗
  12. cad卸载_想重新安装CAD提示已经安装?不会卸载?进来教你卸载CAD
  13. [原创]修改jquery.slideBox.js插件,自定义部分事件
  14. 教程:QuickTime 录屏的同时录制电脑中播放的声音,播放的歌曲等
  15. PermissionError: [Errno 1] Operation not permitted: '../middle_result/df_cleaned.csv'
  16. Android Retrofit的学习
  17. 仿照京东导航条html+css
  18. 2022-2028年中国棉花采摘机行业市场调查研究及投资策略研究报告
  19. 重庆航天职业技术学院计算机宿舍,2019年重庆航天职业技术学院寝室宿舍条件与学校食堂环境图片...
  20. XMLSchema 注解

热门文章

  1. 罗技MX Keys从蓝牙连接切换为优联(无线接收器)连接
  2. 国内有哪些大数据公司?
  3. stm32 IOT_嵌入式云IOT技术圈公众号精选文章专题汇总
  4. 今天手机(ME525 Androdi2.2)神州行GPRS移动上网终于设置好了!!!
  5. IFTTT在开发环境中使用Docker的经验
  6. Windows 7 下安装TensorFlow
  7. Scanner的简单用法
  8. Java解压文件的一些坑及经验分享(MALFORMED异常)
  9. phpstudy mysql中文乱码_MySQL_MySQL中文乱码问题的解决,转自:http://www.phpchina.cn/viewarti - phpStudy...
  10. 中国信通院推出了一个“APP签名服务系统,可防篡改、可追溯、第三方认证“的初步了解