91视频免费?看_蜜芽MY188精品TV在线观看_国产免费无遮挡在线观看视频_深夜国产_亚洲精品欧洲精品_欧美黑人粗暴多交

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發新帖

uCOS 2.00 在TMS320F2812上的移植完整攻略

本人最近在將uCOS(2.00) 移植到DSP(TMS320F2812)上時,碰到不少問題和故障。從網上下載了不少關于移植到2812上的范例,并且有一份2812開發板上的uCOS范例,無一意外的都有嚴重BUG。本人經過多次試驗和驗證,制作出一個相對完整的版本,供大家使用和評價。此版本目前尚未發現問題,但不代表沒有BUG,請大家使用時注意。

移植的文件包含如下幾個文件:“os_IntSw.src”、“ os_StartHighRdy.src”、“ os_Sw.src”、“os_TickISR.src”、“ os_cpu_c.c”共5個文件。文件內容包含在附錄中。另說明,本人系統中,周期中斷使用的是T2定時器,因此os_TickISR函數中沒有對ACK清零的匯編代碼,請大家注意。

對匯編文件,發現2個BUG,添加了一些代碼,基本如下:

PUSH AR1H:AR0H

PUSH XAR2

PUSH XAR3

PUSH XAR4

PUSH XAR5

PUSH XAR6

PUSH XAR7

PUSH XT

ASP

PUSH DP:ST1

對應有:

POP DP:ST1

NASP

POP XT

POP XAR7

POP XAR6

POP XAR5

POP XAR4

POP XAR3

POP XAR2

POP AR1H:AR0H

BUG一:

“ POP XT

POP XAR7

POP XAR6

POP XAR5

POP XAR4

POP XAR3

POP XAR2

POP AR1H:AR0H ”為手工保存CPU核心的通用寄存器,不添加此代碼,線程之間或中斷調用后,會出現異常,此為發現的第1個BUG,添加此代碼后解決。這個也為uCOS的基本要求,即完整保存CPU核心的通用寄存器,沒有此代碼,uCOS將不能正常運行。

全部回復(4)
正序查看
倒序查看
add222
LV.4
2
2014-01-15 16:09

BUG二:

ASP

PUSH DP:ST1

對應有:

POP DP:ST1

NASP

本人在解決第1個問題后,在中斷中調用系統信號量函數,發現一調用,系統就崩潰了,經過試驗,發現是堆棧指針對齊的問題,即ASP 和 NASP 造成的。ASP受ST1中的一個位控制,所以添加此代碼, 保存ST1。同時保存DP1是因為要保證堆棧地址為偶數地址,其實保存DP不起什么作用,僅僅是用來對齊堆棧地址為偶數地址,沒有其他的意思。

在os_cpu_c.c文件中,也作了些修改,如下:

void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt)

{

INT16U *stk;

INT16U temp;

opt = opt; /* 'opt' is not used, prevent warning */

stk = (INT16U *)ptos; /* Load stack pointer */

temp = ((INT32U)pdata)&0x0000ffff; /* Simulate call to function with argument */

*stk++ = (INT16U)temp; /* 保存低16位 */

temp = ((INT32U)pdata)>>16; /* Simulate call to function with argument */

*stk++ = (INT16U)(temp); /* 保存高16位*/

*stk++ = 0x0000; /* ST0 = 0x1111 */

*stk++ = 0x0000; /* T = 0x0000 */

*stk++ = 0x0000; /* AL = 0x3333 */

*stk++ = 0x0000; /* AH = 0x2222 */

*stk++ = 0x0000; /* PL = 0x5555 */

*stk++ = 0x0000; /* PH = 0x4444 */

*stk++ = 0x0000; /* AR0 = 0x7777 */

*stk++ = 0x0000; /* AR1 = 0x6666 */

*stk++ = 0x0A0A; /* ST1 = 0x080B */

*stk++ = 0x0000; /* DP = 0x8888 */

*stk++ = 0x2003; /* IER = 0xBBBB */

*stk++ = 0x2003; /* DBGSTAT = 0xAAAA */

temp = ((INT32U)task)&0x0000ffff;

*stk++ = (INT16U)temp; /* 保存低16位 */

temp = ((INT32U)task)>>16; /* Save task entry */

*stk++ = (INT16U)(temp); /* 保存高16位 */

// PUSH RPC

temp = ((INT32U)task)&0x0000ffff; /* RPCL = 0xCCCC */

*stk++ = (INT16U)temp; /* 保存低16位 */

temp = ((INT32U)task)>>16; /* RPCH = 0xCCCC */

*stk++ = (INT16U)(temp); /* 保存高16位*/

/*

下為手工保存的寄存器

PUSH AR1H:AR0H

PUSH XAR2

PUSH XAR3

PUSH XAR4

PUSH XAR5

PUSH XAR6

PUSH XAR7

PUSH XT

PUSH ST1:DP

*/

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0000; /* 保存高16位 */

*stk++ = 0x0A0A; /* ST1 */

*stk++ = 0x0000; /* DP */

stk++;

return ((void *)stk);

}

