📄 mac_scheduler.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2420 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, 2004 *
*******************************************************************************************************
* 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 *
*******************************************************************************************************
* Compiler: AVR-GCC *
* Target platform: CC2420DB, CC2420 + any ATMEGA MCU *
*******************************************************************************************************
* The revision history is located at the bottom of this file *
*******************************************************************************************************/
#pragma SFR
#pragma NOP
#pragma STOP
#pragma HALT
#pragma DI
#pragma EI
#pragma section @@DATA sch at 0xE900///
#include "mac_headers.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
//-------------------------------------------------------------------------------------------------------
// BOOL 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:
// BOOL
// The task was added (the task number was OK)
//-------------------------------------------------------------------------------------------------------
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).
//-------------------------------------------------------------------------------------------------------
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 (pQueue->taskInProgress) continue;
// 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;
///ENABLE_GLOBAL_INT();///
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 + -