SylixOS热插拔子系统分析(二)
来源:互联网 发布:嵌入式linux教学视频 编辑:程序博客网 时间:2024/05/22 13:16
1. 系统与驱动
热插拔子系统中,系统与驱动层的交互分为热插拔事件和循环检测。热插拔事件是针对设备能够产生热插拔中断通知的情况,SylixOS可以将通知以异步的方式来处理;而循环检测是设备不能产生一个热插拔中断通知的情况,需要轮询检测某些事件标志,来获取设备的插入或拔出状态。
1.1 热插拔事件
能够产生热插拔事件的设备,在驱动层调用API_HotplugEvent函数即可,SylixOS热插拔系统中对热插拔事件处理是通过JobQueue来实现,SylixOS定义工作队列如下:
static LW_JOB_QUEUE _G_jobqHotplug;static LW_JOB_MSG _G_jobmsgHotplug[LW_CFG_HOTPLUG_MAX_MSGS];热插拔事件通过API_HotplugEvent函数中向工作队列中添加工作:
#include <SylixOS.h>INT API_HotplugEvent (VOIDFUNCPTR pfunc, PVOID pvArg0, PVOID pvArg1, PVOID pvArg2, PVOID pvArg3, PVOID pvArg4, PVOID pvArg5){ …… if (_jobQueueAdd( &_G_jobqHotplug, pfunc, pvArg0, pvArg1, pvArg2, pvArg3, pvArg4, pvArg5)) { _ErrorHandle(ERROR_EXCE_LOST); return (PX_ERROR); } ……}
函数API_HotplugEvent原型分析:
- 函数成功返回ERROR_NONE,失败返回PX_ERROE;
- 参数pfunc表示函数指针;
- 参数pvArg0 ~ pvArg5为函数参数。
设备驱动创建时,驱动层调用API_HotplugEvent函数完成工作队列的添加,热插拔内核线程在检测该工作队列时会检测到工作,并调用其中的执行函数,向应用层提供热插拔消息。
1.2 循环检测
针对不能产生一个热插拔中断事件的设备,驱动层可调用API_HotplugPollAdd函数将驱动中的轮询检测函数来添加到系统中,这样系统会在一个确定的时间间隔轮询检测设备状态。
轮询检测节点结构如下,函数指针和函数参数两个成员是驱动设计者所要关心的,也就是驱动的轮询检测函数,全局链表头_G_plineHotplugPoll连接所有的热插拔节点。
typedef struct { LW_LIST_LINE HPPN_lineManage; /* 节点链表 */ VOIDFUNCPTR HPPN_pfunc; /* 函数指针 */ PVOID HPPN_pvArg; /* 函数参数 */ LW_RESOURCE_RAW HPPN_resraw; /* 资源管理节点 */} LW_HOTPLUG_POLLNODE;SylixOS下热插拔驱动支持提供API_HotplugPollAdd接口添加轮询检测函数,如下:
#include <SylixOS.h>INT API_HotplugPollAdd (VOIDFUNCPTR pfunc, PVOID pvArg){ …… phppn->HPPN_pfunc = pfunc; phppn->HPPN_pvArg = pvArg; ……}
API_HotplugPollAdd函数原型分析:
- 函数成功返回ERROR_NONE,失败返回PX_ERROR;
- 参数pfunc表示函数指针;
- 参数pvArg为函数参数。
1.3 内核线程
SylixOS下热插拔子系统中会创建“t_hotplug”内核线程,内核线程代码实现如下:
#include <SylixOS.h>static VOID _hotplugThread (VOID){ …… for (;;) { ulError = _jobQueueExec(&_G_jobqHotplug, LW_HOTPLUG_SEC * LW_TICK_HZ); if (ulError) { …… for (plineTemp = _G_plineHotplugPoll; plineTemp != LW_NULL; plineTemp = _list_line_get_next(plineTemp)) { if (phppn->HPPN_pfunc) { phppn->HPPN_pfunc(phppn->HPPN_pvArg); } } …… } }}
“t_hotplug”内核线程每隔“LW_HOTPLUG_SEC * LW_TICK_HZ”时间间隔会遍历执行工作队列中的工作,若工作队列中没有工作则内核线程遍历循环检测链表,检测到节点则调用其中的循环检测函数。
2. 系统与应用层
系统与应用层的交互是系统将热插拔消息通知给应用层,这样用户层可以感知到设备的插入和拔出。应用层通过调用函数API_HotplugEventMessage即可将热插拔消息通知出去,然后应用层通过读设备“/dev/hotplug”即可获得热插拔消息。
实现原理分两部分,一是热插拔设备部分,二是消息传递部分。
2.1 热插拔设备
热插拔设备的创建涉及到SylixOS设备驱动的知识,这里不再详述,在之后的设备驱动文章中将做详细介绍。
2.2 消息传递
消息传递部分调用HotplugEventMessage函数将热插拔消息存放在设备缓存区中,代码片段如下:
#include <SylixOS.h>INT API_HotplugEventMessage (INT iMsg, BOOL bInsert, CPCHAR pcPath, UINT32 uiArg0, UINT32 uiArg1, UINT32 uiArg2, UINT32 uiArg3){ ……_hotplugDevPutMsg(iMsg, ucBuffer, i); ……}
函数API_HotplugEventMessage原型分析:
- 函数成功返回ERROR_NONE,失败返回PX_ERROR;
- 参数iMsg为消息号;
- 参数bInsert表示是否为插入,否则为拔出;
- 参数pcPath表示设备路径或名称;
- 参数uiArg0 ~ uiArg3为附加参数。
函数HotplugEventMessage根据SylixOS定义的热插拔消息格式,将传入参数封装为热插拔消息,并调用_hotplugDevPutMsg函数将热插拔消息保存至缓存区。
- SylixOS热插拔子系统分析(二)
- SylixOS子系统原理--热插拔子系统
- SylixOS DMA子系统之一
- SylixOS日志子系统简介
- Linux输入子系统分析(二)
- Linux输入子系统分析(二)
- input子系统分析二
- linux input 子系统分析 二
- linux input 子系统分析 二
- linux input 子系统分析 二
- linux input 子系统分析 二
- Linux输入子系统分析二
- Linux I2C子系统分析之(二) ----- 概述
- linux内核I2C驱动子系统分析(二)
- input 子系统的分析与学习(二)
- Linux SCSI子系统分析(二)发现target的过程
- SylixOS 调试方法详解(二)——SylixOS 代码覆盖率检查
- gpio子系统和pinctrl子系统(二)
- pdfbox简明教程
- Hdu 6185 Covering【递推+矩阵快速幂】
- hive-hadoop 常用命令
- 【qt】QT中打开文件不识别中文路径的解决办法
- shiro中 realm中方法何时被调用
- SylixOS热插拔子系统分析(二)
- Oracle 查询库中所有表名、字段名、字段名说明,查询表的数据条数、表名、中文表名
- Linux 磁盘管理命令
- 1054. 求平均值 (20)
- JAVA中循环删除list中元素(移除list两时间范围外的元素)
- React16 中的错误处理
- Android 打开TCPIP调试
- C中的typedef
- Linux 修改IP地址DNS服务器等网络设置