forked from 0xha0/df_datalink
mitigate: 整个地检和节点工程, 增加自动编译
更新了AD9361的profile
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file schdevent.c
|
||||
* @author FanHao ([email protected])
|
||||
* @brief DF Linklayer Event scheduling implementation file.
|
||||
* @version 0.1
|
||||
* @date 2023-05-06
|
||||
*
|
||||
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
|
||||
* Lab of Communication and Network
|
||||
*
|
||||
******************************************************************************/
|
||||
/**
|
||||
* @addtogroup LinkLayer
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup LinkLayer_Scheduler
|
||||
* @{
|
||||
*/
|
||||
/***************************** Include Files *********************************/
|
||||
#include <stdlib.h>
|
||||
#include "schdevent.h"
|
||||
#include "link_layer.h"
|
||||
#include "link_layer_types.h"
|
||||
#include "error.h"
|
||||
#include "clist.h"
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
/**************************** Type Definitions *******************************/
|
||||
/************************** Variable Definitions *****************************/
|
||||
static L2_SCHD_EVENT util_schdevent;
|
||||
/************************** Function Prototypes ******************************/
|
||||
/**
|
||||
* @brief helper function to free schedule events.
|
||||
*/
|
||||
static void schdevent_free(void *val)
|
||||
{
|
||||
if (val == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
free(((L2_SCHD_EVENT *)val)->l2Event.msg);
|
||||
free(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief helper function to match events by ids.
|
||||
*/
|
||||
static int8_t schdevent_compare(void *a, void *b)
|
||||
{
|
||||
ASSERT(a == NULL);
|
||||
ASSERT(b != NULL);
|
||||
register uint32_t idA, idB;
|
||||
idA = ((L2_SCHD_EVENT *)a)->eventId;
|
||||
idB = ((L2_SCHD_EVENT *)b)->eventId;
|
||||
if (idA == idB)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (idA < idB)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Creat a schedule event pool.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
*
|
||||
* @return SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL **schdPool)
|
||||
{
|
||||
(*schdPool) = malloc(sizeof(L2_SCHD_POOL));
|
||||
if (*schdPool == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to allocated memory for schdPool.\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
(*schdPool)->schdList = clist_new();
|
||||
if ((*schdPool)->schdList == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to allocated memory for schdPool->schdList.\n");
|
||||
free(*schdPool);
|
||||
return ENOMEM;
|
||||
}
|
||||
(*schdPool)->schdList->free = schdevent_free;
|
||||
(*schdPool)->schdList->compare = schdevent_compare;
|
||||
(*schdPool)->envCnt = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Clear schedule event pool, delete all events in pool and
|
||||
* free allocated memory.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
*
|
||||
* @return SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
void L2_ClearSchedEventPool(L2_SCHD_POOL *schdPool)
|
||||
{
|
||||
ASSERT(schdPool != NULL);
|
||||
clist_clear(schdPool->schdList);
|
||||
schdPool->envCnt = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Completely destroy schedule event pool.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
*
|
||||
* @return SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
void L2_DestroySchedEventPool(L2_SCHD_POOL *schdPool)
|
||||
{
|
||||
if (schdPool == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
clist_destroy(schdPool->schdList);
|
||||
free(schdPool);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Creat a new schedule event, register event in schedule event pool.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
* @param event event type of the new schedule event.
|
||||
* @param isVolatile event type of the new schedule event.
|
||||
*
|
||||
* @return NULL error occurred
|
||||
* Pointer to schedule event.
|
||||
*
|
||||
******************************************************************************/
|
||||
L2_SCHD_EVENT *L2_CreatNewSchdEvent(L2_SCHD_POOL *schdPool, L2_EVENT_TYPE event, bool isVolatile)
|
||||
{
|
||||
ASSERT(schdPool != NULL);
|
||||
if (event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE)
|
||||
{
|
||||
DBG_ERROR("Unknown event type: %" PRId8 ".\n", event);
|
||||
return NULL;
|
||||
}
|
||||
L2_SCHD_EVENT *schdEvent = (L2_SCHD_EVENT *)malloc(sizeof(L2_SCHD_EVENT));
|
||||
if (schdEvent == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to allocate schedule event.\n");
|
||||
return NULL;
|
||||
}
|
||||
clist_node_t *node = clist_node_new(schdEvent);
|
||||
if (node == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to allocate schedule event list node.\n");
|
||||
free(schdEvent);
|
||||
return NULL;
|
||||
}
|
||||
schdEvent->eventId = schdPool->envCnt++;
|
||||
schdEvent->occurCnt = 0;
|
||||
schdEvent->l2Event.event = event;
|
||||
schdEvent->l2Event.msg = NULL;
|
||||
schdEvent->isSchd = false;
|
||||
schdEvent->isVolatile = isVolatile;
|
||||
schdEvent->schdSlot = L2_SLOTNO_NONE;
|
||||
schdEvent->schdFrame = L2_FRAMENO_NONE;
|
||||
clist_rpush(schdPool->schdList, node);
|
||||
return schdEvent;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Get a schedule event by its id.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
* @param id ID of the event
|
||||
*
|
||||
* @return NULL
|
||||
* Pointer to the schedule event.
|
||||
*
|
||||
******************************************************************************/
|
||||
L2_SCHD_EVENT *L2_GetEventById(L2_SCHD_POOL *schdPool, uint32_t id)
|
||||
{
|
||||
ASSERT(schdPool != NULL);
|
||||
util_schdevent.eventId = id;
|
||||
clist_node_t *node = clist_find(schdPool->schdList, &util_schdevent);
|
||||
if (node != NULL)
|
||||
{
|
||||
DBG_WARNING("Event with id=%" PRIu32 ", dose not exist.\n", id);
|
||||
return NULL;
|
||||
}
|
||||
return ((L2_SCHD_EVENT *)node->val);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Delete a schedule event, remove the event from event pool,
|
||||
* release memory.
|
||||
*
|
||||
* @param schdPool a pointer to schedule pool instance.
|
||||
* @param id ID of the event
|
||||
*
|
||||
* @return SUCCESS
|
||||
* error code
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL *schdPool, uint32_t id)
|
||||
{
|
||||
ASSERT(schdPool != NULL);
|
||||
util_schdevent.eventId = id;
|
||||
clist_node_t *node = clist_find(schdPool->schdList, &util_schdevent);
|
||||
if (node != NULL)
|
||||
{
|
||||
DBG_ERROR("Event with id=%" PRIu32 ", dose not exist.\n", id);
|
||||
return EIGNORE;
|
||||
}
|
||||
clist_remove(schdPool->schdList, node);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Schedule a event at a specific time(indexed by frame and slot number)
|
||||
*
|
||||
* @param instPtr a pointer to linklayer instance
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
* @param frameNum schedule frame number
|
||||
* @param slotNum schedule slot number
|
||||
*
|
||||
* @return FAILURE, event has already been scheduled/schedule time not allowed.
|
||||
* SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNum, uint32_t slotNum)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
if (L2_isEventScheduled(schdEvent) == true)
|
||||
{
|
||||
DBG_ERROR("Event %" PRIu32 " has already been scheduled.\n", schdEvent->eventId);
|
||||
return FAILURE;
|
||||
}
|
||||
if (frameNum <= L2_GetCurrentFrameNum(instPtr) && slotNum < L2_GetCurrentSlotNum(instPtr))
|
||||
{
|
||||
DBG_ERROR("Cannot schedule event %" PRIu32 " to the past(current: [%" PRIu32 "-%" PRIu32 "], schedule: [%" PRIu32 "-%" PRIu32 "]).\n",
|
||||
schdEvent->eventId, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr), frameNum, slotNum);
|
||||
return FAILURE;
|
||||
}
|
||||
DBG_INFO("Schedule event (type:%" PRIu8 ") [%" PRIu32 "] at %" PRIu32 "-%" PRIu32 ".\n",
|
||||
schdEvent->l2Event.event, schdEvent->eventId,
|
||||
frameNum, slotNum);
|
||||
schdEvent->isSchd = true;
|
||||
schdEvent->schdFrame = frameNum;
|
||||
schdEvent->schdSlot = slotNum;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Schedule a event after a specific time period.
|
||||
*
|
||||
* @param instPtr a pointer to linklayer instance
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
* @param numSlots how many slot later the event should be scheduled
|
||||
*
|
||||
* @return FAILURE, event has already been scheduled/schedule time not allowed.
|
||||
* SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
if (L2_isEventScheduled(schdEvent) == true)
|
||||
{
|
||||
DBG_ERROR("Event %" PRIu32 " has already been scheduled.\n", schdEvent->eventId);
|
||||
return FAILURE;
|
||||
}
|
||||
uint32_t frameNum = L2_GetCurrentFrameNum(instPtr) + (numSlots / L2_SLOTS_PER_FRAME);
|
||||
uint32_t slotNum = L2_GetCurrentSlotNum(instPtr) + (numSlots % L2_SLOTS_PER_FRAME);
|
||||
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Reschedule a event at a specific time(indexed by frame and slot number)
|
||||
*
|
||||
* @param instPtr a pointer to linklayer instance
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
* @param frameNum schedule frame number
|
||||
* @param slotNum schedule slot number
|
||||
*
|
||||
* @return FAILURE, event has already been scheduled/schedule time not allowed.
|
||||
* SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_RescheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNum, uint32_t slotNum)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
if (schdEvent->isSchd == false)
|
||||
{
|
||||
DBG_WARNING("Event %" PRIu32 " has not been scheduled yet.\n", schdEvent->eventId);
|
||||
}
|
||||
schdEvent->isSchd = false;
|
||||
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Reschedule a event after a specific time period.
|
||||
*
|
||||
* @param instPtr a pointer to linklayer instance
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
* @param numSlots how many slot later the event should be scheduled
|
||||
*
|
||||
* @return FAILURE, event has already been scheduled/schedule time not allowed.
|
||||
* SUCCESS
|
||||
*
|
||||
******************************************************************************/
|
||||
int32_t L2_RescheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
if (schdEvent->isSchd == false)
|
||||
{
|
||||
DBG_WARNING("Event %" PRIu32 " has not been scheduled yet.\n", schdEvent->eventId);
|
||||
}
|
||||
return L2_ScheduleEventAfter(instPtr, schdEvent, numSlots);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Check and excute schedule event in event pool illiterate.
|
||||
*
|
||||
* @param instPtr a pointer to linklayer instance
|
||||
*
|
||||
* @return NONE.
|
||||
*
|
||||
******************************************************************************/
|
||||
void L2_EventPoolHandler(L2_INST *instPtr)
|
||||
{
|
||||
ASSERT(instPtr != NULL);
|
||||
clist_node_t *node;
|
||||
L2_SCHD_EVENT *event;
|
||||
L2_SCHD_POOL *pool = instPtr->schdEventPool;
|
||||
clist_iterator_t *iter = clist_iterator_new(pool->schdList, LIST_HEAD);
|
||||
if (iter == NULL)
|
||||
{
|
||||
DBG_ERROR("Failed to initialize schedule event pool iteration.\n");
|
||||
return;
|
||||
}
|
||||
while ((node = clist_iterator_next(iter)))
|
||||
{
|
||||
event = (L2_SCHD_EVENT *)node->val;
|
||||
if (L2_isEventScheduled(event))
|
||||
{
|
||||
if (event->schdFrame == L2_GetCurrentFrameNum(instPtr) && event->schdSlot == L2_GetCurrentSlotNum(instPtr))
|
||||
{
|
||||
DBG_INFO("Asserting scheduled event [%" PRIu32 "].\n", event->eventId);
|
||||
(void)AssertL2Event(instPtr, &(event->l2Event));
|
||||
if (event->isVolatile == true)
|
||||
{
|
||||
DBG_INFO("Deleting scheduled event [%" PRIu32 "], since it is volatile.\n", event->eventId);
|
||||
clist_remove(pool->schdList, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
event->occurCnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
clist_iterator_destroy(iter);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Append extra message content to specific schedule event.
|
||||
*
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
* msg pointer to the append content.
|
||||
*
|
||||
* @return SUCCESS.
|
||||
* error code.
|
||||
*
|
||||
******************************************************************************/
|
||||
inline void L2_SchdEventAppendMsg(L2_SCHD_EVENT *schdEvent, void *msg)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
schdEvent->l2Event.msg = msg;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Cancel a scheduled event.
|
||||
*
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
*
|
||||
* @return SUCCESS.
|
||||
*
|
||||
******************************************************************************/
|
||||
inline int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
if (schdEvent->isSchd == false)
|
||||
{
|
||||
DBG_WARNING("Event %" PRIu32 " has not been scheduled yet.\n", schdEvent->eventId);
|
||||
}
|
||||
schdEvent->isSchd = false;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @brief Check if the event was scheduled.
|
||||
*
|
||||
* @param schdEvent pointer to the schedule event.
|
||||
*
|
||||
* @return true.
|
||||
* false.
|
||||
*
|
||||
******************************************************************************/
|
||||
inline bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent)
|
||||
{
|
||||
ASSERT(schdEvent != NULL);
|
||||
return schdEvent->isSchd;
|
||||
}
|
||||
|
||||
/** @} LinkLayer_Scheduler*/
|
||||
/** @} LinkLayer*/
|
||||
Reference in New Issue
Block a user