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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6255|回復: 3
打印 上一主題 下一主題
收起左側

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

[復制鏈接]
跳轉到指定樓層
樓主
ID:72519 發表于 2015-1-23 20:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 liuda 于 2015-1-23 20:53 編輯

還限制字數;只能分割拉。
昨天我簡要的把移植UCOS要增加的幾個文件作了簡要概述,今天開始,一個一個文件的進行分析,首先來說說OS_CPU.H
#ifdef OS_CPU_GLOBALS //這個宏名在OS_CPU_C.C中已定義,那么本文中的OS_CPU_EXT會被extern代替
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
//定義與編譯器無關的數據類型
typedef unsigned char BOOLEAN; //布爾變量
typedef unsigned char INT8U; // 無符號8位整型變量
typedef signed char INT8S; //有符號8位整型變量
typedef unsigned short INT16U; //無符號16位整型變量
typedef signed short INT16S; //有符號16位整型變量
typedef unsigned int INT32U; //無符號32位整型變量
typedef signed int INT32S; //有符號32位整型變量
typedef float FP32; //單精度浮點數(32位長度)
typedef double FP64; //雙精度浮點數(64位長度)
typedef INT32U OS_STK; //堆棧是32位寬度
注: 這里為什么用typedef,因為如果用#define,那么代碼中的每一個相應的類型都會被替代,很有可能會出現問題,畢竟他只是一個替代的關系,且編 譯時間會增加,而用typedef則不會,它就相當于我們C++里面的引用,一樣的思維,在這里面就是說多了一個名稱。還有要注意的是我們怎么知道 unsigned char 就是無符號8位整型變量,可以ARM公司里面下載ADS_CompilerGuide_D.PDF文件,或者在你所裝的ADS1.2目錄里面有一個文件夾 叫PDF,打開它就可以找到,具體頁在259頁。
//與ARM7體系結構相關的一些定義
#define OS_CRITICAL_METHOD 2 //選擇開、關中斷的方式
__swi(0x00) void OS_TASK_SW(void); //任務級任務切換函數
__swi(0x01) void _OSStartHighRdy(void); //運行優先級最高的任務
__swi(0x02) void OS_ENTER_CRITICAL(void); //關中斷
__swi(0x03) void OS_EXIT_CRITICAL(void); //開中斷
__swi(0x40) void *GetOSFunctionAddr(int Index); //獲取系統服務函數入口[自己還未明白]
__swi(0x41) void *GetUsrFunctionAddr(int Index);//獲取自定義服務函數入口[自己還未明白]
__swi(0x42) void OSISRBegin(void); //中斷開始處理
__swi(0x43) int OSISRNeedSwap(void); //判斷中斷是否需要切換
__swi(0x80) void ChangeToSYSMode(void); //任務切換到系統模式
__swi(0x81) void ChangeToUSRMode(void); //任務切換到用戶模式
__swi(0x82) void TaskIsARM(INT8U prio); //任務代碼是ARM代碼
__swi(0x83) void TaskIsTHUMB(INT8U prio); //任務代碼是THUMB
#define OS_STK_GROWTH 1 //堆棧是從上往下長的
#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; //關中斷計數器(開關中斷的信號量)




#define OS_CPU_GLOBALS
#include "config.h"
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{//這個函數是一個指針函數,里面的形參void (*task)(void *pd)也是一個指針函數,就是一個函數的地址,其中task實際上就是我們的用戶任務函數名;pdata是任務開始執行時,傳遞給任務的參數的指針;ptos是分配給任務的堆棧的棧頂指針。
OS_STK *stk; //OS_STK實際就是unsigned int
opt = opt; // 'opt' 沒有使用。作用是避免編譯器警告
stk = ptos; //獲取堆棧指針
//建立任務環境,ADS1.2使用滿遞減堆棧
//注意下面并沒有對SP進行分配空間,因為這個空間本來就是棧,所以沒必要再對SP進行分配
*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);
}
#if OS_SELF_EN > 0
extern int const _OSFunctionAddr[];
extern int const _UsrFunctionAddr[];
#endif
//關于SWI的使用,最好看下ADS1.2目錄下PDF文件夾下的ADS_DeveloperGuide_D.PDF文件的5.4我在這里稍微簡述一下,SWI是一個軟中斷,即由軟件實現的中斷,它的中斷號可從LR中獲得,不同指令狀態的取法不一樣,至于哪不一樣,看下面的代碼或PDF文件就可以發現答案;還有它的第一操作數是放在r0中,也就是中斷號是從r0取出,但是中斷號必須從LR中經過變換后再load in r0。。
void SWI_Exception(int SWI_Num, int *Regs)
{
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;
//上面兩個切換狀態的匯編函數是對SPSR進行操作呢?因為使用的是軟中斷,程序狀態寄存器CPRS保存在軟中斷對應的SPRS中,軟中斷退出后會把軟中斷對應的SPSR【即管理模式的SPRS】恢復到原來狀態的CPRS中,所以我們只要對SPSR進行操作就可以了。


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

使用道具 舉報

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


#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;

}

//上面幾個應該好理解,就不再嗷述啦。

}

void OSStartHighRdy(void)

{

_OSStartHighRdy();

}

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

#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
回復

使用道具 舉報

板凳
ID:68804 發表于 2015-2-9 15:03 | 只看該作者
學習了
回復

使用道具 舉報

地板
ID:72966 發表于 2015-3-19 08:50 | 只看該作者
學習了。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 免费亚洲网站 | 99久久99热这里只有精品 | 九九热精品视频在线观看 | 国产99视频精品免费视频7 | 久久久一区二区 | 91 视频网站| 自拍偷拍中文字幕 | 欧洲精品视频一区 | 成人午夜激情 | 日韩在线一区视频 | 久久精品久久久久久 | 青青草视频免费观看 | 日一日操一操 | 成人做爰www免费看视频网站 | 国产欧美一区二区三区在线看 | 在线视频中文字幕 | 亚洲国产成人精品女人久久久 | h在线免费观看 | 精品亚洲一区二区三区四区五区 | 男女深夜网站 | 欧美极品一区二区 | 久久久久久国模大尺度人体 | 午夜免费网站 | 亚洲三区在线观看 | 中文久久 | 欧美午夜精品 | www.色.com| 五月婷婷丁香婷婷 | 欧美不卡一区 | 成人国产精品久久 | 日本成人片在线观看 | 国产乱码久久久 | 日韩网 | 国产日韩欧美一区二区 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 国产日韩免费观看 | 久久久成 | 国产精品电影在线观看 | 午夜欧美一区二区三区在线播放 | 亚洲 欧美 在线 一区 | 99视频网站|