📄 mac_scheduler.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** Task Scheduler *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2005 *
*******************************************************************************************************
* This module contains the task scheduler used by the MAC layer. A task can begin at every backoff *
* slot boundary, assuming that no tasks of same or higher priorities running: *
* *
* Task queues: Task pool: *
* | H+<T | TT | *
* Execution priority: | H <TTT <----- |TT TTT T| *
* | M <TT |T TT TTT| *
* V L <TTTTT |--------| *
* ^ *
* | *
* One-way linked list, FIFO *
*******************************************************************************************************/
#include <mac_headers.h>
//-------------------------------------------------------------------------------------------------------
// Scheduler data
__no_init MAC_TASK_INFO pMacTasks[MAC_TASK_COUNT] @ "PM0_XDATA";
__no_init MAC_TASK_QUEUE pMacTaskQueues[MAC_TASK_PRIORITY_COUNT] @ "PM0_XDATA";
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------
// void mschInit(void)
//
// DESCRIPTION:
// Initializes the task pool and the task queues.
//-------------------------------------------------------------------------------------------------------
ROOT void mschInit(void) {
UINT8 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;
}
// Initialize the task pool
for (n = 0; n < MAC_TASK_COUNT; n++) {
pMacTasks[n].occupied = FALSE;
pMacTasks[n].taskNumber = n;
}
} // 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(...))
//-------------------------------------------------------------------------------------------------------
ROOT UINT8 mschReserveTask(void) {
UINT8 n;
// 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())
//-------------------------------------------------------------------------------------------------------
ROOT void mschReleaseTask(UINT8 taskNumber) {
if (taskNumber != NO_TASK) pMacTasks[taskNumber].occupied = FALSE;
} // mschReleaseTask
//-------------------------------------------------------------------------------------------------------
// BOOL mschAddTask(UINT8 taskNumber, UINT8 priority, TFPTR pTaskFunc, WORD taskData, void *dataPointer)
//
// 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
//
// RETURN VALUE:
// BOOL
// The task was added (the task number was OK)
//-------------------------------------------------------------------------------------------------------
ROOT BOOL 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).
//-------------------------------------------------------------------------------------------------------
ROOT 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.
//-------------------------------------------------------------------------------------------------------
ROOT 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -