📄 68hc11.c
字号:
/*
*********************************************************************************************************
* uC/OS
* The Real-Time Kernel
*
* (c) Copyright 1992-1995, Jean J. Labrosse, Plantation, FL
* All Rights Reserved
*
*
* 68HC11 Specific code
*
* File : 68HC11.C
* By : Jean J. Labrosse
*********************************************************************************************************
*/
#include "INCLUDES.H"
/*
*********************************************************************************************************
* CREATE A TASK
*
* Description : This function is used to create a task under uC/OS. To manage the task, uC/OS needs to
* know the starting address of the task, the address of any data that you would like to
* pass to that task when it starts executing, the address of the top-of-stack for the
* task's stack and finally, the priority of the task.
* Arguments : task is the address of your task
* pdata is a pointer to data that you wish to pass to the task when the task starts
* pstk is a pointer to the task's top-of-stack
* prio is the task's priority
*********************************************************************************************************
*/
UBYTE OSTaskCreate(void (OS_FAR *task)(void *pd), void *pdata, void *pstk, UBYTE p)
{
UWORD *wstk;
UBYTE *bstk;
UBYTE err;
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[p] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
OS_EXIT_CRITICAL();
wstk = (UWORD *)pstk; /* Load stack pointer */
*--wstk = (UWORD)pdata; /* Simulate call to function with argument */
*--wstk = (UWORD)task;
*--wstk = (UWORD)task; /* Put pointer to task on top of stack */
*--wstk = (UWORD)0x0000; /* Y Register = 0 */
*--wstk = (UWORD)0x0000; /* X Register = 0 */
*--wstk = (UWORD)0x0000; /* D Register = 0 (i.e. A = 0 and B = 0) */
bstk = (UBYTE *)wstk; /* Convert WORD ptr to BYTE ptr to set CCR */
*--bstk = 0xC0; /* CCR Register (disable XIRQ and STOP instruction) */
bstk--; /* SP to point to next empty location */
err = OSTCBInit(p, (void *)bstk); /* Get and initialize a TCB */
if (err == OS_NO_ERR) {
if (OSRunning) { /* Find highest priority task if multitasking has started */
OSSched();
}
}
return (err);
} else {
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* START HIGHEST PRIORITY TASK READY-TO-RUN
*
* Description : This function is called by OSStart() to start the highest priority task that was created
* by your application before calling OSStart().
* Arguments : none
* Execution : 27 bus cycles
*********************************************************************************************************
*/
void OSStartHighRdy(void)
{
_asm(" .external _OSTCBCur \n");
_asm(" .external _OSTCBHighRdy\n");
_asm(" ldx _OSTCBHighRdy\n"); /* 5~, Point to TCB of highest priority task ready to run */
_asm(" stx _OSTCBCur \n"); /* 5~, Save in current TCB */
_asm(" lds 0,x \n"); /* 5~, Load SP into 68HC11 */
_asm(" rti \n"); /* 12~, Run task */
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK LEVEL CONTEXT SWITCH
*
* Description : This function is called when a task makes a higher priority task ready-to-run.
* Arguments : none
* Execution : 35 bus cycles
*********************************************************************************************************
*/
void OS_FAR OSCtxSw(void)
{
_asm(" .external _OSTCBCur \n");
_asm(" .external _OSTCBHighRdy\n");
_asm(" ldx _OSTCBCur \n"); /* 5~, Point to current task's TCB */
_asm(" STS 0,x \n"); /* 3~, Save stack pointer in preempted task's TCB */
_asm(" ldx _OSTCBHighRdy\n"); /* 5~, Point to TCB of highest priority task ready to run */
_asm(" stx _OSTCBCur \n"); /* 5~, Save in current TCB */
_asm(" lds 0,x \n"); /* 5~, Load SP into 68HC11 */
_asm(" rti \n"); /* 12~, Run task */
}
/*
*********************************************************************************************************
* INTERRUPT LEVEL CONTEXT SWITCH
*
* Description : This function is called by OSIntExit() to perform a context switch to a task that has
* been made ready-to-run by an ISR.
* Arguments : none
* Execution : 47 bus cycles
*********************************************************************************************************
*/
void OSIntCtxSw(void)
{
_asm(" .external _OSTCBCur \n");
_asm(" .external _OSTCBHighRdy\n");
_asm(" pulx \n"); /* 5~, Ignore return address to OSIntCtxSw() */
_asm(" pulx \n"); /* 5~, Ignore return address from call to OSIntExit() */
_asm(" ldx _OSTCBCur \n"); /* 5~, Point to current task's TCB */
_asm(" STS 0,x \n"); /* 3~, Save stack pointer in preempted task's TCB */
_asm(" ldx _OSTCBHighRdy\n"); /* 5~, Point to TCB of highest priority task ready to run */
_asm(" stx _OSTCBCur \n"); /* 5~, Save in current TCB */
_asm(" lds 0,x \n"); /* 5~, Load SP into 68HC11 */
_asm(" rti \n"); /* 12~, Run task */
}
/*$PAGE*/
/*
*********************************************************************************************************
* SYSTEM TICK ISR
*
* Description : This function is the ISR used to notify uC/OS that a system tick has occurred. You must
* setup the 68HC11's interrupt vector table so that an OUTPUT COMPARE interrupt vectors
* to this function.
* Arguments : none
* Notes : 1) The 'tick ISR' assumes the we are using the Output Compare specified by OS_TICK_OC
* (see OS_CFG.H) to generate a tick that occurs every OS_TICK_OC_CNTS (also in
* 68HC11.H) which corresponds to the number of FRT (Free Running Timer) counts to the
* next interrupt.
* 2) You must specify which output compare will be used by the tick ISR as follows:
* Set OS_TICK_OC in OS_CFG.H to 1 to use OUTPUT COMPARE #1
* Set OS_TICK_OC in OS_CFG.H to 2 to use OUTPUT COMPARE #2
* Set OS_TICK_OC in OS_CFG.H to 3 to use OUTPUT COMPARE #3
* Set OS_TICK_OC in OS_CFG.H to 4 to use OUTPUT COMPARE #4
* Set OS_TICK_OC in OS_CFG.H to 5 to use OUTPUT COMPARE #5
* 3) TFLG1, TOC1, TOC2, TOC3, TOC4 and TOC5 are defined in the Intermetrics file IO.H
*********************************************************************************************************
*/
void OS_FAR OSTickISR(void)
{
OSIntNesting++; /* Notify uC/OS about the ISR */
#if OS_TICK_OC == 1
TFLG1 = 0x80; /* Clear OC1F interrupt flag (bit 7) */
TOC1 += OS_TICK_OC_CNTS; /* Set TOC1 to present time + desired counts to next ISR */
#endif
#if OS_TICK_OC == 2
TFLG1 = 0x40; /* Clear OC2F interrupt flag (bit 6) */
TOC2 += OS_TICK_OC_CNTS; /* Set TOC2 to present time + desired counts to next ISR */
#endif
#if OS_TICK_OC == 3
TFLG1 = 0x20; /* Clear OC3F interrupt flag (bit 5) */
TOC3 += OS_TICK_OC_CNTS; /* Set TOC3 to present time + desired counts to next ISR */
#endif
#if OS_TICK_OC == 4
TFLG1 = 0x10; /* Clear OC4F interrupt flag (bit 4) */
TOC4 += OS_TICK_OC_CNTS; /* Set TOC4 to present time + desired counts to next ISR */
#endif
#if OS_TICK_OC == 5
TFLG1 = 0x08; /* Clear OC5F interrupt flag (bit 3) */
TOC5 += OS_TICK_OC_CNTS; /* Set TOC5 to present time + desired counts to next ISR */
#endif
OSTimeTick(); /* Call uC/OS's tick updating function */
OSIntExit(); /* Tell uC/OS that we are about to exit the ISR */
_asm(" rti \n"); /* Return from interrupt */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -