msach@0: /* msach@0: * This describes a best effort communication channel. Mainly designed for msach@0: * communication between Core-Controllers, so they can inform each other about msach@0: * their status and pass work around. This is to avoid idling cores that occupy msach@0: * the Masterlock. msach@0: * msach@0: * The communication entities poll a central trigger counter that increases when msach@0: * there are new messages. However it's not guaranteed that the increase of the msach@0: * counter reflects the number of new messages. msach@0: * msach@0: * The messages consist of a single 64bit word so it can be written in one msach@0: * operation and therefore avoiding inconsistent messages. msach@0: * msach@0: * The messages are handled with a handler function provided by the receiver msach@0: * when acquiring the communication endpoint. msach@0: * msach@0: * The message passing is handled by a central struct that is used w/o any lock. msach@0: * It consists of a array messages for the number of communicating entities. The msach@0: * number of entities is fixed at initialization. msach@0: */ msach@0: msach@0: #include msach@0: msach@0: msach@0: msach@0: /*********************************** msach@0: * Type Definitions msach@0: ***********************************/ msach@0: msach@0: #define BROADCAST_ID 65535 msach@0: #define ENDPOINT_ID_SHIFT 32 msach@0: #define TRIGGER_SHIFT 48 msach@0: msach@0: /* msach@0: * A message consists of the msach@0: * 16bit saved trigger value when the message was sent msach@0: * 16bit receiver identifier, this is the index of the slot in the array msach@0: * 65536 is the broadcast identifier msach@0: * 32bit message body, the message format is defined by the endpoints msach@0: */ msach@0: typedef uint64_t lossyCom__msg_t; msach@0: typedef uint32_t lossyCom__msgBody_t; msach@0: typedef uint16_t lossyCom__endpointID_t; msach@0: msach@0: /* msach@0: * Message Handler that has two arguments the sender endpoint ID and the Msg msach@0: * Example: msach@0: * void handler_func(lossyCom__endpointID_t senderID, lossyCom__msgBody_t msg); msach@0: */ msach@0: typedef void (*lossyCom__msgHandler) (lossyCom__endpointID_t, lossyCom__msgBody_t); msach@0: msach@0: /* msach@0: * Central communication structure. msach@0: */ msach@0: typedef struct{ msach@0: uint16_t triggerCounter; msach@0: uint16_t numEndpoints; msach@0: lossyCom__msg_t* outboxArray; msach@0: }lossyCom__exchange_t; msach@0: msach@0: /* msach@0: * Endpoint data structure. msach@0: */ msach@0: typedef struct { msach@0: uint16_t localTriggerCopy; msach@0: lossyCom__endpointID_t endpointID; msach@0: lossyCom__exchange_t* centralExchangePtr; msach@0: lossyCom__msgHandler* msgHandler; msach@0: } lossyCom__endpoint_t; msach@0: msach@0: /*********************************** msach@0: * Function Declarations msach@0: ***********************************/ msach@0: msach@0: lossyCom__exchange_t* lossyCom__initialize(uint16_t numEndpoints); msach@0: msach@0: void lossyCom__initialize_endpoint(lossyCom__endpoint_t* localEndpoint, msach@0: lossyCom__exchange_t* exchange, msach@0: lossyCom__endpointID_t endpointID, msach@0: lossyCom__msgHandler* msgHandler); msach@0: msach@0: void lossyCom__broadcastMsg(lossyCom__endpoint_t* localEndpoint, msach@0: lossyCom__msgBody_t msg); msach@0: msach@0: void lossyCom__sendMsg(lossyCom__endpoint_t* localEndpoint, msach@0: lossyCom__endpointID_t receiverEndpointID, msach@0: lossyCom__msgBody_t msg); msach@0: msach@0: void lossyCom__receiveMsg(lossyCom__endpoint_t* localEndpoint);