📄 mac_scheduler.c
字号:
#pragma section @@DATA sch at 0xF000
#include "includes.h"
//-------------------------------------------------------------------------------------------------------
// Scheduler data
MAC_TASK_INFO pMacTasks[MAC_TASK_COUNT];
MAC_TASK_QUEUE pMacTaskQueues[MAC_TASK_PRIORITY_COUNT];
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void mschInit(void)
//
// DESCRIPTION:
// Initializes the task pool and the task queues.
//-------------------------------------------------------------------------------------------------------
void mschInit(void) {
UINT8 n = 0;
// Initialize the task pool
for (n = 0; n < MAC_TASK_COUNT; n++) {
pMacTasks[n].occupied = FALSE;
pMacTasks[n].taskNumber = n;
}
// Initialize the task queues
for (n = 0; n < MAC_TASK_PRIORITY_COUNT; n++) {
pMacTaskQueues[n].firstTask = NO_TASK;
pMacTaskQueues[n].lastTask = NO_TASK;
pMacTaskQueues[n].taskInProgress = FALSE;
}
} // mschInit
//-------------------------------------------------------------------------------------------------------
// UINT8 mschReserveTask(void)
//
// DESCRIPTION:
// Reserves a task from the task pool (a task must be reserved before it can be used.
//
// RETURN VALUE:
// UINT8
// The index of the reserved task (to be used with mschAddTask(...))
//-------------------------------------------------------------------------------------------------------
UINT8 mschReserveTask(void) {
UINT8 n = 0;
// Find an unused task table entry and reserve it
for ( n = 0; n < MAC_TASK_COUNT; n++) {
DISABLE_GLOBAL_INT();
if (!pMacTasks[n].occupied) {
pMacTasks[n].occupied = TRUE;
ENABLE_GLOBAL_INT();
return n;
}
ENABLE_GLOBAL_INT();
}
return NO_TASK;
} // mschReserveTask
//-------------------------------------------------------------------------------------------------------
// void mschReleaseTask(UINT8 taskNumber)
//
// DESCRIPTION:
// Clears the reservation for an unused task.
//
// ARGUMENTS:
// UINT8 taskNumber
// The number of the task (returned by mschReserveTask())
//-------------------------------------------------------------------------------------------------------
void mschReleaseTask(UINT8 taskNumber) {
if (taskNumber != NO_TASK) pMacTasks[taskNumber].occupied = FALSE;
} // mschReleaseTask
//-------------------------------------------------------------------------------------------------------
// ZBOOL mschAddTask(UINT8 taskNumber, UINT8 priority, TFPTR pTaskFunc, WORD taskData)
//
// DESCRIPTION:
// Configures and adds a reserved to task to the desired task queue.
//
// ARGUMENTS:
// UINT8 taskNumber
// The number of the task (returned by mschReserveTask(...))
// UINT8 priority
// MAC_TASK_PRI_HIGHEST, MAC_TASK_PRI_HIGH, MAC_TASK_PRI_MEDIUM or MAC_TASK_PRI_LOW
// TFPTR pTaskFunc
// A pointer to the task function (void TaskFunction(MAC_TASK_INFO *pTask))
// WORD taskData
// Two bytes of task data (usually a pointer to more data)
//
// RETURN VALUE:
// ZBOOL
// The task was added (the task number was OK)
//-------------------------------------------------------------------------------------------------------
ZBOOL mschAddTask(UINT8 taskNumber, UINT8 priority, TFPTR pTaskFunc, WORD taskData) {
MAC_TASK_INFO *pTask;
MAC_TASK_QUEUE *pQueue;
// The task index must be valid
if (taskNumber == NO_TASK) return FALSE;
DISABLE_GLOBAL_INT();
// Initialize the task
pTask = &pMacTasks[taskNumber];
pTask->pTaskFunc = pTaskFunc;
pTask->taskData = taskData;
pTask->state = 0;
pTask->priority = priority;
pTask->nextTask = NO_TASK;
// Update the queue pointers at the insertion point (last task in the queue)
pQueue = &pMacTaskQueues[priority];
if (pQueue->firstTask == NO_TASK) {
pQueue->firstTask = taskNumber;
pQueue->lastTask = taskNumber;
} else {
pMacTasks[pQueue->lastTask].nextTask = taskNumber;
pQueue->lastTask = taskNumber;
}
ENABLE_GLOBAL_INT();
return TRUE;
} // mschAddTask
//-------------------------------------------------------------------------------------------------------
// void mschRemoveTask(UINT8 priority, BYTE flags)
//
// DESCRIPTION:
// Removes the active task from the specified task queue. This function is usually run from the task
// function when it's about to finished, or before it makes a call to the higher layer.
//
// ARGUMENTS:
// UINT8 priority
// The priority of the task to be removed
// BYTE flags
// MSCH_KEEP_TASK_RESERVED_BM: The task is not released back to the task pool
// MSCH_KEEP_TASK_IN_PROGRESS_BM: Does not allow other tasks of the same priority to run before
// the current task has finished (even if it is removed from the queue).
//-------------------------------------------------------------------------------------------------------
void mschRemoveTask(UINT8 priority, BYTE flags) {
UINT8 taskNumber;
MAC_TASK_INFO *pTask;
MAC_TASK_QUEUE *pQueue = &pMacTaskQueues[priority];
DISABLE_GLOBAL_INT();
// Get the task table index number, and make sure that it is valid
taskNumber = pQueue->firstTask;
// Flag-dependent operations
pTask = &pMacTasks[taskNumber];
if (!(flags & MSCH_KEEP_TASK_RESERVED_BM)) pTask->occupied = FALSE;
if (!(flags & MSCH_KEEP_TASK_IN_PROGRESS_BM)) pQueue->taskInProgress = FALSE;
// Move the "first task" pointer one step forward
pQueue->firstTask = pTask->nextTask;
if (pQueue->firstTask == NO_TASK) {
pQueue->lastTask = NO_TASK;
} else if (pQueue->lastTask == taskNumber) {
pQueue->lastTask = NO_TASK;
}
ENABLE_GLOBAL_INT();
} // mschRemoveTask
//-------------------------------------------------------------------------------------------------------
// void mschRescheduleTask(MAC_TASK_INFO *pTask, UINT8 state)
//
// DESCRIPTION:
// Removes the currently running task from a queue, and adds it to the back of the same queue,
// possibly behind a number of waiting tasks which now will be run first.
//
// ARGUMENTS:
// MAC_TASK_INFO *pTask
// The task to be rescheduled
// UINT8 state
// The task state when run after the rescheduling.
//-------------------------------------------------------------------------------------------------------
void mschRescheduleTask(MAC_TASK_INFO *pTask, UINT8 state) {
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
mschAddTask(pTask->taskNumber, pTask->priority, pTask->pTaskFunc, pTask->taskData);
pTask->state = state;
} // mschRescheduleTask
//-------------------------------------------------------------------------------------------------------
// void mschDoTask(void)
//
// DESCRIPTION:
// Used by the timer module to start or resume a task at every backoff slot boundary
//
// ARGUMENTS:
// None
//
// RETURN VALUE:
// None
//-------------------------------------------------------------------------------------------------------
void mschDoTask(void) {
UINT8 taskNumber;
MAC_TASK_QUEUE *pQueue;
MAC_TASK_INFO *pTask;
// Execute tasks by priority
UINT8 n = MAC_TASK_PRIORITY_COUNT - 1;
do {
// Stop if there's a task in progress
pQueue = &pMacTaskQueues[n];
if (pQueue->taskInProgress) return;
// If there's a valid task in the queue, then start it
DISABLE_GLOBAL_INT();
taskNumber = pQueue->firstTask;
if (taskNumber != NO_TASK) {
pQueue->taskInProgress = TRUE;
pTask = &pMacTasks[taskNumber];
ENABLE_GLOBAL_INT();
((TFPTR) pTask->pTaskFunc)(pTask);
pQueue->taskInProgress = FALSE;
return;
}
ENABLE_GLOBAL_INT();
} while (n--);
} // mschDoTask
/*******************************************************************************************************
* Revision history:
*
* $Log: mac_scheduler.c,v $
* Revision 1.8 2004/12/07 09:47:50 thl
* Fixed potential coruption of memmory when max payload is recived.
*
* Revision 1.7 2004/11/10 09:33:15 thl
* Fixed a number of bugs according to: MAC software check lists.xls
*
* Revision 1.6 2004/08/13 13:04:47 jol
* CC2420 MAC Release v0.7
*
*
*******************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -