📄 os_cpu_c.c
字号:
/*
* COPYRIGHT (c) Notifier 1993-2004, All Rights Reserved
*
* 描述: μCOS-II在lpc210x上的移植代码C语言部分,包括任务堆栈初始化代码和钩子函数等
* 用ads1.2编译,必须使用ARM方式编译
* 版本历史:
*
* 版本 作者 日期 修改内容
* 1.0 王璀 2005-09-07 来自周立功单片机的移植代码
* 1.1 王璀 2005-11-28 整理了文件格式
* 添加了uC/OS II Hook函数的安装接口
* 一些其它小修改
* 1.2 王璀 2006-01-18 标准化
* 将uC/OS II的hook函数安装部分移到ucosii_util.c中
* 1.21 王璀 2006-02-14 添加了对CLOCK模块的支持
* 修改了OS_VIEW模块的编译开关
*/
#define OS_CPU_GLOBALS
//==============================================================================
// 包含的头文件
//==============================================================================
#include <assert.h>
#include "ucos_ii.h"
#include "ucosii_util.h"
#if OS_VIEW_MODULE > 0
#include "os_view.h"
#endif
#if OS_CLK_EN > 0
#include "clk.h"
#endif
#include "system\sys_types.h"
#include "lib_shell.h"
#include "bsp_cfg.h"
#include "library\lib_bits_operation.h"
#include "driver\drv_int_mgr_lpc2xxx.h"
//==============================================================================
// 本地宏及类型定义
//==============================================================================
__swi(0x01) void _OSStartHighRdy(void); /* 运行优先级最高的任务 */
#define USR32Mode 0x10 /* 用户模式 */
#define SYS32Mode 0x1f /* 系统模式 */
#define NoInt 0x80
#ifndef USER_USING_MODE
#define USER_USING_MODE USR32Mode /* 任务缺省模式 */
#endif
#ifndef OS_SELF_EN
#define OS_SELF_EN 0 /* 允许返回OS与任务分别编译、固化*/
#endif
//==============================================================================
// 外部变量声明
//==============================================================================
OS_CPU_EXT INT32U OsEnterSum; /* 关中断计数器(开关中断的信号量) */
#if OS_SELF_EN > 0
extern int const _OSFunctionAddr[];
extern int const _UsrFunctionAddr[];
#endif
//==============================================================================
// 函数定义
//==============================================================================
//------------------------------------------------------------------------------
// 函数描述:任务堆栈初始化代码,本函数调用失败会使系统崩溃
OS_STK *//栈顶指针位置
OSTaskStkInit
(
void (*task)(void *pd),//任务开始执行的地址
void *pdata,//传递给任务的参数
OS_STK *ptos,//任务的堆栈开始位置
INT16U opt//附加参数,当前版本对于本函数无用,具体意义参见OSTaskCreateExt()的opt参数
)
{
OS_STK *stk;
opt = opt; /* 'opt' 没有使用。作用是避免编译器警告 */
stk = ptos; /* 获取堆栈指针 */
/* 建立任务环境,ADS1.2使用满递减堆栈 */
*stk = (OS_STK) task; /* pc */
*--stk = (OS_STK) task; /* 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,第一个参数使用R0传递 */
*--stk = (USER_USING_MODE|0x00); /* spsr,允许 IRQ, FIQ 中断 */
*--stk = 0; /* 关中断计数器OsEnterSum; */
return (stk);
}
//------------------------------------------------------------------------------
// 函数描述:软中断异常处理程序,提供一些系统服务
void SWI_Exception
(
int SWI_Num,//SWI_Num:功能号
int *Regs//Regs[0] 为第一个参数,也是返回值
//Regs[1] 为第二个参数
//Regs[2] 为第三个参数
//Regs[3] 为第四个参数
)
{
OS_TCB *ptcb;
switch(SWI_Num)
{
//case 0x00: /* 任务切换函数OS_TASK_SW,参考os_cpu_s.s文件 */
// break;
//case 0x01: /* 启动任务函数OSStartHighRdy,参考os_cpu_s.s文件 */
// break;
case 0x02: /* 关中断函数OS_ENTER_CRITICAL(),参考os_cpu.h文件 */
__asm
{
MRS R0, SPSR
ORR R0, R0, #NoInt
MSR SPSR_c, R0
}
OsEnterSum++;
break;
case 0x03: /* 开中断函数OS_EXIT_CRITICAL(),参考os_cpu.h文件 */
if (--OsEnterSum == 0)
{
__asm
{
MRS R0, SPSR
BIC R0, R0, #NoInt
MSR SPSR_c, R0
}
}
break;
#if OS_SELF_EN > 0
case 0x40:
/* 返回指定系统服务函数的地址 */
/* 函数地址存于数组_OSFunctionAddr中*/
/* 数组_OSFunctionAddr需要另外定义 */
/* Regs[0] 为第一个参数,也是返回值 */
/* Regs[1] 为第二个参数 */
/* Regs[2] 为第三个参数 */
/* Regs[3] 为第四个参数 */
/* 仅有一个参数为系统服务函数的索引 */
Regs[0] = _OSFunctionAddr[Regs[0]];
break;
case 0x41:
/* 返回指定用户的服务函数的地址 */
/* 函数地址存于数组_UsrFunctionAddr中*/
/* 数组_UsrFunctionAddr需要另外定义 */
/* Regs[0] 为第一个参数,也是返回值 */
/* Regs[1] 为第二个参数 */
/* Regs[2] 为第三个参数 */
/* Regs[3] 为第四个参数 */
/* 仅有一个参数为用户服务函数的索引 */
Regs[0] = _UsrFunctionAddr[Regs[0]];
break;
case 0x42: /* 中断开始处理 */
OSIntNesting++;
break;
case 0x43: /* 判断中断是否需要切换 */
if (OSTCBHighRdy == OSTCBCur)
{
Regs[0] = 0;
}
else
{
Regs[0] = 1;
}
break;
#endif
case 0x80: /* 任务切换到系统模式 */
__asm
{
MRS R0, SPSR
BIC R0, R0, #0x1f
ORR R0, R0, #SYS32Mode
MSR SPSR_c, R0
}
break;
case 0x81: /* 任务切换到用户模式 */
__asm
{
MRS R0, SPSR
BIC R0, R0, #0x1f
ORR R0, R0, #USR32Mode
MSR SPSR_c, R0
}
break;
case 0x82: /* 任务是ARM代码 */
if (Regs[0] <= OS_LOWEST_PRIO)
{
ptcb = OSTCBPrioTbl[Regs[0]];
if (ptcb != NULL)
{
ptcb -> OSTCBStkPtr[1] &= ~(1 << 5);
}
}
break;
case 0x83: /* 任务是THUMB代码 */
if (Regs[0] <= OS_LOWEST_PRIO)
{
ptcb = OSTCBPrioTbl[Regs[0]];
if (ptcb != NULL)
{
ptcb -> OSTCBStkPtr[1] |= (1 << 5);
}
}
break;
default:
break;
}
}
//------------------------------------------------------------------------------
// 函数描述:uC/OS-II启动时使用OSStartHighRdy运行第一个任务,
// 实质是产生swi 1指令
void OSStartHighRdy(void)
{
_OSStartHighRdy();
}
/*********************************************************************************************************
** 函数名称: _TaskIsARM
** 功能描述: 任务代码是ARM代码
**
** 输 入: 无
** 输 出 : 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2004年8月27日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void _TaskIsARM(INT8U prio)
{
OS_TCB *ptcb;
if (prio <= OS_LOWEST_PRIO)
{
ptcb = OSTCBPrioTbl[prio];
if (ptcb != NULL)
{
ptcb -> OSTCBStkPtr[1] &= ~(1 << 5);
}
}
}
/*********************************************************************************************************
** 函数名称: _TaskIsARM
** 功能描述: 任务是THUMB代码
**
** 输 入: 无
** 输 出 : 无
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2004年8月27日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void _TaskIsTHUMB(INT8U prio)
{
OS_TCB *ptcb;
if (prio <= OS_LOWEST_PRIO)
{
ptcb = OSTCBPrioTbl[prio];
if (ptcb != NULL)
{
ptcb -> OSTCBStkPtr[1] |= (1 << 5);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -