Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Two applications connected to a same instance of IARM-Bus are able to exchange events or RPC calls. On a typical system, only one instance of IARM-Bus instance is needed. If desired, it is possible to have multiple IARM-Bus instances. However, applications connected to different buses will not be able to communicate with each other.


 Image Removed

draw.io Diagram
diagramNameIARM Bus Architecture.drawio
size1200
revision1

Bus Daemon

Each Bus Instance is managed by a single Bus Daemon Process. The Bus Daemon oversees the activities on the bus and manage common resources competed by all connected applications. Applications requesting a shared resource must firstly acquire Ownership from acquire from the Bus Daemon. Once it is done with the resource, it must release the ownership back to Bus Daemon so that other applications can use the resource. The IARM Bus Daemon offers standard APIs to request and release ownership of a resource. In Essence, a Bus Daemon itself is a regular applications connected to the IARM-Bus with special privileges. It is the only entity that has knowledge of all applications connected to the bus, and has the authority of granting or denying resources.

...

  • IR manager sends these IR events to other applications.
    • IARM_BUS_IRMGR_EVENT_IRKEY
  • The Event Data contains Key Code and Key Type of the pressed IR key.
    • int keyType;
    • int keyCode;
  • IR manager publishes two RPC Methods:
    • SetRepeatKeyInterval
    • GetRepeatKeyInterval
  • Other application can invoke these methods to determine how often a repeat key is sent when the IR key is held own by the user.

...

Since all the events published by the application are tied to its well-known name, the application must make its well-known name available to other applications that wish to use its service. The well-known name can be thought of as the Namespace within which the application's events and RPC methods live. This name must be declared in the application's public header file. In our example, this file is irMgr.h

Code Block
 #define IARM_BUS_IRMGR_NAME "IRMgr"

...


 Naming 

...

Convention: IARM_BUS_<Manager>_NAME "Manager"

When the application initialize with IARM-Bus, it provides its well-known name:

...

Code Block
IARM_Bus_Init(IARM_BUS_IRMGR_NAME);

...


IARM_Bus_Connect();

...

Applications should use the defined macro of the owner's well-known name (IARM_BUS_IRMGR_NAME in this example) when sending or listening for events.

...

Code Block
typedef enum _EventId_t {
     IARM_BUS_IRMGR_EVENT_IRKEY = 0,
     IARM_BUS_IRMGR_EVENT_MAX
 } 

 
 Naming

...

Convention:

...

IARM_BUS_<Manager>EVENT<Event

...

Name>

...

_EVENT_MAX must have the value of (Number Of Events Published + 1). This MAX value is used when registering all events to the IARM –Bus. 
An event may or may not have Event Data. If an event has event data, the data types must be declared so that the listeners of the events can process the data properly. The data structure should a union of event data for all events that the application would send. For example, IR Manager's IR Event Data contains a keyType and KeyCode field.

Code Block
typedef struct _IRMgr_EventData_t {
    union {
       struct _IRKEY_DATA{
           int keyType;
 	   int keyCode;
       } irkey, fpkey;
   } data; 
}IARM_Bus_IRMgr_EventData_t; 

Naming

...

Convention:

...

IARM_Bus_<Manager>_EventData_t

...

Note
The event data structure cannot have pointers. The sizeof() operator applied on the _EventData_t must equal to the actual memory allocated. Internally an equivalent of memcpy() is used to dispatch event data to its target. If a pointer is used in the event data, the pointer, not the content it points to, is sent to the destination.

...

Code Block
IARM_Bus_BroadcastEvent(
     IARM_BUS_IRMGR_NAME,	 	/* Owner of the Event */
     IARM_BUS_IRMGR_EVENT_IRKEY,	/* Event ID from this owner */
     (void *) &eventData, 		/* IARM_Bus_IRMgr_EventData_t */
     sizeof(eventData) 			/* Length of the eventData */
 )

...

  • Follow the naming conventions recommended.
  • Register to IARM-Bus with its well-known name during initialization.

...


Code Block
IARM_Result_t IARM_Bus_Init(const char name);

...


IARM_Result_t IARM_Bus_Connect(void);
  • Declare its event enumerations and event data types in public header file.
  • Register all its events during initialization using _EVENT_MAX:


Code Block

...

IARM_Result_t IARM_Bus_RegisterEvent(IARM_EventId_t maxEventId);
  • Send/Broadcast Events:


Code Block

...

IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len);

...


 If an application wants to receive and handle events , it needs to :

  • Register to IARM-Bus with its well-known name during initialization.
Code Block

...

IARM_Result_t IARM_Bus_Init(const char *name);

