SylixOS热插拔子系统分析(二)

本文介绍SylixOS操作系统中的热插拔机制,包括热插拔事件处理、循环检测及内核线程的工作原理。此外,还讲解了系统如何与驱动及应用层交互,使用户能感知设备的插入与拔出。

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函数将热插拔消息保存至缓存区。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值