久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 6406|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

UCOS移植代碼之LAMMY分析--OS_CPU_C.C

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:72519 發(fā)表于 2015-1-23 20:50 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 liuda 于 2015-1-23 20:53 編輯

還限制字?jǐn)?shù);只能分割拉。
昨天我簡(jiǎn)要的把移植UCOS要增加的幾個(gè)文件作了簡(jiǎn)要概述,今天開始,一個(gè)一個(gè)文件的進(jìn)行分析,首先來說說OS_CPU.H
#ifdef OS_CPU_GLOBALS //這個(gè)宏名在OS_CPU_C.C中已定義,那么本文中的OS_CPU_EXT會(huì)被extern代替
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
//定義與編譯器無關(guān)的數(shù)據(jù)類型
typedef unsigned char BOOLEAN; //布爾變量
typedef unsigned char INT8U; // 無符號(hào)8位整型變量
typedef signed char INT8S; //有符號(hào)8位整型變量
typedef unsigned short INT16U; //無符號(hào)16位整型變量
typedef signed short INT16S; //有符號(hào)16位整型變量
typedef unsigned int INT32U; //無符號(hào)32位整型變量
typedef signed int INT32S; //有符號(hào)32位整型變量
typedef float FP32; //單精度浮點(diǎn)數(shù)(32位長(zhǎng)度)
typedef double FP64; //雙精度浮點(diǎn)數(shù)(64位長(zhǎng)度)
typedef INT32U OS_STK; //堆棧是32位寬度
注: 這里為什么用typedef,因?yàn)槿绻?define,那么代碼中的每一個(gè)相應(yīng)的類型都會(huì)被替代,很有可能會(huì)出現(xiàn)問題,畢竟他只是一個(gè)替代的關(guān)系,且編 譯時(shí)間會(huì)增加,而用typedef則不會(huì),它就相當(dāng)于我們C++里面的引用,一樣的思維,在這里面就是說多了一個(gè)名稱。還有要注意的是我們?cè)趺粗?unsigned char 就是無符號(hào)8位整型變量,可以ARM公司里面下載ADS_CompilerGuide_D.PDF文件,或者在你所裝的ADS1.2目錄里面有一個(gè)文件夾 叫PDF,打開它就可以找到,具體頁(yè)在259頁(yè)。
//與ARM7體系結(jié)構(gòu)相關(guān)的一些定義
#define OS_CRITICAL_METHOD 2 //選擇開、關(guān)中斷的方式
__swi(0x00) void OS_TASK_SW(void); //任務(wù)級(jí)任務(wù)切換函數(shù)
__swi(0x01) void _OSStartHighRdy(void); //運(yùn)行優(yōu)先級(jí)最高的任務(wù)
__swi(0x02) void OS_ENTER_CRITICAL(void); //關(guān)中斷
__swi(0x03) void OS_EXIT_CRITICAL(void); //開中斷
__swi(0x40) void *GetOSFunctionAddr(int Index); //獲取系統(tǒng)服務(wù)函數(shù)入口[自己還未明白]
__swi(0x41) void *GetUsrFunctionAddr(int Index);//獲取自定義服務(wù)函數(shù)入口[自己還未明白]
__swi(0x42) void OSISRBegin(void); //中斷開始處理
__swi(0x43) int OSISRNeedSwap(void); //判斷中斷是否需要切換
__swi(0x80) void ChangeToSYSMode(void); //任務(wù)切換到系統(tǒng)模式
__swi(0x81) void ChangeToUSRMode(void); //任務(wù)切換到用戶模式
__swi(0x82) void TaskIsARM(INT8U prio); //任務(wù)代碼是ARM代碼
__swi(0x83) void TaskIsTHUMB(INT8U prio); //任務(wù)代碼是THUMB
#define OS_STK_GROWTH 1 //堆棧是從上往下長(zhǎng)的
#define USR32Mode 0x10 //用戶模式
#define SYS32Mode 0x1f //系統(tǒng)模式
#define NoInt 0x80
#ifndef USER_USING_MODE
#define USER_USING_MODE USR32Mode //任務(wù)缺省模式
#endif
#ifndef OS_SELF_EN
#define OS_SELF_EN 0 //允許返回OS與任務(wù)分別編譯、固化
#endif
OS_CPU_EXT INT32U OsEnterSum; //關(guān)中斷計(jì)數(shù)器(開關(guān)中斷的信號(hào)量)




#define OS_CPU_GLOBALS
#include "config.h"
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{//這個(gè)函數(shù)是一個(gè)指針函數(shù),里面的形參void (*task)(void *pd)也是一個(gè)指針函數(shù),就是一個(gè)函數(shù)的地址,其中task實(shí)際上就是我們的用戶任務(wù)函數(shù)名;pdata是任務(wù)開始執(zhí)行時(shí),傳遞給任務(wù)的參數(shù)的指針;ptos是分配給任務(wù)的堆棧的棧頂指針。
OS_STK *stk; //OS_STK實(shí)際就是unsigned int
opt = opt; // 'opt' 沒有使用。作用是避免編譯器警告
stk = ptos; //獲取堆棧指針
//建立任務(wù)環(huán)境,ADS1.2使用滿遞減堆棧
//注意下面并沒有對(duì)SP進(jìn)行分配空間,因?yàn)檫@個(gè)空間本來就是棧,所以沒必要再對(duì)SP進(jìn)行分配
*stk = (OS_STK) task; /* pc */任務(wù)的首地址
*--stk = (OS_STK) task; /* lr */任務(wù)的首地址
*--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,第一個(gè)參數(shù)使用R0傳遞 */
*--stk = (USER_USING_MODE|0x00); /* spsr,允許 IRQ, FIQ 中斷 */
*--stk = 0; /* 關(guān)中斷計(jì)數(shù)器OsEnterSum; */
return (stk);
}
#if OS_SELF_EN > 0
extern int const _OSFunctionAddr[];
extern int const _UsrFunctionAddr[];
#endif
//關(guān)于SWI的使用,最好看下ADS1.2目錄下PDF文件夾下的ADS_DeveloperGuide_D.PDF文件的5.4我在這里稍微簡(jiǎn)述一下,SWI是一個(gè)軟中斷,即由軟件實(shí)現(xiàn)的中斷,它的中斷號(hào)可從LR中獲得,不同指令狀態(tài)的取法不一樣,至于哪不一樣,看下面的代碼或PDF文件就可以發(fā)現(xiàn)答案;還有它的第一操作數(shù)是放在r0中,也就是中斷號(hào)是從r0取出,但是中斷號(hào)必須從LR中經(jīng)過變換后再load in r0。。
void SWI_Exception(int SWI_Num, int *Regs)
{
OS_TCB *ptcb;
switch(SWI_Num)
{
//case 0x00: /* 任務(wù)切換函數(shù)OS_TASK_SW,參考o(jì)s_cpu_s.s文件
// break;
//case 0x01: /* 啟動(dòng)任務(wù)函數(shù)OSStartHighRdy,參考o(jì)s_cpu_s.s文件 */
// break;
case 0x02: /* 關(guān)中斷函數(shù)OS_ENTER_CRITICAL(),參考o(jì)s_cpu.h文件 */
__asm
{
MRS R0, SPSR
ORR R0, R0, #NoInt
MSR SPSR_c, R0
}
OsEnterSum++;
break;
case 0x03: /* 開中斷函數(shù)OS_EXIT_CRITICAL(),參考o(jì)s_cpu.h文件 */
if (--OsEnterSum == 0)
{
__asm
{
MRS R0, SPSR
BIC R0, R0, #NoInt
MSR SPSR_c, R0
}
}
break;
//上面兩個(gè)切換狀態(tài)的匯編函數(shù)是對(duì)SPSR進(jìn)行操作呢?因?yàn)槭褂玫氖擒浿袛啵绦驙顟B(tài)寄存器CPRS保存在軟中斷對(duì)應(yīng)的SPRS中,軟中斷退出后會(huì)把軟中斷對(duì)應(yīng)的SPSR【即管理模式的SPRS】恢復(fù)到原來狀態(tài)的CPRS中,所以我們只要對(duì)SPSR進(jìn)行操作就可以了。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:72519 發(fā)表于 2015-1-23 20:51 | 只看該作者


#if OS_SELF_EN > 0

case 0x40:

/* 返回指定系統(tǒng)服務(wù)函數(shù)的地址 */

/* 函數(shù)地址存于數(shù)組_OSFunctionAddr中*/

/* 數(shù)組_OSFunctionAddr需要另外定義 */

/* Regs[0] 為第一個(gè)參數(shù),也是返回值 */

/* Regs[1] 為第二個(gè)參數(shù) */

/* Regs[2] 為第三個(gè)參數(shù) */

/* Regs[3] 為第四個(gè)參數(shù) */

/* 僅有一個(gè)參數(shù)為系統(tǒng)服務(wù)函數(shù)的索引 */

Regs[0] = _OSFunctionAddr[Regs[0]];

break;

case 0x41:

/* 返回指定用戶的服務(wù)函數(shù)的地址 */

/* 函數(shù)地址存于數(shù)組_UsrFunctionAddr中*/

/* 數(shù)組_UsrFunctionAddr需要另外定義 */

/* Regs[0] 為第一個(gè)參數(shù),也是返回值 */

/* Regs[1] 為第二個(gè)參數(shù) */

/* Regs[2] 為第三個(gè)參數(shù) */

/* Regs[3] 為第四個(gè)參數(shù) */

/* 僅有一個(gè)參數(shù)為用戶服務(wù)函數(shù)的索引 */

Regs[0] = _UsrFunctionAddr[Regs[0]];

break;

case 0x42: /* 中斷開始處理 */

OSIntNesting++;

break;

case 0x43: /* 判斷中斷是否需要切換 */

if (OSTCBHighRdy == OSTCBCur)

{

Regs[0] = 0;

}

else

{

Regs[0] = 1;

}

break;

#endif

//上面幾個(gè)軟中斷處理函數(shù)自己還未研究,也不明白為什么要這么做,先放著,畢竟它對(duì)我們移植不會(huì)帶來影響

case 0x80: /* 任務(wù)切換到系統(tǒng)模式 */

__asm

{

MRS R0, SPSR

BIC R0, R0, #0x1f

ORR R0, R0, #SYS32Mode

MSR SPSR_c, R0

}

break;

case 0x81: /* 任務(wù)切換到用戶模式 */

__asm

{

MRS R0, SPSR

BIC R0, R0, #0x1f

ORR R0, R0, #USR32Mode

MSR SPSR_c, R0

}

break;

case 0x82: /* 任務(wù)是ARM代碼 */

if (Regs[0] <= OS_LOWEST_PRIO)

{

ptcb = OSTCBPrioTbl[Regs[0]];

if (ptcb != NULL)

{

ptcb -> OSTCBStkPtr[1] &= ~(1 << 5);

}

}

break;

case 0x83: /* 任務(wù)是THUMB代碼 */

if (Regs[0] <= OS_LOWEST_PRIO)

{

ptcb = OSTCBPrioTbl[Regs[0]];

if (ptcb != NULL)

{

ptcb -> OSTCBStkPtr[1] |= (1 << 5);

}

}

break;

default:

break;

}

//上面幾個(gè)應(yīng)該好理解,就不再嗷述啦。

}

