當前位置:首頁 > 嵌入式 > 嵌入式硬件
[導讀]前一段時間,我參與了一個SNMP網(wǎng)管板的項目,我負責硬件設計和單板軟件開發(fā)。該板的硬件由 MCS51+RTL8019AS組成,有64K FLASH 和64K SRAM。軟件部分有操作系統(tǒng)和TCPIP協(xié)議

前一段時間,我參與了一個SNMP網(wǎng)管板的項目,我負責硬件設計和單板軟件開發(fā)。該板的硬件由 MCS51+RTL8019AS組成,有64K FLASH 和64K SRAM。軟件部分有操作系統(tǒng)和TCPIP協(xié)議棧。硬件比較簡單,用了一個月就搞定了,協(xié)議棧我參考了老古開發(fā)板的部分程序又上網(wǎng)找了SNMP源代碼也很快完成了,但是測試時發(fā)現(xiàn)當使用較低時鐘頻率的CPU時(為了降低成本),由于ASN.1編解碼部分過于龐大,而我的程序又是一個大循環(huán),AGENT的響應速度受到嚴重影響,用戶界面也反應遲鈍。更壞的消息是公司為了適應市場需求,還要在上面跑PPP和HTTP。那樣的話,我就得用40MHz的 AT89C51RD2或者人為的把程序斷成幾部分然后用狀態(tài)機的方法在運行時再把它們連接起來。不過,我不想增加成本,也不想把程序搞亂,迫不得已,只好使用操作系統(tǒng)。 說實在的,一開始我也不是很有把握,一來我不清楚51的FLASH是否裝得下這么多代碼,二來我只做過OS應用開發(fā),對于它的移植想都不敢想。不過,我在 BBS上搜索了一陣兒后還是有了一些頭緒。我找到了幾個OS的源代碼(我喜歡用現(xiàn)成的),按照代碼大小、實時性、使用人數(shù)、眾人口碑等標準,最后選定了 uCOS2。我感覺它的實時性有保障,延時可預測,代碼據(jù)說可小到2K,網(wǎng)上討論這個話題的人也比較多,而且它的網(wǎng)站上有針對KEIL C51的移植實例。 經(jīng)過一番查找,我得到了5個版本。其中3個是用KEIL編譯的。本來我想直接把OS代碼嵌到應用程序中,但后來發(fā)現(xiàn)沒有一個可以直接使用。有的無法用 KEIL直接編譯,有的需要修改DLL在軟件仿真下使用。而我需要的是能在串口輸入輸出,不需要修改任何無關軟件,能在軟件仿真和硬件上運行的實時多任務操作系統(tǒng)。沒有辦法,我只好硬著頭皮去改編。 我分析了自己的劣勢:1。KEIL剛開始使用,不太熟悉;2?;旌暇幊桃郧皬臎]有作過;3。時間緊迫,要在1個月內(nèi)搞定。而我的優(yōu)勢就是有5個移植實例可供參考,可以上網(wǎng)查資料。一開始,我用“堆棧”、“混合編程”、“匯編”、“ucos”等關鍵字在C51BBS和老古論壇上檢索相關信息并逐條閱讀,讀過之后,頭腦中的思路逐漸清晰了。我了解到在KEIL的HLP目錄下有A51.PDF和C51.PDF非常全面的介紹了匯編和C51,是KEIL的權威用戶手冊;SP初始化、內(nèi)存清0等操作在STARTUP.A51文件中實現(xiàn),用戶可以改寫它;KEIL的變量,子程序等的分配信息可以在.M51文件里查到;KEIL自己的論壇里有很多疑難問題的解答……通過閱讀并經(jīng)過思考,解決了堆棧起點、堆??臻g大小的設定等關鍵問題。論壇里的問題有些是我沒有想到的,這使我發(fā)現(xiàn)了自己的疏漏。 在網(wǎng)上獲得大量信息后,我開始閱讀《uCOSII》中文版,一共讀了3遍。第一遍是瀏覽,了解到uCOSII包括任務調(diào)度、時間管理、內(nèi)存管理、資源管理(信號量、郵箱、消息隊列)四大部分,沒有文件系統(tǒng)、網(wǎng)絡接口、輸入輸出界面。它的移植只與4個文件相關:匯編文件(OS_CPU_A.ASM)、處理器相關C文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。有64個優(yōu)先級,系統(tǒng)占用8個,用戶可創(chuàng)建56個任務,不支持時間片輪轉(zhuǎn)。第二遍主要是把整個工作過程在頭腦里過了一下,不懂地方有針對性的查書,重點是思考工作原理和流程。我發(fā)現(xiàn)其實它的思路挺簡單的。就是 “近似地每時每刻總是讓優(yōu)先級最高的任務處于運行狀態(tài)” 。為了保證這一點,它在調(diào)用系統(tǒng)API函數(shù)、中斷結束、定時中斷結束時總是執(zhí)行調(diào)度算法。原作者通過事先計算好數(shù)據(jù),簡化了運算量,通過精心設計就緒表結構,使得延時可預知。任務的切換是通過模擬一次中斷實現(xiàn)的。第三遍重點看了移植部分的內(nèi)容。對照實例,研究了代碼的具體實現(xiàn)方法。 前期準備用了20幾天,真正編寫代碼只用了1.5天,調(diào)試用了2天。具體過程如下: (1)拷貝書后附贈光盤sourcecode目錄下的內(nèi)容到C:\YY下,刪除不必要的文件和EX1L.C,只剩下p187(《uCOSII》)上列出的文件。 (2)改寫最簡單的OS_CPU.H 數(shù)據(jù)類型的設定見C51.PDF第176頁。注意BOOLEAN要定義成unsigned char 類型,因為bit類型為C51特有,不能用在結構體里。 EA=0關中斷;EA=1開中斷。這樣定義即減少了程序行數(shù),又避免了退出臨界區(qū)后關中斷造成的死機。 MCU-51堆棧從下往上增長(1=向下,0=向上),OS_STK_GROWTH定義為0 #define OS_TASK_SW() OSCtxSw() 因為MCU-51沒有軟中斷指令,所以用程序調(diào)用代替。兩者的堆棧格式相同,RETI指令復位中斷系統(tǒng),RET則沒有。實踐表明,對于MCU-51,用子程序調(diào)用入棧,用中斷返回指令RETI出棧是沒有問題的,反之中斷入棧RET出棧則不行??傊?,對于入棧,子程序調(diào)用與中斷調(diào)用效果是一樣的,可以混用。在沒有中斷發(fā)生的情況下復位中斷系統(tǒng)也不會影響系統(tǒng)正常運行。詳見《uC/OS-II》第八章193頁第12行 (3)改寫OS_CPU_C.C 我設計的堆棧結構如下圖所示: ********************************************************************************* * * ---------- * |OSTCBCur| * ---------- * | * | ----------------------- ---------- * \---->|OSTCBCur->OSTCBStkPtr| SP---->| | * ----------------------- ---------- * | | | * | ---------- - ---------- * | | | | | . | * | ---------- | | . | * | | | | | . | * | ---------- | ---------- * | | . |長度 | | +1 * | | . | | ---------- * | | . | | OSStack---->| | 0 * | ---------- | ---------- * | | | | OSStkStart---->| 不關心 | -1 低地址 * | ---------- - ---------- * \-------->| 長度 | 低地址 系統(tǒng)堆棧 * ---------- * 用戶堆棧 長度=SP-OSStkStart ********************************************************************************* TCB結構體中OSTCBStkPtr總是指向用戶堆棧最低地址,該地址空間內(nèi)存放用戶堆棧長度,其上空間存放系統(tǒng)堆棧映像,即:用戶堆??臻g大小=系統(tǒng)堆??臻g大小+1。 SP總是先加1再存數(shù)據(jù),因此,SP初始時指向系統(tǒng)堆棧起始地址(OSStack)減1處(OSStkStart)。很明顯系統(tǒng)堆棧存儲空間大小=SP- OSStkStart。 任務切換時,先保存當前任務堆棧內(nèi)容。方法是:用SP-OSStkStart得出保存字節(jié)數(shù),將其寫入用戶堆棧最低地址內(nèi),以用戶堆棧最低地址為起址,以 OSStkStart為系統(tǒng)堆棧起址,由系統(tǒng)棧向用戶棧拷貝數(shù)據(jù),循環(huán)SP-OSStkStart次,每次拷貝前先將各自棧指針增1。 其次,恢復最高優(yōu)先級任務系統(tǒng)堆棧。方法是:獲得最高優(yōu)先級任務用戶堆棧最低地址,從中取出“長度”,以最高優(yōu)先級任務用戶堆棧最低地址為起址,以 OSStkStart為系統(tǒng)堆棧起址,由用戶棧向系統(tǒng)棧拷貝數(shù)據(jù),循環(huán)“長度”數(shù)值指示的次數(shù),每次拷貝前先將各自棧指針增1。 用戶堆棧初始化時從下向上依次保存:用戶堆棧長度(15),PCL,PCH,PSW,ACC,B,DPL,DPH,R0,R1,R2,R3,R4,R5,R6,R7。不保存SP,任務切換時根據(jù)用戶堆棧長度計算得出。 OSTaskStkInit函數(shù)總是返回用戶棧最低地址。 操作系統(tǒng)tick時鐘我使用了51單片機的T0定時器,它的初始化代碼用C寫在了本文件中。 最后還有幾點必須注意的事項。本來原則上我們不用修改與處理器無關的代碼,但是由于KEIL編譯器的特殊性,這些代碼仍要多處改動。因為KEIL缺省情況下編譯的代碼不可重入,而多任務系統(tǒng)要求并發(fā)操作導致重入,所以要在每個C函數(shù)及其聲明后標注reentrant關鍵字。另外,“pdata”、 “data”在uCOS中用做一些函數(shù)的形參,但它同時又是KEIL的關鍵字,會導致編譯錯誤,我通過把“pdata”改成 “ppdata”,“data”改成“ddata”解決了此問題。OSTCBCur、OSTCBHighRdy、OSRunning、 OSPrioCur、OSPrioHighRdy這幾個變量在匯編程序中用到了,為了使用Ri訪問而不用DPTR,應該用KEIL擴展關鍵字IDATA將它們定義在內(nèi)部RAM中。 (4)重寫OS_CPU_A.ASM A51宏匯編的大致結構如下: NAME 模塊名 ;與文件名無關 ;定義重定位段 必須按照C51格式定義,匯編遵守C51規(guī)范。段名格式為:?PR?函數(shù)名?模塊名 ;聲明引用全局變量和外部子程序 注意關鍵字為“EXTRN”沒有‘E’ 全局變量名直接引用 無參數(shù)/無寄存器參數(shù)函數(shù) FUNC 帶寄存器參數(shù)函數(shù) _FUNC 重入函數(shù) _?FUNC ;分配堆棧空間 只關心大小,堆棧起點由keil決定,通過標號可以獲得keil分配的SP起點。切莫自己分配堆棧起點,只要用DS通知KEIL預留堆棧空間即可。 ?STACK段名與STARTUP.A51中的段名相同,這意味著KEIL在LINK時將把兩個同名段拼在一起,我預留了40H個字節(jié),STARTUP.A51預留了1個字節(jié),LINK完成后堆棧段總長為41H。查看yy.m51知KEIL將堆棧起點定在21H,長度41H,處于內(nèi)部 RAM中。 ;定義宏 宏名 MACRO 實體 ENDM ;子程序 OSStartHighRdy OSCtxSw OSIntCtxSw OSTickISR SerialISR END ;聲明匯編源文件結束 一般指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù) 詳見C51.PDF第178頁 低位地址存高8位值,高位地址存低8位值。例如0x1234,基址+0:0x12 基址+1:0x34 (5)移植串口驅(qū)動程序 在此之前我寫過基于中斷的串口驅(qū)動程序,包括打印字節(jié)/字/長字/字符串,讀串口,初始化串口/緩沖區(qū)。把它改成重入函數(shù)即可直接使用。 系統(tǒng)提供的顯示函數(shù)是并發(fā)的,它不是直接顯示到串口,而是先輸出到顯存,用戶不必擔心IO慢速操作影響程序運行。串口輸入也采用了同樣的技術,他使得用戶在CPU忙于處理其他任務時照樣可以盲打輸入命令。 (6)編寫測試程序Demo(YY.C) Demo程序創(chuàng)建了3個任務A、B、C優(yōu)先級分別為2、3、4,A每秒顯示一次,B每3秒顯示一次,C每6秒顯示一次。從顯示結果看,顯示3個A后顯示1 個B,顯示6個A和2個B后顯示1個C,結果顯然正確。 顯示結果如下: AAAAAA111111 is active AAAAAA111111 is active AAAAAA111111 is active BBBBBB333333 is active AAAAAA111111 is active AAAAAA111111 is active AAAAAA111111 is active BBBBBB333333 is active CCCCCC666666 is active AAAAAA111111 is active AAAAAA111111 is active AAAAAA111111 is active BBBBBB333333 is active AAAAAA111111 is active AAAAAA111111 is active AAAAAA111111 is active BBBBBB333333 is active CCCCCC666666 is active Demo程序經(jīng)Keil701編譯后,代碼量為7-8K,可直接在KeilC51上仿真運行。 編譯時要將OS_CPU_C.C、UCOS_II.C、OS_CPU_A.ASM、YY.C加入項目 以上是我這次移植uCOS51的一些心得,寫出來只是讓準備在51上運行操作系統(tǒng)的同行們少走彎路并增強使用信心。我強烈推薦大家在自己的51系統(tǒng)中使用 uCOS這個簡單實用的自己的操作系統(tǒng)。它的大小應該不是問題,性能上的提高卻是顯著的。但愿此文能對朋友們有所幫助,錯誤在所難免,希望各位大蝦指正,諸位高手們見笑了! 注:全部源碼可來信索要(asdjf@163.com),以下僅為關鍵代碼部分。 文件名 : OS_CPU_A.ASM $NOMOD51 EA BIT 0A8H.7 SP DATA 081H B DATA 0F0H ACC DATA 0E0H DPH DATA 083H DPL DATA 082H PSW DATA 0D0H TR0 BIT 088H.4 TH0 DATA 08CH TL0 DATA 08AH NAME OS_CPU_A ;模塊名 ;定義重定位段 ?PR?OSStartHighRdy?OS_CPU_A SEGMENT CODE ?PR?OSCtxSw?OS_CPU_A SEGMENT CODE ?PR?OSIntCtxSw?OS_CPU_A SEGMENT CODE ?PR?OSTickISR?OS_CPU_A SEGMENT CODE ?PR?_?serial?OS_CPU_A SEGMENT CODE ;聲明引用全局變量和外部子程序 EXTRN IDATA (OSTCBCur) EXTRN IDATA (OSTCBHighRdy) EXTRN IDATA (OSRunning) EXTRN IDATA (OSPrioCur) EXTRN IDATA (OSPrioHighRdy) EXTRN CODE (_?OSTaskSwHook) EXTRN CODE (_?serial) EXTRN CODE (_?OSIntEnter) EXTRN CODE (_?OSIntExit) EXTRN CODE (_?OSTimeTick) ;對外聲明4個不可重入函數(shù) PUBLIC OSStartHighRdy PUBLIC OSCtxSw PUBLIC OSIntCtxSw PUBLIC OSTickISR ;PUBLIC SerialISR ;分配堆??臻g。只關心大小,堆棧起點由keil決定,通過標號可以獲得keil分配的SP起點。 ?STACK SEGMENT IDATA RSEG ?STACK OSStack: DS 40H OSStkStart IDATA OSStack-1 ;定義壓棧出棧宏 PUSHALL MACRO PUSH PSW PUSH ACC PUSH B PUSH DPL PUSH DPH MOV A,R0 ;R0-R7入棧 PUSH ACC MOV A,R1 PUSH ACC MOV A,R2 PUSH ACC MOV A,R3 PUSH ACC MOV A,R4 PUSH ACC MOV A,R5 PUSH ACC MOV A,R6 PUSH ACC MOV A,R7 PUSH ACC ;PUSH SP ;不必保存SP,任務切換時由相應程序調(diào)整 ENDM POPALL MACRO ;POP ACC ;不必保存SP,任務切換時由相應程序調(diào)整 POP ACC ;R0-R7出棧 MOV R7,A POP ACC MOV R6,A POP ACC MOV R5,A POP ACC MOV R4,A POP ACC MOV R3,A POP ACC MOV R2,A POP ACC MOV R1,A POP ACC MOV R0,A POP DPH POP DPL POP B POP ACC POP PSW ENDM ;子程序 ;------------------------------------------------------------------------- RSEG ?PR?OSStartHighRdy?OS_CPU_A OSStartHighRdy: USING 0 ;上電后51自動關中斷,此處不必用CLR EA指令,因為到此處還未開中斷,本程序退出后,開中斷。 LCALL _?OSTaskSwHook OSCtxSw_in: ;OSTCBCur ===> DPTR 獲得當前TCB指針,詳見C51.PDF第178頁 MOV R0,#LOW (OSTCBCur) ;獲得OSTCBCur指針低地址,指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù) INC R0 MOV DPH,@R0 ;全局變量OSTCBCur在IDATA中 INC R0 MOV DPL,@R0 ;OSTCBCur->OSTCBStkPtr ===> DPTR 獲得用戶堆棧指針 INC DPTR ;指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù) MOVX A,@DPTR ;.OSTCBStkPtr是void指針 MOV R0,A INC DPTR MOVX A,@DPTR MOV R1,A MOV DPH,R0 MOV DPL,R1 ;*UserStkPtr ===> R5 用戶堆棧起始地址內(nèi)容(即用戶堆棧長度放在此處) 詳見文檔說明 指針用法詳見C51.PDF第169頁 MOVX A,@DPTR ;用戶堆棧中是unsigned char類型數(shù)據(jù) MOV R5,A ;R5=用戶堆棧長度 ;恢復現(xiàn)場堆棧內(nèi)容 MOV R0,#OSStkStart restore_stack: INC DPTR INC R0 MOVX A,@DPTR MOV @R0,A DJNZ R5,restore_stack ;恢復堆棧指針SP MOV SP,R0 ;OSRunning=TRUE MOV R0,#LOW (OSRunning) MOV @R0,#01 POPALL SETB EA ;開中斷 RETI ;------------------------------------------------------------------------- RSEG ?PR?OSCtxSw?OS_CPU_A OSCtxSw: PUSHALL OSIntCtxSw_in: ;獲得堆棧長度和起址 MOV A,SP CLR C SUBB A,#OSStkStart MOV R5,A ;獲得堆棧長度 ;OSTCBCur ===> DPTR 獲得當前TCB指針,詳見C51.PDF第178頁 MOV R0,#LOW (OSTCBCur) ;獲得OSTCBCur指針低地址,指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù) INC R0 MOV DPH,@R0 ;全局變量OSTCBCur在IDATA中 INC R0 MOV DPL,@R0 ;OSTCBCur->OSTCBStkPtr ===> DPTR 獲得用戶堆棧指針 INC DPTR ;指針占3字節(jié)。+0類型+1高8位數(shù)據(jù)+2低8位數(shù)據(jù) MOVX A,@DPTR ;.OSTCBStkPtr是void指針 MOV R0,A INC DPTR MOVX A,@DPTR MOV R1,A MOV DPH,R0 MOV DPL,R1 ;保存堆棧長度 MOV A,R5 MOVX @DPTR,A MOV R0,#OSStkStart ;獲得堆棧起址 save_stack: INC DPTR INC R0 MOV A,@R0 MOVX @DPTR,A DJNZ R5,save_stack ;調(diào)用用戶程序 LCALL _?OSTaskSwHook ;OSTCBCur = OSTCBHighRdy MOV R0,#OSTCBCur MOV R1,#OSTCBHighRdy MOV A,@R1 MOV @R0,A INC R0 INC R1 MOV A,@R1 MOV @R0,A INC R0 INC R1 MOV A,@R1 MOV @R0,A ;OSPrioCur = OSPrioHighRdy 使用這兩個變量主要目的是為了使指針比較變?yōu)樽止?jié)比較,以便節(jié)省時間。 MOV R0,#OSPrioCur MOV R1,#OSPrioHighRdy MOV A,@R1 MOV @R0,A LJMP OSCtxSw_in ;------------------------------------------------------------------------- RSEG ?PR?OSIntCtxSw?OS_CPU_A OSIntCtxSw: ;調(diào)整SP指針去掉在調(diào)用OSIntExit(),OSIntCtxSw()過程中壓入堆棧的多余內(nèi)容 ;SP=SP-4 MOV A,SP CLR C SUBB A,#4 MOV SP,A LJMP OSIntCtxSw_in ;------------------------------------------------------------------------- CSEG AT 000BH ;OSTickISR LJMP OSTickISR ;使用定時器0 RSEG ?PR?OSTickISR?OS_CPU_A OSTickISR: USING 0 PUSHALL CLR TR0 MOV TH0,#70H ;定義Tick=50次/秒(即0.02秒/次) MOV TL0,#00H ;OS_CPU_C.C 和 OS_TICKS_PER_SEC SETB TR0 LCALL _?OSIntEnter LCALL _?OSTimeTick LCALL _?OSIntExit POPALL RETI ;------------------------------------------------------------------------- CSEG AT 0023H ;串口中斷 LJMP SerialISR ;工作于系統(tǒng)態(tài),無任務切換。 RSEG ?PR?_?serial?OS_CPU_A SerialISR: USING 0 PUSHALL CLR EA LCALL _?serial SETB EA POPALL RETI ;------------------------------------------------------------------------- END ;------------------------------------------------------------------------- 文件名 : OS_CPU_C.C void *OSTaskStkInit (void (*task)(void *pd), void *ppdata, void *ptos, INT16U opt) reentrant { OS_STK *stk; ppdata = ppdata; opt = opt; //opt沒被用到,保留此語句防止告警產(chǎn)生 stk = (OS_STK *)ptos; //用戶堆棧最低有效地址 *stk++ = 15; //用戶堆棧長度 *stk++ = (INT16U)task %26;amp; 0xFF; //任務地址低8位 *stk++ = (INT16U)task >> 8; //任務地址高8位 *stk++ = 0x00; //PSW *stk++ = 0x0A; //ACC *stk++ = 0x0B; //B *stk++ = 0x00; //DPL *stk++ = 0x00; //DPH *stk++ = 0x00; //R0 *stk++ = 0x01; //R1 *stk++ = 0x02; //R2 *stk++ = 0x03; //R3 *stk++ = 0x04; //R4 *stk++ = 0x05; //R5 *stk++ = 0x06; //R6 *stk++ = 0x07; //R7 //不用保存SP,任務切換時根據(jù)用戶堆棧長度計算得出。 return ((void *)ptos); } #if OS_CPU_HOOKS_EN void OSTaskCreateHook (OS_TCB *ptcb) reentrant { ptcb = ptcb; /* Prevent compiler warning */ } void OSTaskDelHook (OS_TCB *ptcb) reentrant { ptcb = ptcb; /* Prevent compiler warning */ } void OSTimeTickHook (void) reentrant { } #endif //初始化定時器0 void InitTimer0(void) reentrant { TMOD=TMOD%26;amp;0xF0; TMOD=TMOD|0x01; //模式1(16位定時器),僅受TR0控制 TH0=0x70; //定義Tick=50次/秒(即0.02秒/次) TL0=0x00; //OS_CPU_A.ASM 和 OS_TICKS_PER_SEC ET0=1; //允許T0中斷 TR0=1; } 文件名 : YY.C #include #define MAX_STK_SIZE 64 void TaskStartyya(void *yydata) reentrant; void TaskStartyyb(void *yydata) reentrant; void TaskStartyyc(void *yydata) reentrant; OS_STK TaskStartStkyya[MAX_STK_SIZE+1];//注意:我在ASM文件中設置?STACK空間為40H即64,不要超出范圍。 OS_STK TaskStartStkyyb[MAX_STK_SIZE+1];//用戶棧多一個字節(jié)存長度 OS_STK TaskStartStkyyc[MAX_STK_SIZE+1]; void main(void) { OSInit(); InitTimer0(); InitSerial(); InitSerialBuffer(); OSTaskCreate(TaskStartyya, (void *)0, %26;amp;TaskStartStkyya[0],2); OSTaskCreate(TaskStartyyb, (void *)0, %26;amp;TaskStartStkyyb[0],3); OSTaskCreate(TaskStartyyc, (void *)0, %26;amp;TaskStartStkyyc[0],4); OSStart(); } void TaskStartyya(void *yydata) reentrant { yydata=yydata; clrscr(); PrintStr("\n\t\t*******************************\n"); PrintStr("\t\t* Hello! The world. *\n"); PrintStr("\t\t*******************************\n\n\n"); for(;;){ PrintStr("\tAAAAAA111111 is active.\n"); OSTimeDly(OS_TICKS_PER_SEC); } } void TaskStartyyb(void *yydata) reentrant { yydata=yydata; for(;;){ PrintStr("\tBBBBBB333333 is active.\n"); OSTimeDly(3*OS_TICKS_PER_SEC); } } void TaskStartyyc(void *yydata) reentrant { yydata=yydata; for(;;){ PrintStr("\tCCCCCC666666 is active.\n"); OSTimeDly(6*OS_TICKS_PER_SEC); } } * - 本貼最后修改時間:2003-5-29 11:25:08 修改者:gdtyy * - 修改原因:+ 作者信箱 asdjf@163.com 社區(qū)原文 http://www.21icbbs.com/club/bbs/list.asp?boardid=8%26;amp;page=1%26;amp;t=338692%26;amp;tp=uCOS51%u79FB%u690D%u5FC3%u5F97

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