...


        IARM_Result_t IARM_Bus_Connect(void);
  • Register event handler :

...

Code Block
 IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler);
  • Implement the handler.

How to Create and Invoke RPC Methods

...

Since all the RPC methods published by the application are tied to its well-known name, the application must make its well-known name available to other applications that wish to use its service. The well-known name can be thought of as the Namespace within which the application's events and RPC methods live. This name must be declared in the application's public header file. In our example, this file is irMgr.h

Code Block
 #define IARM_BUS_IRMGR_NAME "IRMgr"

...



Naming Convention: IARM_BUS_<Manager>_NAME "Manager"

 When the application initialize with IARM-Bus, it provides its well-known name:

Code Block
 IARM_Bus_Init(IARM_BUS_IRMGR_NAME);

...


IARM_Bus_Connect();

...

 Applications should use macro of the well-known name (IARM_BUS_IRMGR_NAME in this example) when invoking the RPC method.

...

Code Block
IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
     param. timeoutNewValue = 200;
     IARM_Bus_Call (
         IARM_BUS_IRMGR_NAME, /* Owner of the Method */
         IARM_BUS_IRMGR_API_SetRepeatInterval,/* Name of Method */
         (void *)&param, / Parameter of Method */
         sizeof(param)); /* Length of the Parameter */ 
)

...

Code Block
IARM_Bus_Call (
     IARM_BUS_IRMGR_NAME, 			/* Owner of the Method */
     IARM_BUS_IRMGR_API_SetRepeatInterval,	/* Name of Method */
     (void *)&param, 				/ Parameter of Method */
     sizeof(param)); 				/* Length of the Parameter */ 
)

...

Code Block
IRMgr_SetRepeatInterval(int newInterval) 
 {
     IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
     param.timeoutNewValue = 200;
     IARM_Bus_Call (
         IARM_BUS_IRMGR_NAME, /* Owner of the Method */
         IARM_BUS_IRMGR_API_SetRepeatInterval,/* Name of Method */
         (void *)&param, / Parameter of Method */
         sizeof(param)); /* Length of the Parameter */ 
     )
 }

...

Code Block
#define IRMgr_SetRepeatInterval(newInterval) \ 
 do {
     IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
     param. timeoutNewValue = 200;\
     IARM_Bus_Call (
         IARM_BUS_IRMGR_NAME,\ /* Owner of the Method */
         IARM_BUS_IRMGR_API_SetRepeatInterval,\/* Name of Method */
         (void *)&param,\/ Parameter of Method */
         sizeof(param));\/* Length of the Parameter */ 
     )
 }while(0);

...

Code Block
IRMgr_SetRepeatInterval(int newInterval) 
 {
     IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
     param. timeoutNewValue = 200;
     IARM_Bus_Call (
         IARM_BUS_IRMGR_NAME, /* Owner of the Method */
         IARM_BUS_IRMGR_API_SetRepeatInterval,/* Name of Method */
         (void *)&param, / Parameter of Method */
         sizeof(param)); /* Length of the Parameter */ 
     )
 }

...


In

...

the

...

IR

...

Manager's

...

implementation

...

of

...

RPC

...

Method,

...

we

...

have

...

already

...

learned

...

from

...

previous

...

sections

...

that

...

this

...

RPC

...

method

...

is

...

registered

...

with.

 
Code Block
IARM_Result_t IARM_Bus_RegisterCall(
     _BUS_IRMGR_API_SetRepeatInterval,  /* RPC Method Name */
     _SetRepeatInterval			/* RPC Method Implementation*/ 
 )
Where _SetRepeatInterval changes the actual settings.
 static IARM_Result_t _SetRepeatInterval(void *arg)
 {
     /* First cast the argument to its target type */
     IARM_Bus_IRMgr_SetRepeatInterval_Param_t 
     *param = (IARM_Bus_IRMgr_SetRepeatInterval_Param_t *)arg;
     /* changes actual settings here */
 } 

...

Code Block
IRMgr_SetRepeatInterval(int newInterval) 
 {
     IARM_Bus_IRMgr_SetRepeatInterval_Param_t param;
     param. timeoutNewValue = 200;
     IARM_Bus_Call (
         IARM_BUS_IRMGR_NAME, 			/* Owner of the Method */
         IARM_BUS_IRMGR_API_SetRepeatInterval,	/* Name of Method */
         (void *)&param, 			/* Parameter of Method */
         sizeof(param)); 			/* Length of the Parameter */ 
     )
 } 

...

