修改如下:
-
/*------------------------------------------------------------------------------------------------
-
RL-ARM - RTX 源码汇总 Copyright (c) 2004-2010 KEIL - An ARM Company. All rights reserved
-
-
感谢党感谢政府,
-
本文件+rtx_config.c+svc_table.s(根据情况)加入工程, 工程的Target-->Operating System选择None
-
-
qiushui_007 于2011-3-3在V4.12的源码上汇总并在STM32和LM3S系列上实验成功(Email:xxg6688@163.com)
-
V4.12 Corrected: a problem in stack checking for Cortex-M library.
-
The stack was checked before the task context was completely stacked.
-
-
V4.13 Corrected: a problem in isr_mbx_receive() function for Cortex-M library.
-
If sending task was suspended on a full mailbox, a message was lost. (但代码未改变????)
-
Added: big endian RTX libraries for Cortex-M0, Cortex-M1, Cortex-M3 and Cortex-M4
-
-
Code (inc. data) RO Data RW Data ZI Data Debug Object Name
-
4808 256 0 37 96 0 rtx_cm3.o
-
4816 254 0 37 96 0 rtx_cm3.o
-
-
备注:
-
- 启动代码中在__Vectors之前增加如下, 并且屏蔽相关的输出和定义. stm32f10x_it.c中同样屏蔽同名的函数
-
IMPORT SVC_Handler
-
IMPORT PendSV_Handler
-
IMPORT SysTick_Handler ;RTX中的EXPORT
-
- RTX用户进程优先级1-254,(最高254; 最低1, 0和255为系统进程). 优先级可以相同.
-
- RTX系统创建了两个系统任务 os_clock_demon 和 os_idle_demon. 这两个任务经常是RTX内核所必需的。
-
- 对SysTick的操作: 比较相关节拍代码, uCOS可定义为1000(每个节拍为1ms), RTX经试验最大为100(每个节拍10ms)
-
-
//------------------- New/Modify -----------------------------------------*/
-
//#define SVCUSER //若定义此, 工程中必须加上svc_table.s
-
-
#define OS_MBOX_EN 1 /* Enable (1) or Disable (0) code generation for MAILBOXES */
-
#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */
-
#define OS_MUTEX_EN 1 /* Enable (1) or Disable (0) code generation for MUTEX */
-
#define OS_FLAG_EN 0 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
-
#define OS_TMR_EN 0 /* Enable (1) or Disable (0) code generation for TIMERS */
-
-
//---------------------------------------------------------------------------
-
-
/* Types */
-
typedef char S8;
-
typedef unsigned char U8;
-
typedef short S16;
-
typedef unsigned short U16;
-
typedef int S32;
-
typedef unsigned int U32;
-
typedef long long S64;
-
typedef unsigned long long U64;
-
typedef unsigned char BIT;
-
typedef unsigned int BOOL;
-
-
/* Definitions */
-
#define __TRUE 1
-
#define __FALSE 0
-
#define NULL ((void *) 0)
-
-
/* Values for 'state' */
-
#define INACTIVE 0
-
#define READY 1
-
#define RUNNING 2
-
#define WAIT_DLY 3
-
#define WAIT_ITV 4
-
#define WAIT_OR 5
-
#define WAIT_AND 6
-
#define WAIT_SEM 7
-
#define WAIT_MBX 8
-
#define WAIT_MUT 9
-
-
/* Return codes */
-
#define OS_R_TMO 0x01
-
#define OS_R_EVT 0x02
-
#define OS_R_SEM 0x03
-
#define OS_R_MBX 0x04
-
#define OS_R_MUT 0x05
-
#define OS_R_OK 0x00
-
#define OS_R_NOK 0xff
-
-
/* Error Codes */
-
#define OS_ERR_STK_OVF 1
-
#define OS_ERR_FIFO_OVF 2
-
#define OS_ERR_MBX_OVF 3
-
-
typedef void (*FUNCP)(void);
-
typedef U32 OS_TID;
-
typedef void *OS_ID;
-
typedef U32 OS_RESULT;
-
-
typedef struct OS_TCB {
-
/* General part: identical for all implementations. */
-
U8 cb_type; /* Control Block Type */
-
U8 state; /* Task state */
-
U8 prio; /* Execution priority */
-
U8 task_id; /* Task ID value for optimized TCB access */
-
struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */
-
struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */
-
struct OS_TCB *p_dlnk; /* Link pointer for delay list */
-
struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */
-
U16 delta_time; /* Time until time out */
-
U16 interval_time; /* Time interval for periodic waits */
-
U16 events; /* Event flags */
-
U16 waits; /* Wait flags */
-
void **msg; /* Direct message passing when task waits */
-
U8 ret_val; /* Return value upon completion of a wait */
-
-
/* Hardware dependant part: specific for CM processor */
-
U8 ret_upd; /* Updated return value */
-
U16 priv_stack; /* Private stack size, 0= system assigned */
-
U32 tsk_stack; /* Current task Stack pointer (R13) */
-
U32 *stack; /* Pointer to Task Stack memory block */
-
-
/* Task entry point used for uVision debugger */
-
FUNCP ptask; /* Task entry address */
-
} *P_TCB;
-
-
#define TCB_RETVAL 32 /* 'ret_val' offset */
-
#define TCB_RETUPD 33 /* 'ret_upd' offset */
-
#define TCB_TSTACK 36 /* 'tsk_stack' offset */
-
-
typedef struct OS_PSFE { /* Post Service Fifo Entry */
-
void *id; /* Object Identification */
-
U32 arg; /* Object Argument */
-
} *P_PSFE;
-
-
typedef struct OS_PSQ { /* Post Service Queue */
-
U8 first; /* FIFO Head Index */
-
U8 last; /* FIFO Tail Index */
-
U8 count; /* Number of stored items in FIFO */
-
U8 size; /* FIFO Size */
-
struct OS_PSFE q[1]; /* FIFO Content */
-
} *P_PSQ;
-
-
typedef struct OS_TSK {
-
P_TCB run; /* Current running task */
-
P_TCB new; /* Scheduled task to run */
-
} *P_TSK;
-
-
typedef struct OS_ROBIN { /* Round Robin Control */
-
P_TCB task; /* Round Robin task */
-
U16 time; /* Round Robin switch time */
-
U16 tout; /* Round Robin timeout */
-
} *P_ROBIN;
-
-
typedef struct OS_XCB {
-
U8 cb_type; /* Control Block Type */
-
struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */
-
struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */
-
struct OS_TCB *p_dlnk; /* Link pointer for delay list */
-
struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */
-
U16 delta_time; /* Time until time out */
-
} *P_XCB;
-
-
typedef struct OS_MCB {
-
U8 cb_type; /* Control Block Type */
-
U8 isr_st; /* State flag variable for isr functions */
-
struct OS_TCB *p_lnk; /* Chain of tasks waiting for message */
-
U16 first; /* Index of the message list begin */
-
U16 last; /* Index of the message list end */
-
U16 count; /* Actual number of stored messages */
-
U16 size; /* Maximum number of stored messages */
-
void *msg[1]; /* FIFO for Message pointers 1st element */
-
} *P_MCB;
-
-
typedef struct OS_SCB {
-
U8 cb_type; /* Control Block Type */
-
U16 tokens; /* Semaphore tokens */
-
struct OS_TCB *p_lnk; /* Chain of tasks waiting for tokens */
-
} *P_SCB;
-
-
typedef struct OS_MUCB {
-
U8 cb_type; /* Control Block Type */
-
U8 prio; /* Owner task default priority */
-
U16 level; /* Call nesting level */
-
struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */
-
struct OS_TCB *owner; /* Mutex owner task */
-
} *P_MUCB;
-
-
typedef struct OS_XTMR {
-
struct OS_TMR *next;
-
U16 tcnt;
-
} *P_XTMR;
-
-
typedef struct OS_TMR {
-
struct OS_TMR *next; /* Link pointer to Next timer */
-
U16 tcnt; /* Timer delay count */
-
U16 info; /* User defined call info */
-
} *P_TMR;
-
-
typedef struct OS_BM {
-
void *free; /* Pointer to first free memory block */
-
void *end; /* Pointer to memory block end */
-
U32 blk_size; /* Memory block size */
-
} *P_BM;
-
-
//----------------------------------------------------------------------------------------
-
-
#define INITIAL_xPSR 0x01000000
-
#define DEMCR_TRCENA 0x01000000
-
#define ITM_ITMENA 0x00000001
-
#define MAGIC_WORD 0xE25A2EA5
-
-
/* NVIC SysTick registers */
-
#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010))
-
#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014))
-
#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018))
-
#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04))
-
#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C))
-
#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20))
-
-
#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28);
-
#define OS_TINIT() NVIC_ST_RELOAD = os_trv;
-
NVIC_ST_CTRL = 0x0007;
-
NVIC_SYS_PRI3 |= 0xFFFF0000;
-
NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<1) & 0xFE000000;
-
#define OS_LOCK() NVIC_ST_CTRL = 0x0005;
-
#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007;
-
-
/* Core Debug registers */
-
#define DEMCR (*((volatile U32 *)0xE000EDFC))
-
-
/* ITM registers */
-
#define ITM_CONTROL (*((volatile U32 *)0xE0000E80))
-
#define ITM_ENABLE (*((volatile U32 *)0xE0000E00))
-
#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078))
-
#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C))
-
#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C))
-
#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C))
-
-
/* Functions */
-
#if defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)
-
#define rt_inc(p) while(__strex((__ldrex(p)+1),p))
-
#define rt_dec(p) while(__strex((__ldrex(p)-1),p))
-
#else
-
#define rt_inc(p) __disable_irq();(*p)++;__enable_irq();
-
#define rt_dec(p) __disable_irq();(*p)--;__enable_irq();
-
#endif
-
-
__inline U32 rt_inc_qi (U32 size, U8 *count, U8 *first) {
-
U32 cnt,c2;
-
#if defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)
-
do {
-
if ((cnt = __ldrex(count)) == size) {
-
__clrex();
-
return (cnt); }
-
} while (__strex(cnt+1, count));
-
do {
-
c2 = (cnt = __ldrex(first)) + 1;
-
if (c2 == size) c2 = 0;
-
} while (__strex(c2, first));
-
#else
-
__disable_irq();
-
if ((cnt = *count) < size) {
-
*count = cnt+1;
-
c2 = (cnt = *first) + 1;
-
if (c2 == size) c2 = 0;
-
*first = c2;
-
}
-
__enable_irq ();
-
#endif
-
return (cnt);
-
}
-
-
#define rt_tmr_init() OS_TINIT();
-
//void rt_init_stack (P_TCB p_TCB, FUNCP task_body);
-
//void rt_set_PSP (U32 stack);
-
//void os_set_env (void);
-
void *_alloc_box (void *box_mem);
-
int _free_box (void *box_mem, void *box);
-
-
void dbg_init (void);
-
void dbg_task_notify (P_TCB p_tcb, BOOL create);
-
void dbg_task_switch (U32 task_id);
-
-
#ifdef DBG_MSG
-
#define DBG_INIT() dbg_init()
-
#define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create)
-
#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new!=os_tsk.run))
-
dbg_task_switch(task_id)
-
#else
-
#define DBG_INIT()
-
#define DBG_TASK_NOTIFY(p_tcb,create)
-
#define DBG_TASK_SWITCH(task_id)
-
#endif
-
-
//OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait);
-
//void rt_evt_set (U16 event_flags, OS_TID task_id);
-
//void rt_evt_clr (U16 clear_flags, OS_TID task_id);
-
//void isr_evt_set (U16 event_flags, OS_TID task_id);
-
//U16 rt_evt_get (void);
-
void rt_evt_psh (P_TCB p_CB, U16 set_flags);
-
-
/* Functions */
-
void rt_switch_req (P_TCB p_new);
-
void rt_dispatch (P_TCB next_TCB);
-
void rt_block (U16 timeout, U8 block_state);
-
//void rt_tsk_pass (void);
-
//OS_TID rt_tsk_self (void);
-
//OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio);
-
//OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv);
-
//OS_RESULT rt_tsk_delete (OS_TID task_id);
-
//void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk);
-
-
//void rt_dly_wait (U16 delay_time);
-
//void rt_itv_set (U16 interval_time);
-
//void rt_itv_wait (void);
-
-
void rt_tmr_tick (void);
-
//OS_ID rt_tmr_create (U16 tcnt, U16 info);
-
//OS_ID rt_tmr_kill (OS_ID timer);
-
-
-
#define rt_init_box _init_box
-
#define rt_calloc_box _calloc_box
-
int _init_box (void *box_mem, U32 box_size, U32 blk_size);
-
void *rt_alloc_box (void *box_mem);
-
void * _calloc_box (void *box_mem);
-
int rt_free_box (void *box_mem, void *box);
-
-
//void rt_mbx_init (OS_ID mailbox, U16 mbx_size);
-
//OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout);
-
//OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout);
-
//OS_RESULT rt_mbx_check (OS_ID mailbox);
-
//void isr_mbx_send (OS_ID mailbox, void *p_msg);
-
//OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message);
-
void rt_mbx_psh (P_MCB p_CB, void *p_msg);
-
-
//void rt_sem_init (OS_ID semaphore, U16 token_count);
-
//OS_RESULT rt_sem_send (OS_ID semaphore);
-
//OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout);
-
//void isr_sem_send (OS_ID semaphore);
-
void rt_sem_psh (P_SCB p_CB);
-
-
//void rt_mut_init (OS_ID mutex);
-
//OS_RESULT rt_mut_release (OS_ID mutex);
-
//OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout);
-
-
#define os_psq ((P_PSQ)&os_fifo)
-
//void rt_tsk_lock (void);
-
//void rt_tsk_unlock (void);
-
void rt_psh_req (void);
-
void rt_pop_req (void);
-
void rt_systick (void);
-
void rt_stk_check (void);
-
-
//void rt_init_robin (void);
-
//void rt_chk_robin (void);
-
-
#define TCB 0
-
#define MCB 1
-
#define SCB 2
-
#define MUCB 3
-
#define HCB 4
-
/* Functions */
-
void rt_put_prio (P_XCB p_CB, P_TCB p_task);
-
P_TCB rt_get_first (P_XCB p_CB);
-
void rt_put_rdy_first (P_TCB p_task);
-
P_TCB rt_get_same_rdy_prio (void);
-
void rt_resort_prio (P_TCB p_task);
-
void rt_put_dly (P_TCB p_task, U16 delay);
-
void rt_dec_dly (void);
-
void rt_rmv_list (P_TCB p_task);
-
void rt_rmv_dly (P_TCB p_task);
-
void rt_psq_enq (OS_ID entry, U32 arg);
-
-
/* This is a fast macro generating in-line code */
-
#define rt_rdy_prio(void) (os_rdy.p_lnk->prio)
-
-
//--- rtx_config.h, Exported functions of RTX_Config.c. 相关的变量在rtx_config.c中定义
-
/* Definitions */
-
#define BOX_ALIGN_8 0x80000000
-
#define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3]
-
#define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2]
-
#define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8)
-
-
/* Variables */
-
extern U32 mp_tcb[]; //_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASKCNT);
-
extern U64 mp_stk[];
-
extern U32 os_fifo[];
-
extern void *os_active_TCB[];
-
-
/* Constants */
-
extern U16 const os_maxtaskrun; //U16 const os_maxtaskrun = OS_TASKCNT;
-
extern U32 const os_trv;
-
extern U8 const os_flags; //U8 const os_flags = OS_RUNPRIV;
-
extern U32 const os_stackinfo; //U32 const os_stackinfo = (OS_STKCHECK<<24)| (OS_PRIVCNT<<16) | (OS_STKSIZE*4);
-
extern U32 const os_rrobin;
-
//extern U32 const os_clockrate; //U32 const os_clockrate = OS_TICK;
-
extern U32 const os_timernum; //U32 const os_timernum = (OS_TIMER << 16) | OS_TIMERCNT;
-
extern U16 const mp_tcb_size; //U16 const mp_tcb_size = sizeof(mp_tcb);
-
extern U32 const mp_stk_size;
-
extern U32 const *m_tmr; //U32 const *m_tmr = &mp_tmr[0];
-
extern U16 const mp_tmr_size; //U16 const mp_tmr_size = sizeof(mp_tmr);
-
extern U8 const os_fifo_size;
-
-
/* Functions */
-
extern void os_idle_demon (void);
-
extern void os_tmr_call (U16 info);
-
extern void os_error (U32 err_code);
-
-
/*----------------------------------------------------------------------------
-
* Global Variables
-
*---------------------------------------------------------------------------*/
-
U16 os_time; // Free running system tick counter
-
struct OS_XTMR os_tmr; // User Timer list pointer
-
struct OS_TSK os_tsk; // Running and next task info.
-
struct OS_TCB os_idle_TCB; // Task Control Blocks of idle demon
-
static BIT os_lock;
-
static BIT os_psh_flag;
-
struct OS_XCB os_rdy; // List head of chained ready tasks
-
struct OS_XCB os_dly; // List head of chained delay tasks
-
struct OS_ROBIN os_robin;
-
-
//======================== HAL_CM3.c Start ==========================================================
-
BIT dbg_msg;
-
-
__asm void rt_set_PSP (U32 stack) {
-
MSR PSP,R0
-
BX LR
-
}
-
-
__asm void os_set_env (void) {
-
/* Switch to Unpriviliged/Priviliged Thread mode, use PSP. */
-
MOV R0,SP
-
MSR PSP,R0 ; PSP = MSP
-
LDR R0,=__cpp(&os_flags)
-
LDRB R0,[R0]
-
LSLS R0,#31
-
MOVNE R0,#0x02 ; Priviliged Thread mode, use PSP
-
MOVEQ R0,#0x03 ; Unpriviliged Thread mode, use PSP
-
MSR CONTROL,R0
-
BX LR
-
-
ALIGN
-
}
-
-
__asm void *_alloc_box (void *box_mem) {
-
/* Function wrapper for Unpriviliged/Priviliged mode. */
-
LDR R12,=__cpp(rt_alloc_box)
-
MRS R3,IPSR
-
LSLS R3,#24
-
BXNE R12
-
MRS R3,CONTROL
-
LSLS R3,#31
-
BXEQ R12
-
SVC 0
-
BX LR
-
-
ALIGN
-
}
-
-
__asm int _free_box (void *box_mem, void *box) {
-
/* Function wrapper for Unpriviliged/Priviliged mode. */
-
LDR R12,=__cpp(rt_free_box)
-
MRS R3,IPSR
-
LSLS R3,#24
-
BXNE R12
-
MRS R3,CONTROL
-
LSLS R3,#31
-
BXEQ R12
-
SVC 0
-
BX LR
-
-
ALIGN
-
}
-
-
__asm void SVC_Handler (void) {
-
PRESERVE8
-
-
#ifdef SVCUSER
-
IMPORT SVC_Count
-
IMPORT SVC_Table
-
#endif
-
IMPORT rt_stk_check
-
-
MRS R0,PSP ; Read PSP
-
LDR R1,[R0,#24] ; Read Saved PC from Stack
-
LDRH R1,[R1,#-2] ; Load Halfword
-
#ifdef SVCUSER
-
BICS R1,R1,#0xFF00 ; Extract SVC Number
-
BNE SVC_User
-
#endif
-
-
LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
-
BLX R12 ; Call SVC Function
-
-
MRS R12,PSP ; Read PSP
-
LDR R3,=__cpp(&os_tsk)
-
LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
-
CMP R1,R2
-
BEQ SVC_Exit ; no task switch
-
-
PUSH {R2,R3}
-
MOV R3,#1
-
CMP R1,#0 ; Runtask deleted?
-
STRBNE R3,[R1,#TCB_RETUPD] ; os_tsk.run->ret_upd = 1
-
STMDBNE R12!,{R4-R11} ; Save Old context
-
STRNE R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
-
BLNE rt_stk_check ; Check for Stack overflow
-
-
POP {R2,R3}
-
STR R2,[R3] ; os_tsk.run = os_tsk.new
-
-
LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
-
LDMIA R12!,{R4-R11} ; Restore New Context
-
LDRB R3,[R2,#TCB_RETUPD] ; Update ret_val?
-
MSR PSP,R12 ; Write PSP
-
-
CBZ R3,SVC_Return
-
LDRB R0,[R2,#TCB_RETVAL] ; Write os_tsk.new->ret_val
-
-
SVC_Exit
-
STR R0,[R12] ; Function return value
-
-
SVC_Return
-
MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
-
BX LR
-
-
/*------------------- User SVC ------------------------------*/
-
#ifdef SVCUSER
-
SVC_User
-
PUSH {R4,LR} ; Save Registers
-
LDR R2,=SVC_Count
-
LDR R2,[R2]
-
CMP R1,R2
-
BHI SVC_Done ; Overflow
-
-
LDR R4,=SVC_Table-4
-
LDR R4,[R4,R1,LSL #2] ; Load SVC Function Address
-
-
LDM R0,{R0-R3,R12} ; Read R0-R3,R12 from stack
-
BLX R4 ; Call SVC Function
-
-
MRS R12,PSP
-
STM R12,{R0-R3} ; Function return values
-
SVC_Done
-
POP {R4,PC} ; RETI
-
-
ALIGN
-
#endif
-
}
-
-
__asm void Sys_Handler (void) {
-
PRESERVE8
-
-
EXPORT SysTick_Handler
-
EXPORT PendSV_Handler
-
-
PendSV_Handler
-
BL __cpp(rt_pop_req)
-
-
Sys_Switch
-
LDR R3,=__cpp(&os_tsk)
-
LDM R3,{R1,R2} ; os_tsk.run, os_tsk.new
-
CMP R1,R2
-
BEQ SysExit
-
-
PUSH {R2,R3}
-
MOV R3,#0
-
STRB R3,[R1,#TCB_RETUPD] ; os_tsk.run->ret_upd = 0
-
MRS R12,PSP ; Read PSP
-
STMDB R12!,{R4-R11} ; Save Old context
-
STR R12,[R1,#TCB_TSTACK] ; Update os_tsk.run->tsk_stack
-
BL rt_stk_check ; Check for Stack overflow
-
-
POP {R2,R3}
-
STR R2,[R3] ; os_tsk.run = os_tsk.new
-
-
LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack
-
LDMIA R12!,{R4-R11} ; Restore New Context
-
MSR PSP,R12 ; Write PSP
-
-
LDRB R3,[R2,#TCB_RETUPD] ; Update ret_val?
-
CBZ R3,SysExit
-
LDRB R3,[R2,#TCB_RETVAL] ; Write os_tsk.new->ret_val
-
STR R3,[R12]
-
SysExit
-
MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value
-
BX LR ; Return to Thread Mode
-
-
SysTick_Handler
-
BL __cpp(rt_systick)
-
B Sys_Switch
-
-
ALIGN
-
}
-
-
void rt_init_stack (P_TCB p_TCB, FUNCP task_body) {
-
/* Prepare TCB and saved context for a first time start of a task. */
-
U32 *stk,i,size;
-
-
/* Prepare a complete interrupt frame for first task start */
-
size = p_TCB->priv_stack >> 2;
-
if (size == 0) {
-
size = (U16)os_stackinfo >> 2;
-
}
-
-
/* Write to the top of stack. */
-
stk = &p_TCB->stack[size];
-
-
/* Auto correct to 8-byte ARM stack alignment. */
-
if ((U32)stk & 0x04) {
-
stk--;
-
}
-
-
stk -= 16;
-
-
/* Default xPSR and initial PC */
-
stk[15] = INITIAL_xPSR;
-
stk[14] = (U32)task_body;
-
-
/* Clear R1-R12,LR registers. */
-
for (i = 0; i < 14; i++) {
-
stk[i] = 0;
-
}
-
-
/* Assign a void pointer to R0. */
-
stk[8] = (U32)p_TCB->msg;
-
-
/* Initial Task stack pointer. */
-
p_TCB->tsk_stack = (U32)stk;
-
-
/* Task entry point. */
-
p_TCB->ptask = task_body;
-
-
/* Set a magic word for checking of stack overflow. */
-
p_TCB->stack[0] = MAGIC_WORD;
-
}
-
-
void dbg_init (void) {
-
if ((DEMCR & DEMCR_TRCENA) &&
-
(ITM_CONTROL & ITM_ITMENA) &&
-
(ITM_ENABLE & (1UL << 31))) {
-
dbg_msg = __TRUE;
-
}
-
}
-
-
void dbg_task_notify (P_TCB p_tcb, BOOL create) {
-
while (ITM_PORT31_U32 == 0);
-
ITM_PORT31_U32 = (U32)p_tcb->ptask;
-
while (ITM_PORT31_U32 == 0);
-
ITM_PORT31_U16 = (create << 8) | p_tcb->task_id;
-
}
-
-
void dbg_task_switch (U32 task_id) {
-
while (ITM_PORT31_U32 == 0);
-
ITM_PORT31_U8 = task_id;
-
}
-
//======================== HAL_CM3.c End ==========================================================
-
-
//==================== rt_Robin.c ===============================================================
-
__weak void rt_init_robin (void) {
-
/* Initialize Round Robin variables. */
-
os_robin.task = NULL;
-
os_robin.tout = (U16)os_rrobin;
-
}
-
-
__weak void rt_chk_robin (void) {
-
/* Check if Round Robin timeout expired and switch to the next ready task.*/
-
P_TCB p_new;
-
-
if (os_robin.task != os_rdy.p_lnk) {
-
/* New task was suspended, reset Round Robin timeout. */
-
os_robin.task = os_rdy.p_lnk;
-
os_robin.time = os_time + os_robin.tout - 1;
-
}
-
if (os_robin.time == os_time) {
-
/* Round Robin timeout has expired, swap Robin tasks. */
-
os_robin.task = NULL;
-
p_new = rt_get_first (&os_rdy);
-
rt_put_prio ((P_XCB)&os_rdy, p_new);
-
}
-
}
-
//=========================================================================================
-
-
//--- rt_system.c
-
#if 0
-
__asm void $$RTX$$version (void) {
-
/* Export a version number symbol for a version control. */
-
EXPORT __RTX_ARM_VER
-
__RTX_ARM_VER EQU 0x412
-
}
-
#endif
-
-
void rt_tsk_lock (void) {
-
/* Lock out tasks: prevents task switching by locking out scheduler */
-
OS_LOCK();
-
os_lock = __TRUE;
-
}
-
-
void rt_tsk_unlock (void) {
-
/* Enable System Tick Timer Interrupts. */
-
OS_UNLOCK();
-
os_lock = __FALSE;
-
if (os_psh_flag) {
-
OS_PEND_IRQ ();
-
}
-
}
-
-
void rt_psh_req (void) {
-
/* Initiate a post service handling request if required. */
-
if (os_lock == __FALSE) {
-
OS_PEND_IRQ ();
-
}
-
else {
-
os_psh_flag = __TRUE;
-
}
-
}
-
-
void rt_pop_req (void) {
-
/* Process an ISR post service requests. */
-
struct OS_XCB *p_CB;
-
P_TCB next;
-
U32 idx;
-
-
os_tsk.run->state = READY;
-
rt_put_rdy_first (os_tsk.run);
-
-
os_psh_flag = __FALSE;
-
idx = os_psq->last;
-
while (os_psq->count) {
-
p_CB = os_psq->q[idx].id;
-
if (p_CB->cb_type == TCB) {
-
/* Is of TCB type */
-
rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
-
}
-
else if (p_CB->cb_type == MCB) {
-
/* Is of MCB type */
-
rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
-
}
-
else {
-
/* Must be of SCB type */
-
rt_sem_psh ((P_SCB)p_CB);
-
}
-
if (++idx == os_psq->size) idx = 0;
-
rt_dec (&os_psq->count);
-
}
-
os_psq->last = idx;
-
-
next = rt_get_first (&os_rdy);
-
rt_switch_req (next);
-
}
-
-
void rt_systick (void) {
-
/* Check for system clock update, suspend running task. */
-
P_TCB next;
-
-
os_tsk.run->state = READY;
-
rt_put_rdy_first (os_tsk.run);
-
-
/* Check Round Robin timeout. */
-
rt_chk_robin ();
-
-
/* Update delays. */
-
os_time++;
-
rt_dec_dly ();
-
-
/* Check the user timers. */
-
#if OS_TMR_EN > 0
-
rt_tmr_tick ();
-
#endif
-
-
/* Switch back to highest ready task */
-
next = rt_get_first (&os_rdy);
-
rt_switch_req (next);
-
}
-
-
__weak void rt_stk_check (void) {
-
/* Check for stack overflow. */
-
if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
-
(os_tsk.run->stack[0] != MAGIC_WORD)) {
-
os_error (OS_ERR_STK_OVF);
-
}
-
}
-
//=========================================================================================
-
-
//--- rt_task.c
-
static OS_TID rt_get_TID (void) {
-
U32 tid;
-
-
for (tid = 1; tid <= os_maxtaskrun; tid++) {
-
if (os_active_TCB[tid-1] == NULL) {
-
return ((OS_TID)tid);
-
}
-
}
-
return (0);
-
}
-
-
static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) {
-
/* Initialize general part of the Task Control Block. */
-
p_TCB->cb_type = TCB;
-
p_TCB->state = READY;
-
p_TCB->prio = priority;
-
p_TCB->p_lnk = NULL;
-
p_TCB->p_rlnk = NULL;
-
p_TCB->p_dlnk = NULL;
-
p_TCB->p_blnk = NULL;
-
p_TCB->delta_time = 0;
-
p_TCB->interval_time = 0;
-
p_TCB->events = 0;
-
p_TCB->waits = 0;
-
p_TCB->ret_val = OS_R_OK;
-
p_TCB->ret_upd = 0;
-
-
if (p_TCB->priv_stack == 0) {
-
/* Allocate the memory space for the stack. */
-
p_TCB->stack = rt_alloc_box (mp_stk);
-
}
-
rt_init_stack (p_TCB, task_body);
-
}
-
-
void rt_switch_req (P_TCB p_new) {
-
/* Switch to next task (identified by "p_new"). */
-
os_tsk.new = p_new;
-
p_new->state = RUNNING;
-
DBG_TASK_SWITCH(p_new->task_id);
-
}
-
-
void rt_dispatch (P_TCB next_TCB) {
-
/* Dispatch next task if any identified or dispatch highest ready task */
-
/* "next_TCB" identifies a task to run or has value NULL (=no next task) */
-
if (next_TCB == NULL) {
-
/* Running task was blocked: continue with highest ready task */
-
next_TCB = rt_get_first (&os_rdy);
-
rt_switch_req (next_TCB);
-
}
-
else {
-
/* Check which task continues */
-
if (next_TCB->prio > os_tsk.run->prio) {
-
/* preempt running task */
-
rt_put_rdy_first (os_tsk.run);
-
os_tsk.run->state = READY;
-
rt_switch_req (next_TCB);
-
}
-
else {
-
/* put next task into ready list, no task switch takes place */
-
next_TCB->state = READY;
-
rt_put_prio (&os_rdy, next_TCB);
-
}
-
}
-
}
-
-
void rt_block (U16 timeout, U8 block_state) {
-
/* Block running task and choose next ready task. */
-
/* "timeout" sets a time-out value or is 0xffff (=no time-out). */
-
/* "block_state" defines the appropriate task state */
-
P_TCB next_TCB;
-
-
if (timeout) {
-
if (timeout < 0xffff) {
-
rt_put_dly (os_tsk.run, timeout);
-
}
-
os_tsk.run->state = block_state;
-
next_TCB = rt_get_first (&os_rdy);
-
rt_switch_req (next_TCB);
-
}
-
}
-
-
void rt_tsk_pass (void) {
-
/* Allow tasks of same priority level to run cooperatively.*/
-
P_TCB p_new;
-
-
p_new = rt_get_same_rdy_prio();
-
if (p_new != NULL) {
-
rt_put_prio ((P_XCB)&os_rdy, os_tsk.run);
-
os_tsk.run->state = READY;
-
rt_switch_req (p_new);
-
}
-
}
-
-
OS_TID rt_tsk_self (void) {
-
/* Return own task identifier value. */
-
if (os_tsk.run == NULL) {
-
return (0);
-
}
-
return (os_tsk.run->task_id);
-
}
-
-
OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) {
-
/* Change execution priority of a task to "new_prio". */
-
P_TCB p_task;
-
-
if (task_id == 0) {
-
/* Change execution priority of calling task. */
-
os_tsk.run->prio = new_prio;
-
run:if (rt_rdy_prio() > new_prio) {
-
rt_put_prio (&os_rdy, os_tsk.run);
-
os_tsk.run->state = READY;
-
os_tsk.run->ret_val = OS_R_OK;
-
rt_dispatch (NULL);
-
}
-
return (OS_R_OK);
-
}
-
-
/* Find the task in the "os_active_TCB" array. */
-
if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
-
/* Task with "task_id" not found or not started. */
-
return (OS_R_NOK);
-
}
-
p_task = os_active_TCB[task_id-1];
-
p_task->prio = new_prio;
-
if (p_task == os_tsk.run) {
-
goto run;
-
}
-
rt_resort_prio (p_task);
-
if (p_task->state == READY) {
-
/* Task enqueued in a ready list. */
-
p_task = rt_get_first (&os_rdy);
-
os_tsk.run->ret_val = OS_R_OK;
-
rt_dispatch (p_task);
-
}
-
return (OS_R_OK);
-
}
-
-
OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) {
-
/* Start a new task declared with "task". */
-
P_TCB task_context;
-
U32 i;
-
-
/* Priority 0 is reserved for idle */
-
if ((prio_stksz & 0xFF) == 0) {
-
prio_stksz += 1;
-
}
-
task_context = rt_alloc_box (mp_tcb);
-
if (task_context == NULL) {
-
return (0);
-
}
-
/* If "size != 0" use a private user provided stack. */
-
task_context->stack = stk;
-
task_context->priv_stack = prio_stksz >> 8;
-
/* Pass parameter 'argv' to 'rt_init_context' */
-
task_context->msg = argv;
-
/* For 'size == 0' system allocates the user stack from the memory pool. */
-
rt_init_context (task_context, prio_stksz & 0xFF, task);
-
-
/* Find a free entry in 'os_active_TCB' table. */
-
i = rt_get_TID ();
-
os_active_TCB[i-1] = task_context;
-
task_context->task_id = i;
-
DBG_TASK_NOTIFY(task_context, __TRUE);
-
rt_dispatch (task_context);
-
os_tsk.run->ret_val = i;
-
return ((OS_TID)i);
-
}
-
-
OS_RESULT rt_tsk_delete (OS_TID task_id) {
-
/* Terminate the task identified with "task_id". */
-
P_TCB task_context;
-
-
if (task_id == 0 || task_id == os_tsk.run->task_id) {
-
/* Terminate itself. */
-
os_tsk.run->state = INACTIVE;
-
os_active_TCB[os_tsk.run->task_id-1] = NULL;
-
rt_free_box (mp_stk, os_tsk.run->stack);
-
os_tsk.run->stack = NULL;
-
DBG_TASK_NOTIFY(os_tsk.run, __FALSE);
-
rt_free_box (mp_tcb, os_tsk.run);
-
os_tsk.run = NULL;
-
rt_dispatch (NULL);
-
/* The program should never come to this point. */
-
}
-
else {
-
/* Find the task in the "os_active_TCB" array. */
-
if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
-
/* Task with "task_id" not found or not started. */
-
return (OS_R_NOK);
-
}
-
task_context = os_active_TCB[task_id-1];
-
rt_rmv_list (task_context);
-
rt_rmv_dly (task_context);
-
os_active_TCB[task_id-1] = NULL;
-
rt_free_box (mp_stk, task_context->stack);
-
task_context->stack = NULL;
-
DBG_TASK_NOTIFY(task_context, __FALSE);
-
rt_free_box (mp_tcb, task_context);
-
}
-
return (OS_R_OK);
-
}
-
-
void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) {
-
/* Initialize system and start up task declared with "first_task". */
-
U32 i;
-
-
DBG_INIT();
-
-
/* Initialize dynamic memory and task TCB pointers to NULL. */
-
for (i = 0; i < os_maxtaskrun; i++) {
-
os_active_TCB[i] = NULL;
-
}
-
rt_init_box (&mp_tcb, mp_tcb_size, sizeof(struct OS_TCB));
-
rt_init_box (&mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo));
-
#if (os_timernum & 0xff) > 0
-
rt_init_box ((U32 *)m_tmr, mp_tmr_size, sizeof(struct OS_TMR));
-
#endif
-
-
/* Set up TCB of idle demon */
-
os_idle_TCB.task_id = 255;
-
os_idle_TCB.priv_stack = 0;
-
rt_init_context (&os_idle_TCB, 0, os_idle_demon);
-
-
/* Set up ready list: initially empty */
-
os_rdy.cb_type = HCB;
-
os_rdy.p_lnk = NULL;
-
/* Set up delay list: initially empty */
-
os_dly.cb_type = HCB;
-
os_dly.p_dlnk = NULL;
-
os_dly.p_blnk = NULL;
-
os_dly.delta_time = 0;
-
-
/* Fix SP and systemvariables to assume idle task is running */
-
/* Transform main program into idle task by assuming idle TCB */
-
rt_set_PSP (os_idle_TCB.tsk_stack+32);
-
os_tsk.run = &os_idle_TCB;
-
os_tsk.run->state = RUNNING;
-
-
/* Initialize ps queue */
-
os_psq->first = 0;
-
os_psq->last = 0;
-
os_psq->size = os_fifo_size;
-
-
/* Intitialize system clock timer */
-
rt_tmr_init ();
-
rt_init_robin ();
-
-
/* Start up first user task before entering the endless loop */
-
rt_tsk_create (first_task, prio_stksz, stk, NULL);
-
}
-
//=========================================================================================
-
-
//--- rt_time.c ----------------------------------------------------------
-
void rt_dly_wait (U16 delay_time) {
-
/* Delay task by "delay_time" */
-
rt_block (delay_time, WAIT_DLY);
-
}
-
-
void rt_itv_set (U16 interval_time) {
-
/* Set interval length and define start of first interval */
-
os_tsk.run->interval_time = interval_time;
-
os_tsk.run->delta_time = interval_time + os_time;
-
}
-
-
void rt_itv_wait (void) {
-
/* Wait for interval end and define start of next one */
-
U16 delta;
-
-
delta = os_tsk.run->delta_time - os_time;
-
os_tsk.run->delta_time += os_tsk.run->interval_time;
-
if ((delta & 0x8000) == 0) {
-
rt_block (delta, WAIT_ITV);
-
}
-
}
-
//=========================================================================================
-
-
//--- rt_membox.c
-
int _init_box (void *box_mem, U32 box_size, U32 blk_size) {
-
/* Initialize memory block system, returns 0 if OK, 1 if fails. */
-
void *end;
-
void *blk;
-
void *next;
-
U32 sizeof_bm;
-
-
/* Create memory structure. */
-
if (blk_size & BOX_ALIGN_8) {
-
/* Memory blocks 8-byte aligned. */
-
blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7;
-
sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7;
-
}
-
else {
-
/* Memory blocks 4-byte aligned. */
-
blk_size = (blk_size + 3) & ~3;
-
sizeof_bm = sizeof (struct OS_BM);
-
}
-
if (blk_size == 0) {
-
return (1);
-
}
-
if ((blk_size + sizeof_bm) > box_size) {
-
return (1);
-
}
-
/* Create a Memory structure. */
-
blk = ((U8 *) box_mem) + sizeof_bm;
-
((P_BM) box_mem)->free = blk;
-
end = ((U8 *) box_mem) + box_size;
-
((P_BM) box_mem)->end = end;
-
((P_BM) box_mem)->blk_size = blk_size;
-
-
/* Link all free blocks using offsets. */
-
end = ((U8 *) end) - blk_size;
-
while (1) {
-
next = ((U8 *) blk) + blk_size;
-
if (next > end) break;
-
*((void **)blk) = next;
-
blk = next;
-
}
-
/* end marker */
-
*((void **)blk) = 0;
-
return (0);
-
}
-
-
void *rt_alloc_box (void *box_mem) {
-
/* Allocate a memory block and return start address. */
-
void **free;
-
int irq_dis;
-
-
irq_dis = __disable_irq ();
-
free = ((P_BM) box_mem)->free;
-
if (free) {
-
((P_BM) box_mem)->free = *free;
-
}
-
if (!irq_dis) __enable_irq ();
-
return (free);
-
}
-
-
void *_calloc_box (void *box_mem) {
-
/* Allocate a 0-initialized memory block and return start address. */
-
void *free;
-
U32 *p;
-
U32 i;
-
-
free = _alloc_box (box_mem);
-
if (free) {
-
p = free;
-
for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) {
-
*p = 0;
-
p++;
-
}
-
}
-
return (free);
-
}
-
-
int rt_free_box (void *box_mem, void *box) {
-
/* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */
-
int irq_dis;
-
-
if (box < box_mem || box > ((P_BM) box_mem)->end) {
-
return (1);
-
}
-
irq_dis = __disable_irq ();
-
*((void **)box) = ((P_BM) box_mem)->free;
-
((P_BM) box_mem)->free = box;
-
if (!irq_dis) __enable_irq ();
-
return (0);
-
}
-
//==============================================================================================
-
-
//----------------------------- rt_List.c -------------------------------------------
-
void rt_put_prio (P_XCB p_CB, P_TCB p_task) {
-
/* Put task identified with "p_task" into list ordered by priority. */
-
/* "p_CB" points to head of list; list has always an element at end with */
-
/* a priority less than "p_task->prio". */
-
P_TCB p_CB2;
-
U32 prio;
-
BOOL sem_mbx = __FALSE;
-
-
if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) {
-
sem_mbx = __TRUE;
-
}
-
prio = p_task->prio;
-
p_CB2 = p_CB->p_lnk;
-
/* Search for an entry in the list */
-
while (p_CB2 != NULL && prio <= p_CB2->prio) {
-
p_CB = (P_XCB)p_CB2;
-
p_CB2 = p_CB2->p_lnk;
-
}
-
/* Entry found, insert the task into the list */
-
p_task->p_lnk = p_CB2;
-
p_CB->p_lnk = p_task;
-
if (sem_mbx) {
-
if (p_CB2 != NULL) {
-
p_CB2->p_rlnk = p_task;
-
}
-
p_task->p_rlnk = (P_TCB)p_CB;
-
}
-
else {
-
p_task->p_rlnk = NULL;
-
}
-
}
-
-
P_TCB rt_get_first (P_XCB p_CB) {
-
/* Get task at head of list: it is the task with highest priority. */
-
/* "p_CB" points to head of list. */
-
P_TCB p_first;
-
-
p_first = p_CB->p_lnk;
-
p_CB->p_lnk = p_first->p_lnk;
-
if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) {
-
if (p_first->p_lnk != NULL) {
-
p_first->p_lnk->p_rlnk = (P_TCB)p_CB;
-
p_first->p_lnk = NULL;
-
}
-
p_first->p_rlnk = NULL;
-
}
-
else {
-
p_first->p_lnk = NULL;
-
}
-
return (p_first);
-
}
-
-
void rt_put_rdy_first (P_TCB p_task) {
-
/* Put task identified with "p_task" at the head of the ready list. The */
-
/* task must have at least a priority equal to highest priority in list. */
-
p_task->p_lnk = os_rdy.p_lnk;
-
p_task->p_rlnk = NULL;
-
os_rdy.p_lnk = p_task;
-
}
-
-
P_TCB rt_get_same_rdy_prio (void) {
-
/* Remove a task of same priority from ready list if any exists. Other- */
-
/* wise return NULL. */
-
P_TCB p_first;
-
-
p_first = os_rdy.p_lnk;
-
if (p_first->prio == os_tsk.run->prio) {
-
os_rdy.p_lnk = os_rdy.p_lnk->p_lnk;
-
return (p_first);
-
}
-
return (NULL);
-
}
-
-
void rt_resort_prio (P_TCB p_task) {
-
/* Re-sort ordered lists after the priority of 'p_task' has changed. */
-
P_TCB p_CB;
-
-
if (p_task->p_rlnk == NULL) {
-
if (p_task->state == READY) {
-
/* Task is chained into READY list. */
-
p_CB = (P_TCB)&os_rdy;
-
goto res;
-
}
-
}
-
else {
-
p_CB = p_task->p_rlnk;
-
while (p_CB->cb_type == TCB) {
-
/* Find a header of this task chain list. */
-
p_CB = p_CB->p_rlnk;
-
}
-
res:rt_rmv_list (p_task);
-
rt_put_prio ((P_XCB)p_CB, p_task);
-
}
-
}
-
-
void rt_put_dly (P_TCB p_task, U16 delay) {
-
/* Put a task identified with "p_task" into chained delay wait list using */
-
/* a delay value of "delay". */
-
P_TCB p;
-
U32 delta,idelay = delay;
-
-
p = (P_TCB)&os_dly;
-
if (p->p_dlnk == NULL) {
-
/* Delay list empty */
-
delta = 0;
-
goto last;
-
}
-
delta = os_dly.delta_time;
-
while (delta < idelay) {
-
if (p->p_dlnk == NULL) {
-
/* End of list found */
-
last: p_task->p_dlnk = NULL;
-
p->p_dlnk = p_task;
-
p_task->p_blnk = p;
-
p->delta_time = (U16)(idelay - delta);
-
p_task->delta_time = 0;
-
return;
-
}
-
p = p->p_dlnk;
-
delta += p->delta_time;
-
}
-
/* Right place found */
-
p_task->p_dlnk = p->p_dlnk;
-
p->p_dlnk = p_task;
-
p_task->p_blnk = p;
-
if (p_task->p_dlnk != NULL) {
-
p_task->p_dlnk->p_blnk = p_task;
-
}
-
p_task->delta_time = (U16)(delta - idelay);
-
p->delta_time -= p_task->delta_time;
-
}
-
-
void rt_dec_dly (void) {
-
/* Decrement delta time of list head: remove tasks having a value of zero.*/
-
P_TCB p_rdy;
-
-
if (os_dly.p_dlnk == NULL) {
-
return;
-
}
-
os_dly.delta_time--;
-
while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) {
-
p_rdy = os_dly.p_dlnk;
-
if (p_rdy->p_rlnk != NULL) {
-
/* Task is really enqueued, remove task from semaphore/mailbox */
-
/* timeout waiting list. */
-
p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk;
-
if (p_rdy->p_lnk != NULL) {
-
p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk;
-
p_rdy->p_lnk = NULL;
-
}
-
p_rdy->p_rlnk = NULL;
-
}
-
rt_put_prio (&os_rdy, p_rdy);
-
os_dly.delta_time = p_rdy->delta_time;
-
if (p_rdy->state == WAIT_ITV) {
-
/* Calculate the next time for interval wait. */
-
p_rdy->delta_time = p_rdy->interval_time + os_time;
-
}
-
p_rdy->state = READY;
-
p_rdy->ret_val = OS_R_TMO;
-
os_dly.p_dlnk = p_rdy->p_dlnk;
-
if (p_rdy->p_dlnk != NULL) {
-
p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly;
-
p_rdy->p_dlnk = NULL;
-
}
-
p_rdy->p_blnk = NULL;
-
}
-
}
-
-
void rt_rmv_list (P_TCB p_task) {
-
/* Remove task identified with "p_task" from ready, semaphore or mailbox */
-
/* waiting list if enqueued. */
-
P_TCB p_b;
-
-
if (p_task->p_rlnk != NULL) {
-
/* A task is enqueued in semaphore / mailbox waiting list. */
-
p_task->p_rlnk->p_lnk = p_task->p_lnk;
-
if (p_task->p_lnk != NULL) {
-
p_task->p_lnk->p_rlnk = p_task->p_rlnk;
-
}
-
return;
-
}
-
-
p_b = (P_TCB)&os_rdy;
-
while (p_b != NULL) {
-
/* Search the ready list for task "p_task" */
-
if (p_b->p_lnk == p_task) {
-
p_b->p_lnk = p_task->p_lnk;
-
return;
-
}
-
p_b = p_b->p_lnk;
-
}
-
}
-
-
void rt_rmv_dly (P_TCB p_task) {
-
/* Remove task identified with "p_task" from delay list if enqueued. */
-
P_TCB p_b;
-
-
p_b = p_task->p_blnk;
-
if (p_b != NULL) {
-
/* Task is really enqueued */
-
p_b->p_dlnk = p_task->p_dlnk;
-
if (p_task->p_dlnk != NULL) {
-
/* 'p_task' is in the middle of list */
-
p_b->delta_time += p_task->delta_time;
-
p_task->p_dlnk->p_blnk = p_b;
-
p_task->p_dlnk = NULL;
-
}
-
else {
-
/* 'p_task' is at the end of list */
-
p_b->delta_time = 0;
-
}
-
p_task->p_blnk = NULL;
-
}
-
}
-
-
void rt_psq_enq (OS_ID entry, U32 arg) {
-
/* Insert post service request "entry" into ps-queue. */
-
U32 idx;
-
-
idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first);
-
if (idx < os_psq->size) {
-
os_psq->q[idx].id = entry;
-
os_psq->q[idx].arg = arg;
-
}
-
else {
-
os_error (OS_ERR_FIFO_OVF);
-
}
-
}
-
//==================================================================================
-
-
//---------------- rt_Semaphore.c --------------------------------------------------
-
#if OS_SEM_EN > 0
-
void rt_sem_init (OS_ID semaphore, U16 token_count) {
-
/* Initialize a semaphore */
-
P_SCB p_SCB = semaphore;
-
-
p_SCB->cb_type = SCB;
-
p_SCB->p_lnk = NULL;
-
p_SCB->tokens = token_count;
-
}
-
-
OS_RESULT rt_sem_send (OS_ID semaphore) {
-
/* Return a token to semaphore */
-
P_SCB p_SCB = semaphore;
-
P_TCB p_TCB;
-
-
if (p_SCB->p_lnk != NULL) {
-
/* A task is waiting for token */
-
p_TCB = rt_get_first ((P_XCB)p_SCB);
-
p_TCB->ret_val = OS_R_SEM;
-
rt_rmv_dly (p_TCB);
-
rt_dispatch (p_TCB);
-
os_tsk.run->ret_val = OS_R_OK;
-
}
-
else {
-
/* Store token. */
-
p_SCB->tokens++;
-
}
-
return (OS_R_OK);
-
}
-
-
OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) {
-
/* Obtain a token; possibly wait for it */
-
P_SCB p_SCB = semaphore;
-
-
if (p_SCB->tokens) {
-
p_SCB->tokens--;
-
return (OS_R_OK);
-
}
-
/* No token available: wait for one */
-
if (timeout == 0) {
-
return (OS_R_TMO);
-
}
-
if (p_SCB->p_lnk != NULL) {
-
rt_put_prio ((P_XCB)p_SCB, os_tsk.run);
-
}
-
else {
-
p_SCB->p_lnk = os_tsk.run;
-
os_tsk.run->p_lnk = NULL;
-
os_tsk.run->p_rlnk = (P_TCB)p_SCB;
-
}
-
rt_block(timeout, WAIT_SEM);
-
return (OS_R_TMO);
-
}
-
-
void isr_sem_send (OS_ID semaphore) {
-
/* Same function as "os_sem"send", but to be called by ISRs */
-
P_SCB p_SCB = semaphore;
-
-
rt_psq_enq (p_SCB, 0);
-
rt_psh_req ();
-
}
-
#endif
-
-
void rt_sem_psh (P_SCB p_CB) {
-
/* Check if task has to be waken up */
-
P_TCB p_TCB;
-
-
if (p_CB->p_lnk != NULL) {
-
/* A task is waiting for token */
-
p_TCB = rt_get_first ((P_XCB)p_CB);
-
rt_rmv_dly (p_TCB);
-
p_TCB->state = READY;
-
p_TCB->ret_val = OS_R_SEM;
-
rt_put_prio (&os_rdy, p_TCB);
-
}
-
else {
-
/* Store token */
-
p_CB->tokens++;
-
}
-
}
-
//=========================================================================================
-
-
//----------------------- rt_Mutex.c --------------------------------------------------
-
#if OS_MUTEX_EN > 0
-
void rt_mut_init (OS_ID mutex) {
-
/* Initialize a mutex object */
-
P_MUCB p_MCB = mutex;
-
-
p_MCB->cb_type = MUCB;
-
p_MCB->prio = 0;
-
p_MCB->level = 0;
-
p_MCB->p_lnk = NULL;
-
p_MCB->owner = NULL;
-
}
-
-
OS_RESULT rt_mut_release (OS_ID mutex) {
-
/* Release a mutex object */
-
P_MUCB p_MCB = mutex;
-
P_TCB p_TCB;
-
-
if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) {
-
/* Unbalanced mutex release or task is not the owner */
-
return (OS_R_NOK);
-
}
-
if (--p_MCB->level != 0) {
-
return (OS_R_OK);
-
}
-
/* Restore owner task's priority. */
-
os_tsk.run->prio = p_MCB->prio;
-
if (p_MCB->p_lnk != NULL) {
-
/* A task is waiting for mutex. */
-
p_TCB = rt_get_first ((P_XCB)p_MCB);
-
p_TCB->ret_val = OS_R_MUT;
-
rt_rmv_dly (p_TCB);
-
/* A waiting task becomes the owner of this mutex. */
-
p_MCB->level = 1;
-
p_MCB->owner = p_TCB;
-
p_MCB->prio = p_TCB->prio;
-
/* Priority inversion, check which task continues. */
-
if (os_tsk.run->prio >= rt_rdy_prio()) {
-
rt_dispatch (p_TCB);
-
}
-
else {
-
/* Ready task has higher priority than running task. */
-
rt_put_prio (&os_rdy, os_tsk.run);
-
rt_put_prio (&os_rdy, p_TCB);
-
os_tsk.run->state = READY;
-
p_TCB->state = READY;
-
rt_dispatch (NULL);
-
}
-
os_tsk.run->ret_val = OS_R_OK;
-
}
-
else {
-
/* Check if own priority raised by priority inversion. */
-
if (rt_rdy_prio() > os_tsk.run->prio) {
-
rt_put_prio (&os_rdy, os_tsk.run);
-
os_tsk.run->state = READY;
-
rt_dispatch (NULL);
-
os_tsk.run->ret_val = OS_R_OK;
-
}
-
}
-
return (OS_R_OK);
-
}
-
-
OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) {
-
/* Wait for a mutex, continue when mutex is free. */
-
P_MUCB p_MCB = mutex;
-
-
if (p_MCB->level == 0) {
-
p_MCB->owner = os_tsk.run;
-
p_MCB->prio = os_tsk.run->prio;
-
goto inc;
-
}
-
if (p_MCB->owner == os_tsk.run) {
-
/* OK, running task is the owner of this mutex. */
-
inc:p_MCB->level++;
-
return (OS_R_OK);
-
}
-
/* Mutex owned by another task, wait until released. */
-
if (timeout == 0) {
-
return (OS_R_TMO);
-
}
-
/* Raise the owner task priority if lower than current priority. */
-
/* This priority inversion is called priority inheritance. */
-
if (p_MCB->prio < os_tsk.run->prio) {
-
p_MCB->owner->prio = os_tsk.run->prio;
-
rt_resort_prio (p_MCB->owner);
-
}
-
if (p_MCB->p_lnk != NULL) {
-
rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
-
}
-
else {
-
p_MCB->p_lnk = os_tsk.run;
-
os_tsk.run->p_lnk = NULL;
-
os_tsk.run->p_rlnk = (P_TCB)p_MCB;
-
}
-
rt_block(timeout, WAIT_MUT);
-
return (OS_R_TMO);
-
}
-
#endif
-
//=========================================================================================
-
-
//------------------------------ rt_Event.c ------------------------------------
-
#if OS_FLAG_EN > 0
-
OS_RESULT rt_evt_wait (U16 wait_flags, U16 timeout, BOOL and_wait) {
-
/* Wait for one or more event flags with optional time-out. */
-
/* "wait_flags" identifies the flags to wait for. */
-
/* "timeout" is the time-out limit in system ticks (0xffff if no time-out) */
-
/* "and_wait" specifies the AND-ing of "wait_flags" as condition to be met */
-
/* to complete the wait. (OR-ing if set to 0). */
-
U32 block_state;
-
-
if (and_wait) {
-
/* Check for AND-connected events */
-
if ((os_tsk.run->events & wait_flags) == wait_flags) {
-
os_tsk.run->events &= ~wait_flags;
-
return (OS_R_EVT);
-
}
-
block_state = WAIT_AND;
-
}
-
else {
-
/* Check for OR-connected events */
-
if (os_tsk.run->events & wait_flags) {
-
os_tsk.run->waits = os_tsk.run->events & wait_flags;
-
os_tsk.run->events &= ~wait_flags;
-
return (OS_R_EVT);
-
}
-
block_state = WAIT_OR;
-
}
-
/* Task has to wait */
-
os_tsk.run->waits = wait_flags;
-
rt_block (timeout, (U8)block_state);
-
return (OS_R_TMO);
-
}
-
-
void rt_evt_set (U16 event_flags, OS_TID task_id) {
-
/* Set one or more event flags of a selectable task. */
-
P_TCB p_tcb;
-
-
p_tcb = os_active_TCB[task_id-1];
-
if (p_tcb == NULL) {
-
return;
-
}
-
p_tcb->events |= event_flags;
-
event_flags = p_tcb->waits;
-
/* If the task is not waiting for an event, it should not be put */
-
/* to ready state. */
-
if (p_tcb->state == WAIT_AND) {
-
/* Check for AND-connected events */
-
if ((p_tcb->events & event_flags) == event_flags) {
-
goto wkup;
-
}
-
}
-
if (p_tcb->state == WAIT_OR) {
-
/* Check for OR-connected events */
-
if (p_tcb->events & event_flags) {
-
p_tcb->waits &= p_tcb->events;
-
wkup: p_tcb->events &= ~event_flags;
-
rt_rmv_dly (p_tcb);
-
p_tcb->events &= ~event_flags;
-
p_tcb->state = READY;
-
p_tcb->ret_val = OS_R_EVT;
-
rt_dispatch (p_tcb);
-
}
-
}
-
}
-
-
void rt_evt_clr (U16 clear_flags, OS_TID task_id) {
-
/* Clear one or more event flags (identified by "clear_flags") of a */
-
/* selectable task (identified by "task"). */
-
P_TCB task = os_active_TCB[task_id-1];
-
-
if (task == NULL) {
-
return;
-
}
-
task->events &= ~clear_flags;
-
}
-
-
void isr_evt_set (U16 event_flags, OS_TID task_id) {
-
/* Same function as "os_evt_set", but to be called by ISRs. */
-
P_TCB p_tcb = os_active_TCB[task_id-1];
-
-
if (p_tcb == NULL) {
-
return;
-
}
-
rt_psq_enq (p_tcb, event_flags);
-
rt_psh_req ();
-
}
-
-
U16 rt_evt_get (void) {
-
/* Get events of a running task after waiting for OR connected events. */
-
return (os_tsk.run->waits);
-
}
-
#endif
-
-
void rt_evt_psh (P_TCB p_CB, U16 set_flags) {
-
/* Check if task has to be waken up */
-
U16 event_flags;
-
-
p_CB->events |= set_flags;
-
event_flags = p_CB->waits;
-
if (p_CB->state == WAIT_AND) {
-
/* Check for AND-connected events */
-
if ((p_CB->events & event_flags) == event_flags) {
-
goto rdy;
-
}
-
}
-
if (p_CB->state == WAIT_OR) {
-
/* Check for OR-connected events */
-
if (p_CB->events & event_flags) {
-
p_CB->waits &= p_CB->events;
-
rdy: p_CB->events &= ~event_flags;
-
rt_rmv_dly (p_CB);
-
p_CB->state = READY;
-
p_CB->ret_val = OS_R_EVT;
-
rt_put_prio (&os_rdy, p_CB);
-
}
-
}
-
}
-
//=========================================================================================
-
-
//---- rt_mailbox.c ----------------------------------------------------------------------------
-
#if OS_MBOX_EN > 0
-
void rt_mbx_init (OS_ID mailbox, U16 mbx_size) {
-
/* Initialize a mailbox */
-
P_MCB p_MCB = mailbox;
-
-
p_MCB->cb_type = MCB;
-
p_MCB->isr_st = 0;
-
p_MCB->p_lnk = NULL;
-
p_MCB->first = 0;
-
p_MCB->last = 0;
-
p_MCB->count = 0;
-
p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) /
-
(U32)sizeof (void *);
-
}
-
-
OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) {
-
/* Send message to a mailbox */
-
P_MCB p_MCB = mailbox;
-
P_TCB p_TCB;
-
-
if (p_MCB->p_lnk != NULL && p_MCB->count == 0) {
-
/* A task is waiting for message */
-
p_TCB = rt_get_first ((P_XCB)p_MCB);
-
*p_TCB->msg = p_msg;
-
p_TCB->ret_val = OS_R_MBX;
-
rt_rmv_dly (p_TCB);
-
rt_dispatch (p_TCB);
-
os_tsk.run->ret_val = OS_R_OK;
-
}
-
else {
-
/* Store message in mailbox queue */
-
if (p_MCB->count == p_MCB->size) {
-
/* No free message entry, wait for one. If message queue is full, */
-
/* then no task is waiting for message. The 'p_MCB->p_lnk' list */
-
/* pointer can now be reused for send message waits task list. */
-
if (timeout == 0) {
-
return (OS_R_TMO);
-
}
-
if (p_MCB->p_lnk != NULL) {
-
rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
-
}
-
else {
-
p_MCB->p_lnk = os_tsk.run;
-
os_tsk.run->p_lnk = NULL;
-
os_tsk.run->p_rlnk = (P_TCB)p_MCB;
-
/* Signal the 'isr_mbx_receive ()' that the task is waiting */
-
/* to send a message */
-
p_MCB->isr_st = 1;
-
}
-
os_tsk.run->msg = p_msg;
-
rt_block (timeout, WAIT_MBX);
-
return (OS_R_TMO);
-
}
-
/* Yes, there is a free entry in a mailbox. */
-
p_MCB->msg[p_MCB->first] = p_msg;
-
rt_inc (&p_MCB->count);
-
if (++p_MCB->first == p_MCB->size) {
-
p_MCB->first = 0;
-
}
-
}
-
return (OS_R_OK);
-
}
-
-
OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) {
-
/* Receive a message; possibly wait for it */
-
P_MCB p_MCB = mailbox;
-
P_TCB p_TCB;
-
-
/* If a message is available in the fifo buffer */
-
/* remove it from the fifo buffer and return. */
-
if (p_MCB->count) {
-
*message = p_MCB->msg[p_MCB->last];
-
if (++p_MCB->last == p_MCB->size) {
-
p_MCB->last = 0;
-
}
-
if (p_MCB->p_lnk != NULL) {
-
/* A task is waiting to send message */
-
p_TCB = rt_get_first ((P_XCB)p_MCB);
-
p_TCB->ret_val = OS_R_OK;
-
p_MCB->msg[p_MCB->first] = p_TCB->msg;
-
if (++p_MCB->first == p_MCB->size) {
-
p_MCB->first = 0;
-
}
-
rt_rmv_dly (p_TCB);
-
rt_dispatch (p_TCB);
-
os_tsk.run->ret_val = OS_R_OK;
-
}
-
else {
-
rt_dec (&p_MCB->count);
-
}
-
return (OS_R_OK);
-
}
-
/* No message available: wait for one */
-
if (timeout == 0) {
-
return (OS_R_TMO);
-
}
-
if (p_MCB->p_lnk != NULL) {
-
rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
-
}
-
else {
-
p_MCB->p_lnk = os_tsk.run;
-
os_tsk.run->p_lnk = NULL;
-
os_tsk.run->p_rlnk = (P_TCB)p_MCB;
-
}
-
rt_block(timeout, WAIT_MBX);
-
os_tsk.run->msg = message;
-
return (OS_R_TMO);
-
}
-
-
OS_RESULT rt_mbx_check (OS_ID mailbox) {
-
/* Check for free space in a mailbox. Returns the number of messages */
-
/* that can be stored to a mailbox. It returns 0 when mailbox is full. */
-
P_MCB p_MCB = mailbox;
-
-
return (p_MCB->size - p_MCB->count);
-
}
-
-
void isr_mbx_send (OS_ID mailbox, void *p_msg) {
-
/* Same function as "os_mbx_send", but to be called by ISRs. */
-
P_MCB p_MCB = mailbox;
-
-
rt_psq_enq (p_MCB, (U32)p_msg);
-
rt_psh_req ();
-
}
-
-
//---V4.13
-
OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) {
-
/* Receive a message in the interrupt function. The interrupt function */
-
/* should not wait for a message since this would block the rtx os. */
-
P_MCB p_MCB = mailbox;
-
-
if (p_MCB->count) {
-
/* A message is available in the fifo buffer. */
-
*message = p_MCB->msg[p_MCB->last];
-
if (p_MCB->isr_st == 1) {
-
/* A task is locked waiting to send message */
-
p_MCB->isr_st = 2;
-
rt_psq_enq (p_MCB, 0);
-
rt_psh_req ();
-
}
-
rt_dec (&p_MCB->count);
-
if (++p_MCB->last == p_MCB->size) {
-
p_MCB->last = 0;
-
}
-
return (OS_R_MBX);
-
}
-
return (OS_R_OK);
-
}
-
-
//---V4.12
-
#if 0
-
OS_RESULT isr_mbx_receive_old (OS_ID mailbox, void **message) {
-
/* Receive a message in the interrupt function. The interrupt function */
-
/* should not wait for a message since this would block the rtx os. */
-
P_MCB p_MCB = mailbox;
-
-
if (p_MCB->count) {
-
/* A message is available in the fifo buffer. */
-
*message = p_MCB->msg[p_MCB->last];
-
if (p_MCB->isr_st == 1) {
-
/* A task is locked waiting to send message */
-
p_MCB->isr_st = 2;
-
rt_psq_enq (p_MCB, 0);
-
rt_psh_req ();
-
}
-
rt_dec (&p_MCB->count);
-
if (++p_MCB->last == p_MCB->size) {
-
p_MCB->last = 0;
-
}
-
return (OS_R_MBX);
-
}
-
return (OS_R_OK);
-
}
-
#endif
-
#endif
-
-
void rt_mbx_psh (P_MCB p_CB, void *p_msg) {
-
/* Store the message to the mailbox queue or pass it to task directly. */
-
P_TCB p_TCB;
-
-
/* Check if this was an 'isr_mbx_receive ()' post service request. */
-
if (p_CB->p_lnk != NULL && p_CB->isr_st == 2) {
-
/* A task is waiting to send message, remove it from the waiting list. */
-
p_CB->isr_st = 0;
-
p_TCB = rt_get_first ((P_XCB)p_CB);
-
p_TCB->ret_val = OS_R_OK;
-
goto rdy;
-
}
-
/* A task is waiting for message, pass the message to task directly. */
-
if (p_CB->p_lnk != NULL && p_CB->count == 0) {
-
p_TCB = rt_get_first ((P_XCB)p_CB);
-
*p_TCB->msg = p_msg;
-
p_TCB->ret_val = OS_R_MBX;
-
rdy:p_TCB->state = READY;
-
rt_rmv_dly (p_TCB);
-
rt_put_prio (&os_rdy, p_TCB);
-
}
-
else {
-
/* No task is waiting for message, store the message to the mailbox queue.*/
-
if (p_CB->count < p_CB->size) {
-
p_CB->msg[p_CB->first] = p_msg;
-
rt_inc (&p_CB->count);
-
if (++p_CB->first == p_CB->size) {
-
p_CB->first = 0;
-
}
-
}
-
else {
-
os_error (OS_ERR_MBX_OVF);
-
}
-
}
-
}
-
//=========================================================================================
-
-
//------ rt_timer.c ---------------------------------------------------------------------
-
#if OS_TMR_EN > 0
-
void rt_tmr_tick (void) {
-
/* Decrement delta count of timer list head. Timers having the value of */
-
/* zero are removed from the list and the callback function is called. */
-
P_TMR p;
-
-
if (os_tmr.next == NULL) {
-
return;
-
}
-
os_tmr.tcnt--;
-
while (os_tmr.tcnt == 0 && (p = os_tmr.next) != NULL) {
-
/* Call a user provided function to handle an elapsed timer */
-
os_tmr_call (p->info);
-
os_tmr.tcnt = p->tcnt;
-
os_tmr.next = p->next;
-
rt_free_box ((U32 *)m_tmr, p);
-
}
-
}
-
-
OS_ID rt_tmr_create (U16 tcnt, U16 info) {
-
/* Create an user timer and put it into the chained timer list using */
-
/* a timeout count value of "tcnt". User parameter "info" is used as a */
-
/* parameter for the user provided callback function "os_tmr_call ()". */
-
P_TMR p_tmr, p;
-
U32 delta,itcnt = tcnt;
-
-
if (tcnt == 0 || m_tmr == NULL) {
-
return (NULL);
-
}
-
p_tmr = rt_alloc_box ((U32 *)m_tmr);
-
if (!p_tmr) {
-
return (NULL);
-
}
-
p_tmr->info = info;
-
p = (P_TMR)&os_tmr;
-
delta = p->tcnt;
-
while (delta < itcnt && p->next != NULL) {
-
p = p->next;
-
delta += p->tcnt;
-
}
-
/* Right place found, insert timer into the list */
-
p_tmr->next = p->next;
-
p_tmr->tcnt = (U16)(delta - itcnt);
-
p->next = p_tmr;
-
p->tcnt -= p_tmr->tcnt;
-
return (p_tmr);
-
}
-
-
OS_ID rt_tmr_kill (OS_ID timer) {
-
/* Remove user timer from the chained timer list. */
-
P_TMR p, p_tmr;
-
-
p_tmr = (P_TMR)timer;
-
p = (P_TMR)&os_tmr;
-
/* Search timer list for requested timer */
-
while (p->next != p_tmr) {
-
if (p->next == NULL) {
-
/* Failed, "timer
阅读(8680) | 评论(0) | 转发(0) |