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@1: /*********************************** msach@1: * General Defines msach@1: ***********************************/ msach@1: //never use this number as a endpoint! msach@1: #define BROADCAST_ID 65535 msach@3: #define MAX_TRIGGER 65535 msach@0: msach@0: /*********************************** msach@0: * Type Definitions msach@0: ***********************************/ msach@0: msach@0: /* msach@0: * A message consists of the msach@1: * 16bit saved trigger value +1 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@1: * msach@1: * | 16bit trigger value | 16bit receiverID | 32bit message body | msach@0: */ msach@1: #define ENDPOINT_ID_SHIFT 32 msach@1: #define TRIGGER_SHIFT 48 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@1: typedef void (*lossyCom__msgHandler) (lossyCom__endpointID_t, lossyCom__msgBody_t, void*); msach@0: msach@0: /* msach@0: * Central communication structure. msach@0: */ msach@0: typedef struct{ msach@4: volatile uint16_t BroadcastTriggerCounter; msach@4: volatile uint16_t* p2pTriggerCounter; msach@4: uint16_t numEndpoints; msach@4: 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@4: uint16_t lastReceivedBroadcastTrigger; msach@4: uint16_t lastReceivedp2pTrigger; msach@0: lossyCom__endpointID_t endpointID; msach@4: lossyCom__exchange_t* centralExchange; msach@4: lossyCom__msgHandler msgHandler; msach@4: void* msgHandlerData; 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@1: lossyCom__msgHandler msgHandler, msach@1: void* msgHandlerData); 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);