文件中比較重要的地方都以紅色作了標記,這里特別說明:

temp = ((INT32U)pdata)&0x0000ffff; /* Simulate call to function with argument */

*stk++ = (INT16U)temp; /* 保存低16位 */

temp = ((INT32U)pdata)>>16; /* Simulate call to function with argument */

*stk++ = (INT16U)(temp); /* 保存高16位*/

這個好像沒什么用,這樣做只是為了避免編譯時出現告警(和原來比較)。

*stk++ = 0x0A0A; /* ST1 = 0x080B */

這個特別重要。因為進入任務后,中斷必須都是開著的,這個值直接用來設置ST1,詳細見ST1的位說明。任務在第一次進入時,NASP指令不能起作用也由這里控制(任務堆棧一般為偶地址)。總中斷是由ST1來控制的,因此,在進入任務前,你開關總中斷都是無意義的操作,只有這里才是開總中斷的地方,要特別注意。當然,你也可以在每個任務開始設置總中斷,但那樣比較復雜。

0
回復
add222
LV.4
3
2014-01-15 16:09
@add222
BUG二:ASPPUSHDP:ST1對應有:POPDP:ST1NASP本人在解決第1個問題后,在中斷中調用系統信號量函數,發現一調用,系統就崩潰了,經過試驗,發現是堆棧指針對齊的問題,即ASP和NASP造成的。ASP受ST1中的一個位控制,所以添加此代碼,保存ST1。同時保存DP1是因為要保證堆棧地址為偶數地址,其實保存DP不起什么作用,僅僅是用來對齊堆棧地址為偶數地址,沒有其他的意思。在os_cpu_c.c文件中,也作了些修改,如下:void*OSTaskStkInit(void(*task)(void*pd),void*pdata,void*ptos,INT16Uopt){INT16U*stk;INT16Utemp;opt=opt;/*'opt'isnotused,preventwarning*/stk=(INT16U*)ptos;/*Loadstackpointer*/temp=((INT32U)pdata)&0x0000ffff;/*Simulatecalltofunctionwithargument*/*stk++=(INT16U)temp;/*保存低16位*/temp=((INT32U)pdata)>>16;/*Simulatecalltofunctionwithargument*/*stk++=(INT16U)(temp);/*保存高16位*/*stk++=0x0000;/*ST0=0x1111*/*stk++=0x0000;/*T=0x0000*/*stk++=0x0000;/*AL=0x3333*/*stk++=0x0000;/*AH=0x2222*/*stk++=0x0000;/*PL=0x5555*/*stk++=0x0000;/*PH=0x4444*/*stk++=0x0000;/*AR0=0x7777*/*stk++=0x0000;/*AR1=0x6666*/*stk++=0x0A0A;/*ST1=0x080B*/*stk++=0x0000;/*DP=0x8888*/*stk++=0x2003;/*IER=0xBBBB*/*stk++=0x2003;/*DBGSTAT=0xAAAA*/temp=((INT32U)task)&0x0000ffff;*stk++=(INT16U)temp;/*保存低16位*/temp=((INT32U)task)>>16;/*Savetaskentry*/*stk++=(INT16U)(temp);/*保存高16位*///PUSHRPCtemp=((INT32U)task)&0x0000ffff;/*RPCL=0xCCCC*/*stk++=(INT16U)temp;/*保存低16位*/temp=((INT32U)task)>>16;/*RPCH=0xCCCC*/*stk++=(INT16U)(temp);/*保存高16位*//*下為手工保存的寄存器PUSHAR1H:AR0HPUSHXAR2PUSHXAR3PUSHXAR4PUSHXAR5PUSHXAR6PUSHXAR7PUSHXTPUSHST1:DP*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0000;/*保存高16位*/*stk++=0x0A0A;/*ST1*/*stk++=0x0000;/*DP*/stk++;return((void*)stk);}文件中比較重要的地方都以紅色作了標記,這里特別說明:temp=((INT32U)pdata)&0x0000ffff;/*Simulatecalltofunctionwithargument*/*stk++=(INT16U)temp;/*保存低16位*/temp=((INT32U)pdata)>>16;/*Simulatecalltofunctionwithargument*/*stk++=(INT16U)(temp);/*保存高16位*/這個好像沒什么用,這樣做只是為了避免編譯時出現告警(和原來比較)。*stk++=0x0A0A;/*ST1=0x080B*/這個特別重要。因為進入任務后,中斷必須都是開著的,這個值直接用來設置ST1,詳細見ST1的位說明。任務在第一次進入時,NASP指令不能起作用也由這里控制(任務堆棧一般為偶地址)。總中斷是由ST1來控制的,因此,在進入任務前,你開關總中斷都是無意義的操作,只有這里才是開總中斷的地方,要特別注意。當然,你也可以在每個任務開始設置總中斷,但那樣比較復雜。

uCOS 2.00 在TMS320F2812上的移植完整攻略

*stk++ = 0x2003; /* IER = 0xBBBB */

*stk++ = 0x2003; /* DBGSTAT = 0xAAAA */

這個也很重要,是中斷允許位IER。原來是設置的0xFFFF,即任務開始時,所有的中斷允許開著的,這必將和你的設想不一樣。因此這個應該根據你的系統使用的中斷的多少來自己確定,這個也是整個C文件中,要根據用戶使用情況修改的部分,當然,你也可以在每個任務開始時來設置IER,效果差不多,但必須包含空閑任務。因此,推薦使用在這里設置IER。

針對手工保存通用寄存器,函數中做了相應的處理,這個沒什么好說的。

對于中斷的說明:

如果你的系統使用的中斷程序中,不需要任務切換,不使用uCOS的系統服務,你可以使用“interrupt”關鍵字來聲明一個中斷,并且是C代碼的。要注意的是,在這種中斷中,中斷必須是關閉的,不能開中斷。

如果你的中斷程序中,需要任務切換或uCOS的系統服務,那么你的中斷只能用匯編代碼,但可以在匯編中調用C代碼,這里要注意的是,此時C代碼不能用“interrupt”來申明。這里附加一個中斷匯編程序“EVA_T1PINT_ISR.src”,你可以進行參考。

.global _EVA_T1PINT_ISR

_EVA_T1PINT_ISR:

.ref _EVA_T1PINT_ISR_C

.ref _OSIntNesting

.ref _OSIntExit

.ref _PieCtrl

.ref _EvaRegs

PUSH RPC

PUSH AR1H:AR0H

PUSH XAR2

PUSH XAR3

PUSH XAR4

PUSH XAR5

PUSH XAR6

PUSH XAR7

PUSH XT

ASP

PUSH DP:ST1

CLRC PAGE0,OVM

CLRC AMODE

MOVW DP, #_PieCtrl+1

OR @_PieCtrl+1, #0x0002

MOVW DP, #_EvaRegs+47

OR @_EvaRegs+47, #0x0080

MOVW DP,#_OSIntNesting ;提示uc/OS-II 進入中斷

INC @_OSIntNesting ; |168|

LCR _EVA_T1PINT_ISR_C

LCR _OSIntExit

POP DP:ST1

NASP

POP XT

POP XAR7

POP XAR6

POP XAR5

POP XAR4

POP XAR3

POP XAR2

POP AR1H:AR0H

POP RPC

IRET

說明:

MOVW DP, #_PieCtrl+1

OR @_PieCtrl+1, #0x0002

MOVW DP, #_EvaRegs+47

OR @_EvaRegs+47, #0x0080

是匯編中清ACK及其他位的操作。這個可以放到C代碼中,全憑個人喜好。

CLRC PAGE0,OVM

CLRC AMODE

這個是一般的中斷中都會有的,加和不加好像沒什么不同,保險起見,還是加上了。

LCR _EVA_T1PINT_ISR_C

調用C代碼,你只需要申明void EVA_T1PINT_ISR_C(void)這個函數就可以了,這個函數不能用“interrupt”來申明。這里面你可以開中斷,也可以不開,全憑需要。

關于任務開關中斷的說明:

由于IER是在任務切換的時候被保存到任務堆棧,因此任務開關中斷不能用管IER位的方式來解決,而必須去關閉相應的外設的中斷允許位來操作。好在2812中每個實用的中斷都有對應的中斷允許位,因而不需要去設置IER。

看門狗的使用:

多任務中,看門狗如何使用,現在還沒想到好主意,只好使用了一個專門的任務來做看門狗。

0
回復
add222
LV.4
4
2014-01-15 16:09
@add222
uCOS2.00在TMS320F2812上的移植完整攻略*stk++=0x2003;/*IER=0xBBBB*/*stk++=0x2003;/*DBGSTAT=0xAAAA*/這個也很重要,是中斷允許位IER。原來是設置的0xFFFF,即任務開始時,所有的中斷允許開著的,這必將和你的設想不一樣。因此這個應該根據你的系統使用的中斷的多少來自己確定,這個也是整個C文件中,要根據用戶使用情況修改的部分,當然,你也可以在每個任務開始時來設置IER,效果差不多,但必須包含空閑任務。因此,推薦使用在這里設置IER。針對手工保存通用寄存器,函數中做了相應的處理,這個沒什么好說的。對于中斷的說明:如果你的系統使用的中斷程序中,不需要任務切換,不使用uCOS的系統服務,你可以使用“interrupt”關鍵字來聲明一個中斷,并且是C代碼的。要注意的是,在這種中斷中,中斷必須是關閉的,不能開中斷。如果你的中斷程序中,需要任務切換或uCOS的系統服務,那么你的中斷只能用匯編代碼,但可以在匯編中調用C代碼,這里要注意的是,此時C代碼不能用“interrupt”來申明。這里附加一個中斷匯編程序“EVA_T1PINT_ISR.src”,你可以進行參考。.global_EVA_T1PINT_ISR_EVA_T1PINT_ISR:.ref_EVA_T1PINT_ISR_C.ref_OSIntNesting.ref_OSIntExit.ref_PieCtrl.ref_EvaRegsPUSHRPCPUSHAR1H:AR0HPUSHXAR2PUSHXAR3PUSHXAR4PUSHXAR5PUSHXAR6PUSHXAR7PUSHXTASPPUSHDP:ST1CLRCPAGE0,OVMCLRCAMODEMOVWDP,#_PieCtrl+1OR@_PieCtrl+1,#0x0002MOVWDP,#_EvaRegs+47OR@_EvaRegs+47,#0x0080MOVWDP,#_OSIntNesting;提示uc/OS-II進入中斷INC@_OSIntNesting;|168|LCR_EVA_T1PINT_ISR_CLCR_OSIntExitPOPDP:ST1NASPPOPXTPOPXAR7POPXAR6POPXAR5POPXAR4POPXAR3POPXAR2POPAR1H:AR0HPOPRPCIRET說明:MOVWDP,#_PieCtrl+1OR@_PieCtrl+1,#0x0002MOVWDP,#_EvaRegs+47OR@_EvaRegs+47,#0x0080是匯編中清ACK及其他位的操作。這個可以放到C代碼中,全憑個人喜好。CLRCPAGE0,OVMCLRCAMODE這個是一般的中斷中都會有的,加和不加好像沒什么不同,保險起見,還是加上了。LCR_EVA_T1PINT_ISR_C調用C代碼,你只需要申明voidEVA_T1PINT_ISR_C(void)這個函數就可以了,這個函數不能用“interrupt”來申明。這里面你可以開中斷,也可以不開,全憑需要。關于任務開關中斷的說明:由于IER是在任務切換的時候被保存到任務堆棧,因此任務開關中斷不能用管IER位的方式來解決,而必須去關閉相應的外設的中斷允許位來操作。好在2812中每個實用的中斷都有對應的中斷允許位,因而不需要去設置IER。看門狗的使用:多任務中,看門狗如何使用,現在還沒想到好主意,只好使用了一個專門的任務來做看門狗。
0
回復
2017-04-01 17:55
@add222
uCOS2.00在TMS320F2812上的移植完整攻略.rar

厲害!最近也在往28035系列上移植,參考下你的例程,謝謝了!

0
回復
主站蜘蛛池模板: 河南省| 乐东| 无锡市| 湘乡市| 二手房| 永康市| 台前县| 金乡县| 旌德县| 海林市| 杭锦后旗| 丰镇市| 高雄县| 健康| 肇州县| 明溪县| 农安县| 青铜峡市| 贺州市| 康保县| 周宁县| 正定县| 舒兰市| 壶关县| 绥滨县| 奉贤区| 丰城市| 五大连池市| 抚松县| 易门县| 德阳市| 大石桥市| 池州市| 浮山县| 阳西县| 枝江市| 河源市| 进贤县| 海城市| 东丽区| 新巴尔虎左旗|