昨天晚上真是 糾結(jié)。為了一個(gè)簡單的問題糾結(jié)了這么久。先不說到一點(diǎn)影響了睡眠,關(guān)鍵問題一直沒解決。今早到了公司,還耽誤了工作,滿腦子是那個(gè)問題的答案。
單片機(jī)的操作系統(tǒng)內(nèi)核果然要看明白得花很大的心思,里面的一些底層匯編代碼真的讓人很糾結(jié)。STACK為了這個(gè)我調(diào)試運(yùn)行,發(fā)現(xiàn)是i:0x17于是我直接 翻看RAM里的IDATA中的數(shù)據(jù)發(fā)現(xiàn)這個(gè)地址的內(nèi)容是0x88,在OSStart()吧堆棧STACK賦給了臨時(shí)的堆棧指針變量*cp,我 查找STACK的定義,只找到了extern unsigned char STACK[1]外部引用申明,于是我繼續(xù)找,在匯編代碼中找到這個(gè)的定義
?STACK SEGMENT IDATA
RSEG ?STACK
STACK: DS 1
這匯編代碼的偽指令我找了半天沒搜到什么意思,不過現(xiàn)在知道 了 RSEG 吧已申明的段設(shè)置為當(dāng)前段 STACK DS 1 這句話一直想不通,希望通過調(diào)試找到端倪。后來才發(fā)現(xiàn)什么都看不出來。在main()內(nèi)部查看SP=0x15到OSStart()SP=0x17,我怎么 也想不明白,我查看了0x15開始的內(nèi)存塊,發(fā)現(xiàn)a7 03,也就是說函數(shù)吧下條指令的地址壓入棧中,使得SP+2了所以變成SP=0x17,于是我吧DS 1認(rèn)為就是現(xiàn)在的地址。于是我就想看看在main()之前是跑在哪個(gè)程序中的,我想通過查看0x15前2位找到代碼地址,實(shí)踐發(fā)現(xiàn)是不對(duì)的。于是我吧運(yùn)行 到mian()去掉,于是調(diào)試,打開匯編窗口發(fā)現(xiàn)起始地址時(shí)0000H 這個(gè)代碼是個(gè)跳轉(zhuǎn)指令,這時(shí)候我看見SP直接是0x07我 不明白這是為什么,然后我網(wǎng)上搜資料,突然就發(fā)現(xiàn)一句話。單片機(jī)復(fù)位程序從0000H運(yùn)行,SP從0x07開始,可這是為什么呢?總算我看到有人說這個(gè), 突然想到工作寄存器組要占8位,于是這個(gè)也知道了。然后往下跑,發(fā)現(xiàn)有mov sp (0x81) #OSFastSwap(0x15)這里告訴我為什么main()里的SP是0x15可是OSFastSwap又是哪定義的呢?我 找啊找,問 朋友,朋友告訴我這個(gè)定義的位置,我看到了,但是又開始糾結(jié)了,因?yàn)槟蔷涠x是這樣的 unsigned char OSFastSwap= 0xff 我 查看0x15的內(nèi)容不是0xff我 就 奇怪 了 0x15不是地址那 0xff在哪,于是一直在 頭疼這個(gè),后來看下時(shí)間不早了就休息了 。今早花了3個(gè)小時(shí)吧所有的問題都解決了。
首先程序中有個(gè)mov r0 #7F昨天看了半天不知道怎么回事,今早看了51啟動(dòng)代碼才知道是吧低128個(gè)字節(jié)清零的操作代碼的一部分。這個(gè)是寄存器初始化的部分那 OSFastSwap里的值是在后面賦值 mov sp (0x81) #OSFastSwap(0x15) 這里還沒到達(dá)賦值的時(shí)間段。 調(diào)試進(jìn)入到main()就能查看到0x15這個(gè)值是FF 。早上我學(xué)會(huì)看.m51結(jié)尾的文件是一些編譯后創(chuàng)建的內(nèi)存映射的表格,上面告訴了每個(gè)變量每個(gè)函數(shù)入口地址。也是這個(gè)我才知道 DS 1真正的意思。預(yù)留一個(gè)存儲(chǔ)單元。表格上已經(jīng)告訴我0x16前地址被什么所占用,所以堆棧預(yù)留一個(gè)存儲(chǔ)單元的地址就到0x16了。這下所有的理順了。 后 面就是直接吧最高優(yōu)先級(jí)的入口地址直接存到SP中,然后函數(shù)返回直接吧PC的指針指向最高優(yōu)先級(jí)的任務(wù)中跑程序。
寫下這篇文章,一是自己攻克第一個(gè)難關(guān)做個(gè)記錄,二是順便讓硬件開發(fā)初學(xué)者學(xué)習(xí)RTOS對(duì)STACK那段代碼有個(gè)了解。
歡迎光臨 (http://www.raoushi.com/bbs/) | Powered by Discuz! X3.1 |