文档章节

SylixOS虚拟文件设备浅析

 星域之旅
发布于 2017/06/15 09:25
字数 1350
阅读 6
收藏 0

    目录

1.虚拟设备文件概述    1

2.虚拟设备文件eventfd    1

2.1    虚拟设备文件eventfd概述    1

2.2    打开虚拟设备文件eventfd    1

2.3    读取事件文件    3

2.4    写事件文件    3

3.参考文献    4

 

  1. 虚拟设备文件概述

    Linux内核自2.6.22版本开始逐步增加了三个虚拟设备文件:eventfd、timerfd、signalfd。这三个文件让应用程序可以通过标准I/O操作的方式代替传统调用API的方式来使用事件(信号量)、定时器和信号资源,这带来的最大好处是应用程序可以通过使用select(或poll、epoll)同时监听多个此类文件(或此类文件与其他文件),将对多个事件的异步并行处理方便地转化为同步串行处理,这在许多应用中非常有用。SylixOS完全兼容这三个虚拟设备文件,并且增加了一个hstimerfd,用于高精度定时器。

  2. 虚拟设备文件eventfd

  3. 虚拟设备文件eventfd概述

  4. SylixOS中的虚拟设备文件eventfd主要用于线程间的事件通信,其本质上是内核为应用程序提供的信号量。它与POSIX信号量相比的优势是,eventfd在内核中是以文件形式存在的,可用于select/epoll/poll循环中,因此可以实现异步的信号量,避免了消费者在资源不可用时的阻塞。

    event表示它可用来作事件通知(异步),fd表示它是一个"文件"。

  5. 打开虚拟设备文件eventfd

    如果用户想要使用eventfd的相关API函数,需要满足如下条件:

    1.当前允许使用系统的设备管理功能(LW_CFG_DEVICE_EN的参数值大于零);

    2.已在系统中加入eventfd功能模块(LW_CFG_EVENTFD_EN的参数值大于零);

    3.调用函数API_EventfdDrvInstall安装eventfd设备驱动程序,具体实现如程序清单 2-1所示;

    程序清单 2-1安装设备驱动

    LW_API

    INTAPI_EventfdDrvInstall (VOID)

    {

    if (_G_iEvtfdDrvNum <= 0) {

    _G_iEvtfdDrvNum =iosDrvInstall(LW_NULL,

    LW_NULL,

    _evtfdOpen,

    _evtfdClose,

    _evtfdRead,

    _evtfdWrite,

    _evtfdIoctl);

    DRIVER_LICENSE(_G_iEvtfdDrvNum,"GPL->Ver 2.0");

    DRIVER_AUTHOR(_G_iEvtfdDrvNum,"Han.hui");

    DRIVER_DESCRIPTION(_G_iEvtfdDrvNum,"eventfd driver.");

    }

    if (_G_hEvtfdSelMutex ==LW_OBJECT_HANDLE_INVALID) {

    _G_hEvtfdSelMutex =API_SemaphoreMCreate("evtfdsel_lock",LW_PRIO_DEF_CEILING,

    LW_OPTION_WAIT_PRIORITY |LW_OPTION_DELETE_SAFE |

    LW_OPTION_INHERIT_PRIORITY |LW_OPTION_OBJECT_GLOBAL,

    LW_NULL);

    }

    return ((_G_iEvtfdDrvNum == (PX_ERROR)) ? (PX_ERROR) : (ERROR_NONE));

    }

     

    4.调用函数API_EventfdDevCreate安装eventfd设备,具体实现如程序清单 2-2所示。

    程序清单 2-2安装设备

    LW_API

    INTAPI_EventfdDevCreate (VOID)

    {

    if (_G_iEvtfdDrvNum <= 0) {

    _DebugHandle(__ERRORMESSAGE_LEVEL,"no driver.\r\n");

    _ErrorHandle(ERROR_IO_NO_DRIVER);

    return (PX_ERROR);

    }

    if (iosDevAddEx(&_G_evtfddev.ED_devhdrHdr,LW_EVTFD_DEV_PATH,

    _G_iEvtfdDrvNum,DT_CHR) != ERROR_NONE) {

    return (PX_ERROR);

    }

    return (ERROR_NONE);

    }

     

    打开虚拟设备文件eventfd,在该函数中initval参数表示事件的初始状态,为0则表示当前没有任何事件产生,参数flags为该事件文件的操作选项。

    flags标志位有如下三种:

    1.EFD_SEMAPHORE的含义为将事件按照计数信号量来操作;

    2.EFD_NONBLOCK 类似于使用O_NONBLOCK标志来设置文件描述符;

    3.EFD_CLOEXEC 类似open以O_CLOEXEC标志打开,O_CLOEXEC应该表示执行exec()时,之前通过open()打开的文件描述符会自动关闭测试,在open()之后,调用exec(),在新的进程中检测描述符是否已经关闭,具体实现如程序清单 23所示。

    程序清单 2-3打开eventfd文件

    LW_API

    inteventfd (unsignedintinitval,intflags)

    {

    INTiFd;

    PLW_EVTFD_FILEpevtfdfil;

    flags &= (EFD_SEMAPHORE |EFD_CLOEXEC | EFD_NONBLOCK);

    iFd =open(LW_EVTFD_DEV_PATH,O_RDWR | flags);

    if (iFd >= 0) {

    pevtfdfil = (PLW_EVTFD_FILE)API_IosFdValue(iFd);

    pevtfdfil->EF_u64Counter = (UINT64)initval;

    if (pevtfdfil->EF_u64Counter) {

    API_SemaphoreBPost(pevtfdfil->EF_ulReadLock);

    }

    }

    return (iFd);

    }

     

  6. 读取事件文件

    用户在使用虚拟设备文件eventfd时,如果需要读取事件文件或者等待事件的发送则需要用到函数eventfd_read,当没有事件需要调用并且没有使用参数EFD_SEMAPHORE时,该函数将会阻塞。具体实现如程序清单 24所示。

    程序清单 2-4读取事件文件

    LW_API

    inteventfd_read (intfd,eventfd_t *value)

    {

    return (read(fd,value, sizeof(eventfd_t)) !=sizeof(eventfd_t) ?PX_ERROR : ERROR_NONE);

    }

     

    需要用户注意的地方是如果使用的eventfd函数的参数flags包含了EFD_SEMAPHORE时,其含义为将事件按照计数信号量来操作。即如果当前已经产生了多个事件,每一次读取只会包含一个事件,该文件内部的事件计数器只减一,value里面的内容为1。当没有使用EFD_SEMAPHORE时,一次读取所有的事件,value里面的内容即为读取的事件数量,内部的事件计数器归零。两种方式可满足应用程序在不同场景的需求。

  7. 写事件文件

    当用户在使用虚拟设备文件eventfd时,如果需要写事件文件或者发送事件则需要用到函数eventfd_write,当内部事件计数器达到最大值时,将不能继续发送事件,此时将返回错误。具体实现如程序清单 25所示。

    程序清单 2-5写事件文件

    LW_API

    inteventfd_write (intfd,eventfd_tvalue)

    {

    return (write(fd, &value,sizeof(eventfd_t)) !=sizeof(eventfd_t) ?PX_ERROR : ERROR_NONE);

    }

     

    需要用户注意的是,eventfd_write函数总是会等待上一次写入的事件被读取完后才能完成本次事件的写入,所以事件文件的读和写是一个相互同步的过程,一次事件的数值可理解为事件发生后所能处理的资源数量,EFD_SEMAPHORE则允许事件接受方决定是一次处理多个资源还是单个资源。

  8. 参考文献

    1.《SylixOS应用开发手册》

    2. SylixOS源码

© 著作权归作者所有

粉丝 1
博文 6
码字总数 6937
作品 0
南京
私信 提问
SylixOS-IgH系统平台搭建

1.参考手册 下面7个文件存放在本地服务器“\10.9.1.113.研发部9.ExchangeFolder郑磊”路径下 《RealEvo-IDE使用手册》 《SylixOS应用开发手册》 《SylixOSshell用户手册》 《SylixOS-IgH使用...

zhengleich
2018/05/15
0
0
VxWorks驱动移植至SylixOS总结

本文档描述了将VxWorks中的驱动源码快速移植至SylixOS中的方法,使用时需要结合SylixOS中的VxWorks兼容层实现。 1. 驱动注册与初始化 1.1 VxWorks中驱动注册与初始化 1.1.1 初始化函数 VxWo...

zhywxyy
2018/08/21
56
0
SylixOS上EtherCAT实现

1 EtherCAT开源协议栈介绍 目前常见开源的主站代码为RT-LAB开发的SOEM(Simple OpenSource EtherCAT Master)和EtherLab的the IgH EtherCAT® Master,SylixOS对两者都支持。其中IgH作为常用的...

Jackstraw瑞
2017/11/01
286
0
SylixOS线程堆栈大小浅析

目录 1. SylixOS线程、线程栈介绍 1 1.1 线程的介绍 1 1.2 线程栈的介绍 1 2. SylixOS线程栈大小的分配 1 2.1 线程、线程栈相关属性的设置 2 2.2 线程栈大小 2 2.3 线程堆栈警戒区 3 3. 总结...

Esc120
2018/06/26
0
0
SylixOS调试方法详解——综合案例分析

1. SylixOS调试方法介绍 SylixOS实现了一个功能强大的调试stub(桩),可在设备或模拟器上在线调试应用程序,RealEvo-IDE也提供配套的调试插件。目前RealEvo-IDE既支持自动推送调试、也支持传...

Esc120
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么? 所谓的动态代理,他是一个代理机制,代理机制可以看作是对调用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成,通过代理可以有效的让调...

code-ortaerc
今天
5
0
学习记录(day05-标签操作、属性绑定、语句控制、数据绑定、事件绑定、案例用户登录)

[TOC] 1.1.1标签操作v-text&v-html v-text:会把data中绑定的数据值原样输出。 v-html:会把data中值输出,且会自动解析html代码 <!--可以将指定的内容显示到标签体中--><标签 v-text=""></......

庭前云落
今天
8
0
VMware vSphere的两种RDM磁盘

在VMware vSphere vCenter中创建虚拟机时,可以添加一种叫RDM的磁盘。 RDM - Raw Device Mapping,原始设备映射,那么,RDM磁盘是不是就可以称作为“原始设备映射磁盘”呢?这也是一种可以热...

大别阿郎
今天
12
0
【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
16
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部