The application can then choose which implementation to link to at build time based on its needs. To use the multi-app version of API, the application links to libirMgrCli.so. To use the single-app version of the API, the application links to libirMgr.so. In either choice, the application is no longer coupled to IARM. The following diagrams demonstrate the linkage relationship between applications and the generic API.

draw.io Diagram
diagramNameIARM Publisher and Listeners Concept Flow Diagram.drawio
Image Removed
revision1
        Image Removed
 

Porting layer of IARM-Bus

...


By default, the IARM-Bus has the following Manager Components. The published events and RPC methods from these manager components can be found in their public header files.
On a standard system, you should see the following 3 processes running before executing your own application.

  • IARMDaemonMain
  • irMgrMain
  • pwrMgrMain 

To see the  IARM managers available in the device. Use the below command,

ps

...

-aef|grep

...

Mgr*

...

root

...

462 1

...

0

...

05:07 ? 00:00

...

:02 /usr/bin/mfrMgrMain
root 1195 1 0 05:07 ? 00:00:

...

02 /usr/bin/sysMgrMain
root 1240 1 0 05:07 ? 00:00:02 /usr/bin/dsMgrMain
root 1343 1 1 05:07 ? 00:06:01 /usr/bin/irMgrMain
root 1545 1 0 05:07 ? 00:00:02 /usr/bin/pwrMgrMain
root 1593 1 0 05:07 ? 00:00:02 /usr/bin/deepSleepMgrMain

Bus Daemon

Executable name is IARMDaemonMain. The IARM Bus Daemon is a Manager Component with special privileges. 

...

  • libIARMBus.so is at a known library path.
  • Daemon process IARMDaemonMain is running.
    • ps –aef | grep IARMDaemonMain
    • You see log message "Bus Daemon HeartBeat" on console or /opt/logs/uimgr_log.txt.Doxygen Documentation

Sample Code

For sample code, refer 

    • cat /opt/logs/uimgr_log.txt

      No Format
      Oct 17 08:47:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: I-ARM Bus Daemon : HeartBeat at Thu Oct 17 08:47:00 2019
      Oct 17 08:47:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: [1B blob data]
      Oct 17 08:47:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: I-ARM MFR Lib: HeartBeat at Thu Oct 17 08:47:01 2019
      Oct 17 08:47:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: [1B blob data]
      Oct 17 08:47:04 raspberrypi-rdk-hybrid-thunder dsMgrMain[1240]: I-ARM BUS DS Mgr: HeartBeat at Thu Oct 17 08:47:04 2019
      Oct 17 08:47:04 raspberrypi-rdk-hybrid-thunder dsMgrMain[1240]: [1B blob data]
      Oct 17 08:47:06 raspberrypi-rdk-hybrid-thunder pwrMgrMain[1545]: I-ARM POWER Mgr: HeartBeat at Thu Oct 17 08:47:06 2019
      Oct 17 08:47:06 raspberrypi-rdk-hybrid-thunder pwrMgrMain[1545]: [1B blob data]
      Oct 17 08:52:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: I-ARM Bus Daemon : HeartBeat at Thu Oct 17 08:52:00 2019
      Oct 17 08:52:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: [1B blob data]
      Oct 17 08:52:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: I-ARM MFR Lib: HeartBeat at Thu Oct 17 08:52:01 2019
      Oct 17 08:52:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: [1B blob data]
      Oct 17 08:52:04 raspberrypi-rdk-hybrid-thunder dsMgrMain[1240]: I-ARM BUS DS Mgr: HeartBeat at Thu Oct 17 08:52:04 2019
      Oct 17 08:52:04 raspberrypi-rdk-hybrid-thunder dsMgrMain[1240]: [1B blob data]
      Oct 17 08:52:06 raspberrypi-rdk-hybrid-thunder pwrMgrMain[1545]: I-ARM POWER Mgr: HeartBeat at Thu Oct 17 08:52:06 2019
      Oct 17 08:52:06 raspberrypi-rdk-hybrid-thunder pwrMgrMain[1545]: [1B blob data]
      Oct 17 08:57:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: I-ARM Bus Daemon : HeartBeat at Thu Oct 17 08:57:00 2019
      Oct 17 08:57:00 raspberrypi-rdk-hybrid-thunder IARMDaemonMain[234]: [1B blob data]
      Oct 17 08:57:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: I-ARM MFR Lib: HeartBeat at Thu Oct 17 08:57:01 2019
      Oct 17 08:57:01 raspberrypi-rdk-hybrid-thunder mfrMgrMain[462]: [1B blob data]
    IARM Test app

API Documentation

 To know more about SoC/Application level APIs details use in RDK, refer the link  IARM BUS API Documentation