📄 rtx_config.c
字号:
/*----------------------------------------------------------------------------
* R T L - K e r n e l
*----------------------------------------------------------------------------
* Name: RTX_CONFIG.C
* Purpose: Configuration of RTX Kernel for CORTEX M3
* Rev.: V3.04a / 17-jan-2007
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright (c) 2004-2007 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include <RTX_Config.h> /* RTX user configuration header */
/*----------------------------------------------------------------------------
* RTX User configuration part BEGIN
*---------------------------------------------------------------------------*/
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
// <h>Task Definitions
// ===================
//
// <o>Number of concurrent running tasks <0-250>
// <i> Define max. number of tasks that will run at the same time.
// <i> Default: 6
#ifndef OS_TASKCNT
#define OS_TASKCNT 5
#endif
// <o>Number of tasks with user-provided stack <0-250>
// <i> Define the number of tasks that will use a bigger stack.
// <i> The memory space for the stack is provided by the user.
// <i> Default: 0
#ifndef OS_PRIVCNT
#define OS_PRIVCNT 0
#endif
// <o>Task stack size [bytes] <20-4096:8><#/4>
// <i> Set the stack size for tasks which is assigned by the system.
// <i> Default: 200
#ifndef OS_STKSIZE
#define OS_STKSIZE 40
#endif
// <q>Check for the stack overflow
// ===============================
// <i> Include the stack checking code for a stack overflow.
// <i> Note that additional code reduces the Kernel performance.
#ifndef OS_STKCHECK
#define OS_STKCHECK 1
#endif
// <o>Number of user timers <0-250>
// <i> Define max. number of user timers that will run at the same time.
// <i> Default: 0 (User timers disabled)
#ifndef OS_TIMERCNT
#define OS_TIMERCNT 0
#endif
// </h>
// <h>SysTick Timer Configuration
// =============================
// <o>Timer clock value [Hz] <1-1000000000>
// <i> Set the timer clock value for selected timer.
// <i> Default: 6000000 (6MHz)
#ifndef OS_CLOCK
#define OS_CLOCK 6000000
#endif
// <o>Timer tick value [us] <1-1000000>
// <i> Set the timer tick value for selected timer.
// <i> Default: 10000 (10ms)
#ifndef OS_TICK
#define OS_TICK 10000
#endif
// </h>
// <e>Round-Robin Task switching
// =============================
// <i> Enable Round-Robin Task switching.
#ifndef OS_ROBIN
#define OS_ROBIN 1
#endif
// <o>Round-Robin Timeout [ticks] <1-1000>
// <i> Define how long a task will execute before a task switch.
// <i> Default: 5
#ifndef OS_ROBINTOUT
#define OS_ROBINTOUT 5
#endif
// </e>
//------------- <<< end of configuration section >>> -----------------------
/*----------------------------------------------------------------------------
* RTX User configuration part END
*---------------------------------------------------------------------------*/
#define OS_TIMER 0
#define MAGIC_WORD 0xE25A2EA5
#define OS_TRV ((U32)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
/*----------------------------------------------------------------------------
* Global Variables
*---------------------------------------------------------------------------*/
extern P_TCB os_runtask;
extern struct OS_XCB os_rdy;
extern struct OS_TCB os_clock_TCB;
extern U16 os_time;
#pragma push
#pragma O0
U16 const os_maxtaskrun = OS_TASKCNT;
U16 const os_stksize = OS_STKSIZE;
U32 const os_trv = OS_TRV;
U32 const os_magic_word = MAGIC_WORD;
/* Export following defines to uVision debugger. */
U32 const os_stackinfo = (OS_STKCHECK<<24) | (OS_PRIVCNT<<16) | (OS_STKSIZE*4);
U32 const os_clockrate = OS_TICK;
U32 const os_timernum = (OS_TIMER << 16) | OS_TIMERCNT;
U32 const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT;
#pragma pop
/*----------------------------------------------------------------------------
* Local Variables
*---------------------------------------------------------------------------*/
/* Memory pool for TCB allocation */
_declare_box (static m_tcb, sizeof(struct OS_TCB), OS_TASKCNT);
/* Memory pool for System stack allocation. Need to allocate 2 additional */
/* entries for 'os_clock_demon()' and 'os_idle_demon()'. */
_declare_box8 (static m_stk, OS_STKSIZE*4, OS_TASKCNT-OS_PRIVCNT+2);
/* An array of Active task pointers. */
P_TCB os_active_TCB[OS_TASKCNT];
#if (OS_ROBIN == 1)
static U16 os_robin_time;
static P_TCB os_tsk_robin;
#endif
#if (OS_TIMERCNT != 0)
/* Memory pool for User Timer allocation */
_declare_box (static m_tmr, sizeof(struct OS_TMR), OS_TIMERCNT);
#endif
#if (OS_STKCHECK == 1)
static BIT os_del_flag;
#endif
/*----------------------------------------------------------------------------
* Global Functions
*---------------------------------------------------------------------------*/
/*--------------------------- os_idle_demon ---------------------------------*/
void os_idle_demon (void) __task {
/* The idle demon is a system task. It is running when no other task is */
/* ready to run (idle situation). It must not terminate. Therefore it */
/* should contain at least an endless loop. */
for (;;) {
/* HERE: include here optional user code to be executed when no task runs.*/
}
} /* end of os_idle_demon */
/*--------------------------- os_tmr_call -----------------------------------*/
void os_tmr_call (U16 info) {
/* This function is called when the user timer has expired. */
/* Parameter "info" is the parameter defined when the timer was created. */
/* HERE: include here optional user code to be executed on timeout. */
info = info;
} /* end of os_tmr_call */
/*--------------------------- os_stk_overflow -------------------------------*/
#if (OS_STKCHECK == 1)
static void os_stk_overflow (void) {
/* This function is called when a stack overflow is detected. */
/* 'os_runtask' points to a TCB of a task which has a stack overflow */
/* 'task_id' holds a task id for this task */
/* HERE: include here optional code to be executed on stack overflow. */
static volatile OS_TID task_id;
/* Get a task identification for a task with stack problem to 'task_id'.*/
task_id = os_get_TID (os_runtask);
/* Use a uVision 'RTX Kernel' debug dialog page 'Active Tasks' to */
/* check which task has got a stack overflow and needs a bigger stack. */
for (;;);
}
#endif
/*--------------------------- os_init_mem -----------------------------------*/
void os_init_mem (void) {
U32 i;
for (i = 0; i < OS_TASKCNT; i++) {
os_active_TCB[i] = NULL;
}
_init_box (&m_tcb, sizeof(m_tcb), sizeof(struct OS_TCB));
_init_box8 (&m_stk, sizeof(m_stk), OS_STKSIZE*4);
#if (OS_TIMERCNT != 0)
_init_box (&m_tmr, sizeof(m_tmr), sizeof(struct OS_TMR));
#endif
} /* end of os_init_mem */
/*--------------------------- os_alloc_TCB ----------------------------------*/
P_TCB os_alloc_TCB (void) {
return (_alloc_box (m_tcb));
} /* end of os_alloc_TCB */
/*--------------------------- os_alloc_stk ----------------------------------*/
void *os_alloc_stk (void) {
return (_alloc_box (m_stk));
} /* end of os_alloc_stk */
/*--------------------------- os_free_TCB -----------------------------------*/
void os_free_TCB (P_TCB p_TCB) {
/* Free allocated memory resources for the task "p_TCB" */
_free_box (m_stk, p_TCB->stack);
_free_box (m_tcb, p_TCB);
#if (OS_STKCHECK == 1)
if (os_runtask == p_TCB) {
/* os_tsk_delete_self() called. */
os_del_flag = __TRUE;
}
#endif
} /* end of os_free_TCB */
/*--------------------------- os_alloc_TMR ----------------------------------*/
P_TMR os_alloc_TMR (void) {
#if (OS_TIMERCNT != 0)
return (_alloc_box (m_tmr));
#else
return (NULL);
#endif
} /* end of os_alloc_TMR */
/*--------------------------- os_free_TMR -----------------------------------*/
void os_free_TMR (P_TMR timer) {
/* Free allocated memory resources for user timer 'timer' */
#if (OS_TIMERCNT != 0)
_free_box (m_tmr, timer);
#else
timer = timer;
#endif
} /* end of os_free_TMR */
/*--------------------------- os_switch_tasks -------------------------------*/
void __svc(0) os_switch_tasks (P_TCB p_new);
void __SVC_0 (P_TCB p_new) {
/* Switch to next task (identified by "p_new"). Saving old and restoring */
/* new context is written in assembly (module: Swi_RTX.s) */
#if (OS_STKCHECK == 1)
if (tstclrb (&os_del_flag) == __FALSE) {
/* Do not check if task has deleted itself. */
if ((os_runtask->tsk_stack < (U32)os_runtask->stack) ||
(os_runtask->stack[0] != os_magic_word)) {
os_stk_overflow ();
}
}
#endif
os_runtask->full_ctx = __FALSE;
os_runtask = p_new;
p_new->state = RUNNING;
#if (OS_ROBIN == 1)
if (p_new->full_ctx == __TRUE) {
os_tsk_robin = p_new;
}
#endif
tsk_unlock ();
} /* end of os_switch_tasks */
/*--------------------------- os_init_robin ---------------------------------*/
void os_init_robin (void) {
/* Initialize Round Robin timeout. */
#if (OS_ROBIN == 1)
os_robin_time = OS_ROBINTOUT;
#endif
}
/*--------------------------- os_chk_robin ----------------------------------*/
void os_chk_robin (void) {
/* Check if Round Robin timeout expired and switch to the next ready task.*/
/* This function is called from the "os_clock_demon()" task scheduler. */
#if (OS_ROBIN == 1)
P_TCB p_new;
if (os_rdy.p_lnk != os_tsk_robin) {
os_robin_time = os_time + OS_ROBINTOUT;
return;
}
if (os_robin_time == os_time) {
/* Round Robin timeout has expired. */
os_robin_time += OS_ROBINTOUT;
p_new = os_get_first (&os_rdy);
os_put_prio ((P_XCB)&os_rdy, p_new);
}
#endif
} /* end of os_chk_robin */
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -