⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_arm.c

📁 NXP LPC ARMThumb port for uCOS-II
💻 C
字号:
/*
*********************************************************************************************************
*                                               uC/OS
*                                         The Real-Time Kernel
*
*                        (c) Copyright 1992, 1993, Jean J. Labrosse, Plantation, FL
*                                          All Rights Reserved
*                        (c) Copyright ARM Limited 1999.  All rights reserved.
*
*                                          ARM Specific code
*
*
* File : os_arm.c
* By   : Lee Dunbar
*********************************************************************************************************
*/

#include "ucos_ii.h"

/*
 * Definitions specific to ARM
 */

/*
 * Program Status Registers
 */
#define PSR_IRQ_DISABLE     0x00000080
#define PSR_FIQ_DISABLE     0x00000040

#define	PSR_MODE_FIQ32	    0x00000011
#define	PSR_MODE_IRQ32	    0x00000012
#define	PSR_MODE_SVC32	    0x00000013
#define PSR_MODE_THUMB      0x00000020

#define	PSR_CC_OVER         0x10000000
#define	PSR_CC_NEG          0x80000000

#define DEFAULT_PSR         ( PSR_MODE_SVC32 )

#pragma off(thumb);

/*
*********************************************************************************************************
*                                        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_XXX).
*
* 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 *pdata, OS_STK *ptos, INT16U opt)
{
    unsigned int *stk ;

    opt    = opt;                           /* 'opt' is not used, prevent warning                      */
    stk    = (unsigned int *)ptos;          /* Load stack pointer                                      */

    /* build a context for the new task */

    /* NOTE:  or'ed with 1 below since tasks start in thumb mode */
    *--stk = (unsigned int) task | 1;   /* lr */

    *--stk = 0;                         /* r12 */
    *--stk = 0;                         /* r11 */
    *--stk = 0;                         /* r10 */
    *--stk = 0;                         /* r9 */
    *--stk = 0;                         /* r8 */
    *--stk = 0;                         /* r7 */
    *--stk = 0;                         /* r6 */
    *--stk = 0;                         /* r5 */
    *--stk = 0;                         /* r4 */
    *--stk = 0;                         /* r3 */
    *--stk = 0;                         /* r2 */
    *--stk = 0;                         /* r1 */
    *--stk = (unsigned int) pdata;      /* r0 */
    *--stk = DEFAULT_PSR;               /* spsr YYY+ */
    *--stk = DEFAULT_PSR;               /* psr */
    return ((void *)stk);
}



//
// When asked to do a context swap, simply record fact that one needs to get
// done and postpone context swap until scheduler runs.
//
void OSIrqCtxSw(void)
{
    OSCtxSw = TRUE;
}

//
// At beginning of IRQ, register interrupt with OS
//
void OSIrqStart (void)
{
    if (OSRunning) 
    {
        OSIntEnter();
    }
}


//
// At end of IRQ, register interrupt with OS and decide if need to do context
// swap or not.
//
// The return value is either the context switch function or NULL if no
// context switch is to be performed.
//
void (*OSIrqFinish (void))()        // returns ptr to func
{
    if (OSRunning) 
    {
        OSIntExit();
        if (OSCtxSw)
        {
            OSCtxSw = FALSE;
            return (OSIrqContextSwap);
        }
    }

    return (void (*)()) 0;
}


//
// During Time slice IRQ, service OS scheduler
//
void OSIrqTick (void)
{
    if (OSRunning) 
    {
        OSTimeTick();
    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -