📄 os_cpu_c.c
字号:
/*
*********************************************************************************************************
* OS_CPU_C.C
*
* Copyright 2003, Validated Software Corporation, Lafayette, CO
* All Rights Reserved
*
* Author: Scott N.
* Date: 03-Sep-03
*
* References:
* $Workfile: OS_CPU_C.C $
*
* Description: These are the C level OS support routines
* for the TMS320C6414 port on Code Composer Studio
*
* Contents:
* void setTickISR (int setting); CONTROL CALL TO OSTimeTick (UCIT-SysTimer only).
* void interrupt TimerOneTick(void) SYSTEM TIMER INTERRUPT VECTOR
* BOOLEAN areInterruptsEnabled (void) RETURN TRUE IF INTERRUPTS ENABLED
* BOOLEAN enableInterrupts (void) ENABLE INTERRUPTS
* void OS_CPU_Init (void) CPU INITIALIZATION
* void OS_CPU_InitTick (void) TICKER INITIALIZATION
* OS_STK *OSTaskStkInit (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT16U opt)
* INITIALIZE A TASK'S STACK
* interrupt void InterruptNotEnabled(void) CATCH-ALL INTERRUPT VECTOR
*
* Revision History - latest change on top
*
* $Log: $
*
*********************************************************************************************************
*/
/*#define OS_CPU_GLOBALS*/
#include "ucos_II.h"
/*
*********************************************************************************************************
* System Timer ISR (Timer 1)
*
* Description: This is the system timer ISR
*
* Note(s):
* This implementation of UCOS-II requires that the IRP and CSR registers be saved
* upon entry into any interrupt and restored upon exit. Need to save the registers as locals
* so each context has its own copy.
*
*********************************************************************************************************
*/
void interrupt TimerOneTick(void)
{
const unsigned int iirp = IRP; /* LOCAL copy of IRP and CSR to be restored upon */
const unsigned int icsr = CSR; /* return from this ISR. */
OSIntEnter(); /* tell the OS that we're in an interrupt */
OSTimeTick(); /* Call OS timer tick */
OSIntExit(); /* Task switch if we can */
IRP = iirp;
CSR = icsr;
return;
}
/*
*********************************************************************************************************
* Return the state of global interrupts.
*
* Description: This function returns 1 if interrupts are enabled, otherwise 0.
*
* Note(s): Only the global interrupt enable bit is examined. Specific device interrupts may
* or may not be enabled as controlled by the IER and device initialization.
*
*********************************************************************************************************
*/
BOOLEAN areInterruptsEnabled (void)
{
/* The global interrupt enable bit is the lowest order bit of the CSR. */
return (CSR & 0x1);
}
/*
*********************************************************************************************************
* Enable interrupts
*
* Description: This function enables interrupts.
*
* Returns: This function returns 1 if the processor's global interrupt enable bit was already
* set when this function was called, else 0.
*
*
* Note(s): MicroCOS uses OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() to protect critical
* regions. Their implementation disables interrupts during the critical region,
* then sets interrupts back to what they were. They are to be used in pairs.
* Calling OS_EXIT_CRITICAL() alone when interrupts are already off will not turn
* them on.
*
* This function only sets the processor's GLOBAL interrupt bit. The OSTaskStkInit
* function turns on interrupts for the timer (level 15) and maskable interrupts
* generally (2nd lowest order bit of IER).
*
*
*********************************************************************************************************
*/
BOOLEAN enableInterrupts (void)
{
BOOLEAN previousState = areInterruptsEnabled();
/* The global interrupt enable bit is the lowest order bit of the CSR. */
CSR |= 0x1;
return previousState;
}
/*
*********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
* stack frame of the task being created. This function is highly processor specific.
*
* Arguments : task is a pointer to the task code
*
* p_arg is a pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
* of the stack.
*
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
* (see uCOS_II.H for OS_TASK_OPT_???).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : Interrupts are enabled when your task starts executing. You can change this by setting the
* PSW to 0x0002 instead. In this case, interrupts would be disabled upon task startup. The
* application code would be responsible for enabling interrupts at the beginning of the task
* code. You will need to modify OSTaskIdle() and OSTaskStat() so that they enable
* interrupts. Failure to do this will make your system crash!
*********************************************************************************************************
*/
OS_STK *OSTaskStkInit(void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT16U opt)
{
REGISTER_FRAME *Frame, *StackBottom;
unsigned int *FirstFreeCellInStack ;
unsigned int Temp, Temp1;
/*------------------------------------------------------------------------
THE SP MUST BE ALIGNED ON AN 8-BYTE BOUNDARY.
The FRAME must be an alignment of that also
------------------------------------------------------------------------*/
opt = opt; // prevent compiler warning
Frame = (REGISTER_FRAME *)((int)ptos &~7 );
StackBottom = Frame ;
Temp1 = (unsigned int)Frame;
Temp = (sizeof(REGISTER_FRAME) - sizeof(unsigned int)) ; // Decrement pointer to simulate pushing a frame
Frame = (REGISTER_FRAME *)(Temp1 - Temp);
Frame->A0 = 0x0A0;
Frame->A1 = 0x0A1;
Frame->A2 = 0x0A2;
Frame->A3 = 0x0A3;
Frame->A4 = (unsigned int)p_arg; /* data pointer first argument */
Frame->A5 = 0x0A5;
Frame->A6 = 0x0A6;
Frame->A7 = 0x0A7;
Frame->A8 = 0x0A8;
Frame->A9 = 0x0A9;
Frame->A10 = 0x0A10;
Frame->A11 = 0x0A11;
Frame->A12 = 0x0A12;
Frame->A13 = 0x0A13;
Frame->A14 = 0x0A14;
Frame->A15 = 0x0A15;
Frame->A16 = 0x0A16;
Frame->A17 = 0x0A17;
Frame->A18 = 0x0A18;
Frame->A19 = 0x0A19;
Frame->A20 = 0x0A20;
Frame->A21 = 0x0A21;
Frame->A22 = 0x0A22;
Frame->A23 = 0x0A23;
Frame->A24 = 0x0A24;
Frame->A25 = 0x0A25;
Frame->A26 = 0x0A26;
Frame->A27 = 0x0A27;
Frame->A28 = 0x0A28;
Frame->A29 = 0x0A29;
Frame->A30 = 0x0A30;
Frame->A31 = 0x0A31;
Frame->B0 = 0x0B0;
Frame->B1 = 0x0B1;
Frame->B2 = 0x0B2;
Frame->B3 = 0x0B3;
Frame->B4 = 0x0B4;
Frame->B5 = 0x0B5;
Frame->B6 = 0x0B6;
Frame->B7 = 0x0B7;
Frame->B8 = 0x0B8;
Frame->B9 = 0x0B9;
Frame->B10 = 0x0B10;
Frame->B11 = 0x0B11;
Frame->B12 = 0x0B12;
Frame->B13 = 0x0B13;
/*------------------------------------------------------------------------
PASS THE CURRENT DP TO THE task
------------------------------------------------------------------------*/
Frame->B14 = ReturnCurrentDP(); /* by convention the data pointer is in B14. */
Frame->B15 = (unsigned int)StackBottom ; /* C env Frame pointer */
Frame->B16 = 0x0B16;
Frame->B17 = 0x0B17;
Frame->B18 = 0x0B18;
Frame->B19 = 0x0B19;
Frame->B20 = 0x0B20;
Frame->B21 = 0x0B21;
Frame->B22 = 0x0B22;
Frame->B23 = 0x0B23;
Frame->B24 = 0x0B24;
Frame->B25 = 0x0B25;
Frame->B26 = 0x0B26;
Frame->B27 = 0x0B27;
Frame->B28 = 0x0B28;
Frame->B29 = 0x0B29;
Frame->B30 = 0x0B30;
Frame->B31 = 0x0B31;
Frame->AMR_ = 0;
/* little endian */
/* Program Cache disabled ( 2 << 5 ) */
/* Data Cache disabled ( 2 << 2 ) */
/* PGIE set and GIE disabled. This will enable interrupts on ctx sw*/
Frame->CSR_ = (0<<8) + 2;
Frame->IER_ = 0; /* Once, the IER was set here. This value is not being used. */
Frame->IRP_ = 0xdeadbeef;
Frame->B3 = (unsigned int)task ;
/*
* In this processor, pushing on the stack decrements the stack pointer.
* Within this function, "Frame" has been pointing to the first location
* of the stack frame. In this processor, the correct value of the stack
* pointer is one word BEFORE the pushed frame data. These lines place that
* address into "FirstFreeCellInStack". Lint does not like the cast from the
* REGISTER_FRAME* to an int*. Suppress the warning.
*/
FirstFreeCellInStack = (unsigned int *)Frame ;
FirstFreeCellInStack--;
return (FirstFreeCellInStack);
}
// ------------------------------------------------------------------------1
void timerInit(void)
{
/*------------------------------------------------------------------------*/
/* SETUP THE TIMER. */
/*------------------------------------------------------------------------*/
TIMER_1_BASE[ TIMER_CONTROL ] = 0;
TIMER_1_BASE[ TIMER_PERIOD ] = ( ( CLOCK_PER_SEC / OS_TICKS_PER_SEC ) / 2 ); // set period register
TIMER_1_BASE[ TIMER_COUNTER ] = 0x0;
TIMER_1_BASE[ TIMER_CONTROL ] = ( 1 << 4 ) + ( 1 << 8 ) + ( 1 << 9 ); // C/P = clk mode, PWID=2 clk pulses, CLKSRC=CPU/8
TIMER_1_BASE[ TIMER_CONTROL ] |= 1; // turns on T1OUT
TIMER_1_BASE[ TIMER_CONTROL ] |= ( 1 << 6 ) + ( 1 << 7 ); // start timer, GO=1, ~HLD=1
/* Enable the timer interrupt and NMI. Global, maskable interrupts remain off. */
IER = 0x8002;
}
// ------------------------------------------------------------------------1
void OSTCBInitHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent Compiler warning. */
}
// ------------------------------------------------------------------------2
void OSTaskCreateHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
// ------------------------------------------------------------------------3
void OSTaskDelHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
// ------------------------------------------------------------------------4
void OSTaskSwHook (void)
{
}
// ------------------------------------------------------------------------5
void OSInitHookBegin (void)
{
}
// ------------------------------------------------------------------------6
void OSInitHookEnd (void)
{
}
// ------------------------------------------------------------------------7
void OSTaskIdleHook (void)
{
}
// ------------------------------------------------------------------------8
void OSTaskStatHook (void)
{
}
// ------------------------------------------------------------------------9
void OSTimeTickHook (void)
{
#if OS_TMR_EN > 0
OSTmrTickCtr++;
if (OSTmrTickCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
OSTmrTickCtr = 0;
OSTmrSignal();
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -