在polyorb中添加驱动 - HPECLab/tutorials GitHub Wiki

#在polyorb中添加驱动 ##1.概要 在polyorb中的驱动程序主要包括初始化时的包装函数(wrapper function),创建配置和访问驱动的原语(primitives)即含有如下内容

+ 在ASN.1中创建配置数据类型
+ 一个初始化函数
+ 一个轮询函数(poller function)
+ 一个发送函数 

##2.创建配置数据类型 我们在polyorb 的ASN.1文件里创建配置数据类型,其中已经包含1553,spacewire,serial,ethernet 的驱动文件,如果你要另添加配置数据类型,应该在其中创建新类型。该类型将在配置驱动时使用。其配置文件所在目录为
carina/include/ocarina/runtime/polyorb-hi-c/src/drivers

3.在aadl组件里指明驱动

编写好驱动后,将在aadl组件里进行使用,首先其包含在device组件里,该组件同时包含如下子组件。

+ Deployment::Driver_Name :驱动名
+ Device_Driver: 包含驱动实现的子组件
+ Initialize_Entrypoint: 驱动初始化的子函数
+ Provided_Virtual_Bus_Class: 列出所有可以与驱动通信的总线

Device_Driver 子组件是一个抽象AADL子组件,描述了运行驱动所需要的资源。以spacewire的驱动来说,其包含以下子组件

1. 轮询组件用于从设备接收数据
2. 发送组件用于在网络上发送数据

实现如下spacewire_driver.aadl

##4.实现驱动 接下来的任务就是实现驱动,包括实现aadl中驱动组件实现里指明的源文件,实现的代码需要调用底层操作系统提供的驱动原语,对于例子中得SpaceWire驱动,需要实现如下三个函数

  • void __po_hi_c_driver_spacewire_rasta_poller(const __po_hi_device_id dev_id)轮询函数,函数的参数为系统中得设备号,
  • void __po_hi_c_driver_spacewire_rasta_init(__po_hi_device_id id):设备初始化函数,与轮询函数类似,参数为设备号
  • int __po_hi_c_driver_spacewire_rasta_sender(const __po_hi_task_id task_id,const __po_hi_port_t port):发送函数,第一个参数是任务号,第二个参数是本任务的发送源端口。因为一个任务可能存在多个通信端口,所以需要指明是哪个通信端口。另外通过polyorb-hi-c提供的通信服务,开发者可以调用函数来获得目的端口和远程设备(类似于socket编程里调用函数获得对等端口信息),该函数失败时应该返回0,对于通信设备,建议查看polyorb-hi-c中现存的驱动代码,其存放于carina/include/ocarina/runtime/polyorb-hi-c/include/ 目录下。

##5.驱动样例 在目录carina/include/ocarina/runtime/polyorb-hi-c/src/drivers下包含了现有的驱动代码,开发者可以查看这些代码来了解polyorb-hi-c的工作机制,从而开发自己的驱动。

##6.添加驱动测试 以ping为例,介绍下如何注册驱动文件,ping 工程下面包含如下文件

devicesconf.c ping.aadl scenario.aadl ping.aadl ping.h software.aadl

其中ping.aadl包含如下与驱动相关代码。 ####ping.aadl

  Device_A : device ocarina_drivers::generic_sockets_ip.pohic
    {Source_Text => ("devicesconf.c");};
  Device_B : device ocarina_drivers::generic_sockets_ip.pohic
    {Source_Text => ("devicesconf.c");};

编译能生成可执行文件 修改驱动为自己的驱动(暂时未实现),修改后的文件如下(将generic_socket_ip 驱动修改为 demo驱动) ####ping.aadl

  Device_A : device ocarina_drivers::demo.pohic
    {Source_Text => ("devicesconf.c");};
  Device_B : device ocarina_drivers::demo.pohic
    {Source_Text => ("devicesconf.c");};

编译,报错如下

Device_A(subcomponent) points to ocarina_drivers::demo.pohic
Device_B(subcomponent) points to
ocarina_drivers::demo.pohic

由报错提示可得,出错原因在于未包含相应的驱动组件。 故下一步在ocarina里添加驱动组件。

查找在哪些文件里添加驱动组件,aadl的相关组件库在目录ocarina/share/ocarina/AADLv2下其包含如下文件

Cheddar_Properties.aadl		emv2.aadl
aadl_project.aadl		memory_properties.aadl
arinc653.aadl			modeling_properties.aadl
arinc653_properties.aadl	ocarina_components.aadl
assert_properties.aadl		ocarina_components.aadl~
assert_properties_extended.aadl	ocarina_config.aadl
assert_types.aadl		pok_properties.aadl
base_types.aadl			programming_properties.aadl
behavior_properties.aadl	taste_properties.aadl
communication_properties.aadl	thread_properties.aadl
data_model.aadl			timing_properties.aadl
deployment.aadl			transformations.aadl

搜寻关于驱动组件库信息

$:grep generic_sockets_ip *  
ocarina_components.aadl: device generic_sockets_ip

可得驱动组件在ocarina_components.aadl文件里,故在其中添加驱动组件demo 打开ocarina_components.aadl相关内容如下 ###ocarin_components.aadl

  -------------------------------
  -- Generic sockets/ip driver --
  -------------------------------
  device generic_sockets_ip
  features
    link : requires bus access ocarina_buses::ip.i;
  end generic_sockets_ip;

  device implementation generic_sockets_ip.pohic
  properties
    Deployment::Driver_Name       => "sockets";
    Device_Driver                 => classifier (ocarina_drivers_ip_pohic::sockets_impl.i);
    Initialize_Entrypoint         => classifier (ocarina_drivers_ip_pohic::spg_sockets_init);
    Provided_Virtual_Bus_Class    => (classifier (ocarina_buses::pohi.c));
  end generic_sockets_ip.pohic;

  device implementation generic_sockets_ip.pohiada
  properties
    Deployment::Driver_Name       => "socketsnew";
    Device_Driver => classifier (TCP_IP_Protocol::Driver_TCP_IP_Protocol.impl);
    Initialize_Entrypoint => classifier (TCP_IP_Protocol::Initialize);
    Provided_Virtual_Bus_Class    => (classifier (ocarina_buses::pohi.c));
  end generic_sockets_ip.pohiada;

仿照generic_sockets_ip组件,添加demo组件。(复制上面代码然后将generic_sockets_ip替换为demo即可) 添加代码如下 ###ocarina_components.aadl

 -------------------------------
  -- my adding demo driver --
 ------------------------------- 
  device demo
  features
    link : requires bus access ocarina_buses::ip.i;
  end demo;

  device implementation demo.pohic
  properties
    Deployment::Driver_Name       => "sockets";
    Device_Driver                 => classifier (ocarina_drivers_ip_pohic::sockets_impl.i);
    Initialize_Entrypoint         => classifier (ocarina_drivers_ip_pohic::spg_sockets_init);
    Provided_Virtual_Bus_Class    => (classifier (ocarina_buses::pohi.c));
  end demo.pohic;

  device implementation demo.pohiada
  properties
    Deployment::Driver_Name       => "socketsnew";
    Device_Driver => classifier (TCP_IP_Protocol::Driver_TCP_IP_Protocol.impl);
    Initialize_Entrypoint => classifier (TCP_IP_Protocol::Initialize);
    Provided_Virtual_Bus_Class    => (classifier (ocarina_buses::pohi.c));
  end demo.pohiada;

编译,能生成可执行文件。此即表明添加驱动工作主要在于向ocarina_components里添加驱动组件。