Change the bus associated to a port using PolyORB-HI-C
Port, devices and bus identifiers
PolyORB-HI-C manages port, bus and devices using identifiers generated from the AADL model. The identifiers are generated in the deployment.h file on each node. The following types are very important and have the same values on each node:
- __po_hi_node_t : identifier of each node in a distributed system
- __po_hi_device_id : identifier of each device of all the distributed system
- __po_hi_port_t : identifiers of all ports of all the distributed system (not only the local port.
In addition, the system provides the following macros that define the resources dimension:
- __PO_HI_NB_DEVICES : number of devices in the distributed system (not on the local node)
- __PO_HI_NB_BUSES : number of buses in the distributed system
- __PO_HI_NB_NODES : number of nodes in the distributed system
Sending and receiving data
When sending or receiving data to/from other nodes in the distributed system, the transport layer of PolyORB-HI-C inspect the connection tables across ports and checks if the remote port is local or belongs to another node. This is done using the following block of code :
/*
* Task-ID is the task who is performing the operation. Local-port the value of the
* port relative to the local port. See __po_hi_local_port_t in deployment.h.
*/
for (i=0 ; i < __po_hi_gqueue_get_destinations_number (task_id, local_port) ; i++)
{
destination_port = __po_hi_gqueue_get_destination (task_id, local_port, i);
destination_entity = __po_hi_get_entity_from_global_port (destination_port);
if (__po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (port)) ==
__po_hi_transport_get_node_from_entity (__po_hi_get_entity_from_global_port (destination_port)))
{
/* LOCAL COMMUNICATION, SAME NODE-ID */
}
else
{
/* REMOTE COMMUNICATION, DIFFERENT NODE-ID */
}
Then, once you have detected this is a remote connection, in order to send it, you have to know the device associated with a port. For that, you have to retrieve the destination port related to the local port and then, retrieve the two devices (local and remote) connected to the bus. This is done by using the following block of code in the device drivers implementation :
/* First, get the value of the local port associated to the port */
local_port = __po_hi_get_local_port_from_global_port (port);
/*
* Get the value of the remote destination port, we assume there is only one destination port
* for this source (last argument set to 0)
*/
destination_port = __po_hi_gqueue_get_destination (task_id, local_port, 0);
/*
* Get the device associated with the local port.
*/
local_device = __po_hi_get_device_from_port (port);
/*
* Get the device associated with the remote port.
*/
remote_device = __po_hi_get_device_from_port (destination_port);
Changing the bus associated to a device
So, when you need to change the bus associated to a particular port, you need to make different operation to change the association between ports, bus and devices. This part is automatically done using the function __po_hi_transport_associate_port_bus. This function update all the identifiers connected to a port so that the port will be associated with the appropriate device and bus values for that particular bus. The function returns 1 in case of success, 0 in case of failure. However, in order to be called successfully, the bus must be connected on the device using a device. If the bus is not associated to a device running on the same node than the port, it will return 0.
This operation needs to be done on both local and destinations ports. The first argument is the port identifier (__po_hi_port_t value) of the port while the second is the bus identifier (__po_hi_bus_id) from the file deploymeht.h.
The following block of code indicates how to associate a bus with a port. For more information, please see the ping example of PolyORB-HI-C (directory examples/aadlv2/ping)
if ( ( p % 2 ) == 0)
{
__po_hi_transport_associate_port_bus (ping_me_global_data_sink, bus_first_bus);
}
else
{
__po_hi_transport_associate_port_bus (ping_me_global_data_sink, bus_second_bus);
}