void OSStartHighRdy(void)

{

_OSStartHighRdy();

}

/* 以下為一些鉤子函數(shù),全部為空函數(shù)。具體說明請(qǐng)看相關(guān)資料 */我自也未往深入的研究,只是知道它們功能不能忽視,可以把邵貝貝翻譯的那本書相關(guān)內(nèi)容好好看看

#if OS_CPU_HOOKS_EN

#if OS_VERSION > 203

void OSInitHookBegin (void)

{

}

#endif

#if OS_VERSION > 203

void OSInitHookEnd (void)

{

}

#endif

void OSTaskCreateHook (OS_TCB *ptcb)

{

ptcb = ptcb; /* Prevent compiler warning */

}

void OSTaskDelHook (OS_TCB *ptcb)

{

ptcb = ptcb; /* Prevent compiler warning */

}

void OSTaskSwHook (void)

{

}

void OSTaskStatHook (void)

{

}

#if OS_VERSION > 203

void OSTCBInitHook (OS_TCB *ptcb)

{

ptcb = ptcb; /* Prevent Compiler warning */

}

#endif

void OSTimeTickHook (void)

{

}

#if OS_VERSION >= 251

void OSTaskIdleHook (void)

{

}

#endif

#endif
回復(fù)

使用道具 舉報(bào)

板凳
ID:68804 發(fā)表于 2015-2-9 15:03 | 只看該作者
學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

地板
ID:72966 發(fā)表于 2015-3-19 08:50 | 只看該作者
學(xué)習(xí)了。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲伊人色 | 久久99深爱久久99精品 | 欧美福利在线观看 | 夜夜嗨av一区二区三区网页 | 国产伦精品一区二区三区视频网站 | 国产黄a三级三级看三级 | h片在线 | 国产精品视频专区 | 欧美一级片免费观看 | a视频在线观看 | 欧美顶级黄色大片免费 | 日韩黄色影院 | 欧美日韩中文字幕 | 男女av在线| 久久艳片www.17c.com | 亚洲精品91| 国产精品96 | 国产精品一区二区三区四区五区 | 日韩国产精品一区二区 | 午夜在线视频观看日韩17c | 放几个免费的毛片出来看 | 在线一区二区视频 | 黄色一级毛片 | 婷久久| 中文字幕婷婷 | 欧美视频一区二区 | 久久国内精品 | 国产99页 | 免费看黄色一级片 | www男人天堂 | 黄色一级在线观看 | 成人在线免费观看视频 | 国产a久久麻豆入口 | 中文字幕精品一区久久久久 | 大尺度做爰呻吟舌吻网站 | 欧美一级在线视频 | 一级视频在线观看 | 国产www视频 | 精品视频国产 | 免费a视频 | 国产精品片 |