📄 os_cpu_c.c
字号:
/*
*************************************************************************
*************************************************************************
** **
** FILE : OS_CPU_C.C **
** **
** DESCRIPTION : This file along with os_cpu_a.tri, contains **
** most of the code specific to TriCore, TC10GP. **
** This is also a board support package for the **
** Triboard, TC10GP released around end of **
** November 1999. **
** **
** AUTHOR : Andre Gompel **
** **
** REVISION HISTORY **
** : **
** **
** Copyright (c) 2000 Micrium Inc. **
** All Rights Reserved **
** **
** Copyright (c) 2000 Infineon Technologies Corproration **
** All Rights Reserved **
** **
** THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR **
** IMPLIED WARRANTY. BOTH INFINEON TECHNOLOGIES CORPORATION AND **
** MICRIUM INC. DISCLAIMS ALL REPRESENTATIONS AND WARRANTIES WITH **
** REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT **
** SHALL INFINEON TECHNOLOGIES CORPORATION OR MICRIUM INC. BE LIABLE **
** FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES **
** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN **
** AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACT OR **
** OMISSION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR **
** PERFORMANCE OF THIS SOFTWARE. **
** **
*************************************************************************
*************************************************************************
*/
#include "INCLUDES.H"
/*$PAGE*/
/*
*********************************************************************************************************
* 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
*
* pdata 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) : 1) The initial value of the Status Register (SR) is OS_INITIAL_SR sets the 683xx processor
* to run in SUPERVISOR mode. It is assumed that all uC/OS-II tasks run in supervisor
* mode.
* 2) You can pass the above options in the 'opt' argument. You MUST only use the upper
* 8 bits of 'opt' because the lower bits are reserved by uC/OS-II. If you make changes
* to the code below, you will need to ensure that it doesn't affect the behaviour of
* OSTaskIdle() and OSTaskStat().
* 3) Registers are initialized to make them easy to differentiate with a debugger.
*********************************************************************************************************
*/
/*
** Implementation note.
** In this section you will find parameter passing by global variable.
** This is not for speed reason.
** This is mostly because TriCore architecture requires basically two stacks
** for each task. Code (called CSA free list in TriCore books, and data.
** This scheme allows to leave the processor independant code untouched.
** Or almost: OsTaskCreateExt is now a macro, which add the necessary
** call for context allocation.
** The default number of csa per task is initialized.
** However you may adjust/ change the global g_num_of_ctx, before you create
** a task.
** The code could be written much shortly, thanks to TriCore architecture.
** At this time, the choice has been made to stick with UCOS-II code unchanged
** expected for the processor dependant files.
**
*/
BOOLEAN OSRunning;
/* Globals used for context management */
INT32U g_free_ctx, // Set by OSInitTriCore, Updated by os_ctx_alloc
g_next_fcx, // Set by OSInitTriCore, Updated by os_ctx_alloc
g_tsk_ctx0, // Set by OSInitTriCore, Updated by os_ctx_alloc
g_tsk_lcx, // Updated by os_ctx_alloc
g_ctx_req; // Must be initialized.
/*
** OSInitTriCore: What it does.
** --------------
**
** 1) Init global variables from context registers.
** 2) Init/Set Interrupts vectors, (traps also, if required).
** 3) Init GPTU : general purpose timer usee for UCOS ticks.
*/
#define crFCX 0xFE38
#define crLCX 0xFE3C
void OSInitASC0(void);
void OSInitTriCore(void)
{
static INT32U reload_val = 0xFFFFfd00;
static INT32U timer_priority=0x02;
fcx_t lcx;
// Note that We are one context up from main()
g_ctx_req = TSK_CSA_SIZE; // This may be modified as needed.
g_next_fcx = CTX_RESERVED+ __mfcr(crFCX);
g_free_ctx = __mfcr(crLCX) - g_next_fcx ; // This works only if context are in the same segment
OSInitFlags();
OSInitTricoreInt(); // Interrupts, Vectors and BIV initialization
OSInitGptu(); // Note: interrupts still not enabled.
OSInitASC0(); // Initialize the Serial port, UART 0
P0_DIR = 0x80; //P0.7=Output
}
/*
** OSinitHook was added later to initialize the stdout semaphore
** It should be the place of choice for any BSP (Board Support Package) LEvel
** initialization, which are executed after OSInit.
**
*/
OS_EVENT *pSem;
void OSInitHook(void)
{
pSem = OSSemCreate(1); // Semaphore for OSprintf critical section.
// The semaphore is initialized to 1 to allow
// exclusive access to the calling task.
}
/*
** os_ctx_alloc use is similar to malloc.
**
** after call:
** 1)the return value is an fcx type, use to initialize the TCB
** at task creation time. (NULL if no ctxt available)
**
** 2) The ctx_req (passed by reference) is modified to reflect
** the number of contextes actually allocated.
**
** 3) The global g_tsk_avail_ctxt is updated, to fcx_t value if there
** are still ctxts available, to zero if not.
** Note: for fully dynamic CSA allocation, need to defragment the context list
** at each allocation: not done yet.
**
** 4) Note that this function is called by the macro OSTaskCreateExt
** This is done that way to keep the Processor Independent Code unmodified.
**
** Assumptions: fcx and lcx have been proprely initialized by crt0 or cstart modules
*/
void os_ctx_alloc(void)
{
if (!g_free_ctx)
{
g_tsk_ctx0= (fcx_t) 0;
return; // No free context left: bail out...
}
else // Number of context granted maybe =< requested
{
g_tsk_ctx0 = g_next_fcx;
g_ctx_req = g_free_ctx >= g_ctx_req ? g_ctx_req : g_free_ctx; // adjust to granted
g_free_ctx -= g_ctx_req;
g_tsk_lcx = (fcx_t) g_tsk_ctx0 + g_ctx_req ; // May want next ctx less 2 or 3
g_next_fcx = g_tsk_lcx + 1; // Update for next valid request.
}
}
void unused_interrupt_isr (void)
{
}
void nmi_isr (void)
{
}
/*$PAGE*/
#if OS_CPU_HOOKS_EN
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : ptcb is a pointer to the task control block of the task being created.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void OSTaskCreateHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
void OSTaskDelHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent compiler warning */
}
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
* task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
void OSTaskSwHook (void)
{
}
//
// For ASC look at:
// TC10GP User's manual, and also
// Holger Dienst code: file RS232.C on the Tricore startup kit CD ROM.
//
BOOLEAN volatile FlgTxBuffAvailable;
void OSInitASC0(void)
{
P2_ALTSEL0 =0x30; // Select ASC0 TXD & RXD
P2_ALTSEL1 =0;
P2_DIR =0x10; // Select TXD as an output, all other= Input
P2_OUT =0x10; // Similar
ASC0_CLC =0x100; // RMC field: CLC divide by 1
ASC0_CON =0; // Need R bit clear before writing the BG register.
ASC0_BG =0xE9; // 16*Baud rate reload register. (ok with 16 Mhz OSC)
ASC0_CON =0x8011; // Control register.
ASC0_FDV =0; // Just to be safe.
ASC0_SRCTB =0x1003; // SRE=TRUE, TOS=CPU, SRPN=3 : Transmit Buffer SRC
ASC0_SRCR =0x1004; // SRE=TRUE, TOS=CPU, SRPN=4 : Receive buffer has char.
FlgTxBuffAvailable=TRUE;
}
INT8U bidon;
void OS_ASC0_RxISR(void) // Actually full means here:"has a character"
{
extern OS_EVENT *RxSem; // Receive Semaphore
INT8U c;
INT8U RxISRerr;
OS_ENABLE_GW(); // Enable PSW.GW bit
RxISRerr= OSSemPost (RxSem); // Do a "V" on the semaphore
// this will "wake up" the task which was waiting
// for the semaphore to be released, since the semaphore
// was initilized to 1, then 0 by the initial
// "P" primitive.
// Reference: Dijska
c=ASC0_RBUF;
bidon=c;
}
void OS_ASC0_TxISR(void) // ASC0 Transmit buffer available interrupt
{
FlgTxBuffAvailable=TRUE;
}
__inline int OSputc(INT8U c)
{
while(!FlgTxBuffAvailable); // Just wait at this time: we could do better!
FlgTxBuffAvailable=FALSE; // Tx Buffer Available interrupt will clear
ASC0_TBUF=c;
return 0;
}
int fputc(int c, FILE * fp)
{
// We just ignore the stream, since ASC0
// is our stdout here.
return OSputc( c & 0xff);
}
/*
**
** Since Osprintf is a "common" ressource, a critical section must be used.
** uCOS semaphore to program the critical section makes this quite simple..
** See code below. AG.
**
**
*/
void OSprintf(char *fmt, ...)
{
INT8U error;
va_list args;
OSSemPend(pSem, 0, &error); // Do a "P"
va_start(args, fmt);
vfprintf(stdout, fmt, args);
va_end(args);
OSSemPost(pSem); // Do a "V" primitive.
}
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : none
*********************************************************************************************************
*/
void OSTaskStatHook (void)
{
}
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : none
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
void OSTimeTickHook (void)
{
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -