版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、小梅哥 AC620 FPGA 開發(fā)板SOPC 設(shè)計(jì)全功能高性價(jià)比FPGA 開發(fā)板AC620 火熱銷售中,配套 800 頁。:https/item.htm?spm=a1z10.1-c-s.w4004-.6.8uPVJ6&id=544830995588目錄NIOS II 開發(fā)elf 文件總結(jié)3失敗4CPU 運(yùn)行一段時(shí)間后停止10程序運(yùn)行不正確11解決 NIOS II 工程移動在磁盤上位置后 project 無法編譯問題16sof 與 NIOS II 的 elf 固件合并 jic 得到文件29Symbol NULL could not be resolved41設(shè)置 NIOS II 軟件工程頭文件包
2、含路徑42EPCS 使用相關(guān)要點(diǎn)43使用非器NIOS II 軟件45EPCS拔掉器或者關(guān)閉 NIOS II EDS 軟件,開發(fā)板上的系統(tǒng)即停止運(yùn)行.47編譯 NIOS 軟件工程提示” Permission denied”47設(shè)置 Eclipse 在編譯(build)前自動保存源代碼文件48切換 NIOS II CPU 的主內(nèi)存后軟中需要注意的幾點(diǎn)設(shè)置49NIOS II 開發(fā)總結(jié)從開始接觸 Altera(現(xiàn)在應(yīng)該叫 intel PSG 了)的 NIOS II 處理器,到現(xiàn)在,已經(jīng)有 6 個(gè)年頭了。從開始的 C 語言都不懂,到現(xiàn)在能使用 NIOS II 開發(fā)一些實(shí)用的東西,中間的過程也是非常的曲折
3、。最開始的時(shí)候,完全是一般,走一步,十個(gè)坑,沒人指導(dǎo),填幾天,再走一步,再填一個(gè)坑。到了后來對這個(gè)東西開始心生敬畏,敬畏不是因?yàn)樗卸嗝炊嗝磸?qiáng)大,而是在學(xué)習(xí)和使用它的過程中,讓我對 CPU 架構(gòu),單片機(jī)系統(tǒng)實(shí)現(xiàn)思路和編程方法有了較為底層的認(rèn)識,也算是一個(gè)升華吧,雖然在這個(gè)過程中還是常常掉入坑里好久才能爬出來。到了現(xiàn)在,能夠指導(dǎo)大家學(xué)習(xí)和使用 NIOS II 處理器結(jié)合 FPGA RTL 邏輯實(shí)現(xiàn)一些功能,自己也能做一些不大的小東西。這 6 年,感覺就像是按照指數(shù)函數(shù)的曲線進(jìn)步的,最開始很慢,后面越來越快。想想自己能堅(jiān)持到現(xiàn)在,可真不容易(/偷笑)。深知大家在自學(xué)這門技術(shù)的開始半年時(shí)間內(nèi)有多么痛
4、苦。我一早就想出一點(diǎn)NIOS II 方面開發(fā)的實(shí)用性書籍文檔,可一直一個(gè)人打理著各種事情,實(shí)在沒有精力。我也深知當(dāng)下講解和使用 NIOS II 的開發(fā)已經(jīng)有些不那么前沿了,畢竟現(xiàn)在嵌入硬核的 FPGA 應(yīng)用已經(jīng)較為成熟了,NIOS II 這個(gè)處理器處于中間這樣一個(gè)尷尬的位置,實(shí)用性和性價(jià)比值得思量。但是,畢竟 NIOS II 和Xilinx 的MicroBlaze處理器設(shè)計(jì)和開發(fā)思路異曲同工,MicroBlaze 和 Xilinx 當(dāng)前非常受歡迎的 Zynq 硬核 FPGA 開發(fā)思路和過程很像,NIOS II 和 Intel(Altera)的 SOC FPGA 開發(fā)過程和思路很像,因此,學(xué)習(xí)
5、NIOS II 處理器,是一條經(jīng)濟(jì)輕巧的道路。真正掌握了 NIOS II 處理器的應(yīng)用和開發(fā),遷移到 Intel SOC FPGA 上,也就需要 35 周的時(shí)間,換到 Xilinx 的 MicroBlaze 或者 Zynq 平臺上也只需要 58 周。所以,這個(gè)事情值得一做,畢竟,咱每年還有那么多高校學(xué)子需要一個(gè)合適的切入點(diǎn)來進(jìn)入SOPC/SOC 開發(fā)的大門。當(dāng)下定決心做這件事的時(shí)候,我卻犯了難。到底,我該以一種怎樣的方式來開啟系列文檔呢?是從 CPU 架構(gòu)、指令集開講,還是直接從 LED 點(diǎn)燈寫起呢?每天在技術(shù)里,看到大家學(xué)習(xí)時(shí)候遇到各種問題并卻不知道如何解決時(shí),我突然覺得,其實(shí),大家暫時(shí)不缺
6、入門的,缺的,是繼續(xù)學(xué)習(xí)下去的信心。那么信心從何而來?就從解決 NIOS II 開發(fā)中常見的各種問題著手開始吧。如果大家首先就有一份“捉蟲子”手冊放在旁邊,遇到各種問題馬上能從手冊中找到解決方法或解決思路,那么大家的學(xué)習(xí)信心必然會與日俱增。所以,我選擇這一份文檔,從教大家捉蟲子開始。嘮叨了這么多,下面開始切入正題。大家在進(jìn)行 NIOS II 系統(tǒng)開發(fā)時(shí),往往有很多的疑問,第一個(gè)疑問就是大家經(jīng)常提到的,NIOS II CPU 運(yùn)行不穩(wěn)定,NIOS II 開發(fā) bug 太多。由于 FPGA 本身相對于單片機(jī)、ARM 處理器來說,應(yīng)用市場要小的多。加上 NIOS II 僅僅是 FPGA 應(yīng)用和開發(fā)的
7、一個(gè)小的分支,用的就更加的少了。所以,關(guān)于 NIOS II 非常系統(tǒng)且科學(xué)的也是非常的少,導(dǎo)致大部分人在進(jìn)行 NIOS II 的學(xué)習(xí)和開發(fā)的時(shí)候,都會遇到各種各樣的問題,如 elf 文件失敗,CPU 運(yùn)行不起來,程序運(yùn)行不正確,CPU 運(yùn)行一段時(shí)間后停止,調(diào)試正常但是燒寫到 EPCS 后無法運(yùn)行等。那么今天,我就在這里將 NIOS II CPU 的各種問題做一個(gè)總結(jié)分析,希望大家通過本總結(jié)分析,以后在開發(fā) NIOS II 相關(guān)應(yīng)用時(shí)候,能夠手到擒來。elf 文件失敗當(dāng)大家將FPGA 的編程文件SOF 文件到FPGA中后,就可以niosii eds 中編譯好的軟件固件,該固件的尾綴為.elf。那
8、么大家在常遇到下述問題:的時(shí)候,會經(jīng)Launching New_configuration has encountered a problem. Downloading ELF Processfailed。文件到 FPGA 中,或者時(shí)鐘、復(fù)位、器(SRAM、SDRAM、DDR2)引腳分配有誤,當(dāng)使用 SDRAM器作為 NIOS II CPU 的內(nèi)存時(shí),還有可能是 SDRAM的控制器時(shí)鐘和接口時(shí)鐘之間的相位差不合適。解決方法:重新sof;檢查核對引腳分配;查看 SDRAM 參數(shù)配置和時(shí)鐘配置。2)創(chuàng)建NIOS II 軟件工程時(shí)候,選擇的 sopcinfo 文件與對應(yīng)的FPGA 工程不一致。這一點(diǎn)
9、我在每次公開課的時(shí)候都會強(qiáng)調(diào), NIOS II 軟件開發(fā)需要兩個(gè)工程,一個(gè)板級支持包(BSP)和一個(gè)應(yīng)用工程。每次創(chuàng)建 NIOS II BSP 工程的時(shí)候都需要選擇一個(gè) sopcinfo 文件,該文件就是實(shí)際我們在 Qsys 中搭建的希望使用的NIOS II 系統(tǒng)的描述文件。NIOS II 軟件開發(fā)環(huán)境根據(jù)該信息文件創(chuàng)建對應(yīng)的硬件信息頭文件“system.h”,但是,NIOS II 開發(fā)軟件有一個(gè)比較不好的地方就是每次選擇 sopcinfo 文件的時(shí)候,都會上一次選擇 sopcinfo 文件的路徑并直接自動到該路徑,所以大家如果一旦粗心,一點(diǎn)擊瀏覽文件,發(fā)現(xiàn)一個(gè) sopcinfo 文件就直接選
10、擇的話,往往就會選擇到上一次的工程的文件,而不是本次新的工程的文件。這樣我們創(chuàng)建軟件工程時(shí)使用的 sopcinfo 文件就還是上一個(gè)工程的,而我們sof 時(shí)又是的新的工程的,所以就出現(xiàn)了的sof 文件與elf 文件不是基于同一個(gè)工程的問題,導(dǎo)致無法成功。因此為了避免出現(xiàn)這個(gè)問題,新建工程時(shí)請時(shí)刻記住選擇正確的 sopcinfo 文件。該問題一個(gè)更加奇妙的現(xiàn)象就是當(dāng)前一個(gè)工程和這次的新工程兩者之間差別不大的時(shí)候,elf 甚至可以正確,NIOS II 也能運(yùn)行起來,但是就是現(xiàn)象與預(yù)期不一致,這一點(diǎn)可能往往也是讓很多人誤以為 NIOS II 不穩(wěn)定的原因之一。如果你想知道你當(dāng)前的工程的 bsp 文件
11、是否正確,非常簡單,打開 bsp工程下的 settings.bsp 文件,查看第 9 行就可以啦。解決方法:新建工程選擇 sopcinfo 文件時(shí)務(wù)必選擇正確的 sopcinfo 文件。3) NIOS II 的啟動地址錯誤。NIOS II 是一個(gè) CPU,其運(yùn)行過程是受程序指令控制的,而程序有不同的存放位置。例如,程序可以直接存放在 RAM 中,然后 CPU 復(fù)位后直接從硬件定義的 RAM 中程序存放的初始位置開始執(zhí)行。該種方式常見于我們在進(jìn)行軟件編寫調(diào)試的過程中,這個(gè)過程,我們可能需要經(jīng)常進(jìn)行程序的調(diào)試,所以直接使用器(USB Blaster)將程序到 CPU 的 RAM 中運(yùn)行或者 deb
12、ug。另一種情況就是項(xiàng)目發(fā)布的時(shí)候,我們做一個(gè)項(xiàng)目或,當(dāng)產(chǎn)品功能都調(diào)試通過之后,需要將程序燒寫在板卡上,這樣板卡在上電之后,不需要 PC 端程序,就可以自動從非易失性器(FLASH、EEPROM)中加載程序并運(yùn)行。此時(shí)我們需要 CPU 設(shè)置從非易失性器中開始啟動。那么如果我們設(shè)置了 NIOS II 的啟動地址為 FLASH(EPCS),而我們又了定義從 RAM 中啟動的程序,那么程序會被到 RAM 中,CPU 啟動時(shí)候會去 FLASH 中程序,由于我們的程序并沒有到 FLASH 中去,因此 CPU無法到正確的程序,就會無法正常運(yùn)行,然后報(bào)此錯誤。同理,如果我們設(shè)置 CPU 從 RAM 中啟動,
13、而我們又將程序燒寫在了 FLASH 中,那么 CPU上電運(yùn)行后,由于 RAM 中沒有正確的程序,因此也無法運(yùn)行。這一點(diǎn)實(shí)際上是我們上面提到的另一個(gè)現(xiàn)象,即調(diào)試正常但是燒寫到 EPCS 后無法運(yùn)行。好了,饒了這么多口舌,該說大家最關(guān)心的問題了,怎么設(shè)置 CPU 的復(fù)位地址呢?其實(shí)有兩個(gè)地方需要設(shè)置,而 90%以上的人只知道一個(gè)地方,那就是 QSYS 中選擇 CPU 的復(fù)位地址。當(dāng)我們的系統(tǒng)中 FLASH 使用 EPCS剩余容量,那么如果我們要定義 CPU 硬件上從 FLASH 中啟動,就需要定義CPU 的 Reset Vector 為 EPCS , 如果我們要定義CPU 硬件上從 RAM(onc
14、hip_ram/SDRAM/DDR2)中啟動,那么就選擇 Reset Vector 為 ram。當(dāng)然,這沒什么問題,但是我們?nèi)稳豢梢栽谝婚_始就定義 CPU 的 Reset Vector為 EPCS,然后在調(diào)試的時(shí)候,卻從 RAM 中運(yùn)行。為什么可以呢,這就是我說的 90%人不知道的第二個(gè)地方,該設(shè)置在 NIOS II 軟件開發(fā)環(huán)境中。我們選擇一個(gè) bsp 工程,打開 bsp editor 頁面,在第一個(gè)選項(xiàng)卡 main 中,找到下面的 Advanced 選項(xiàng),然后右側(cè)相關(guān)內(nèi)容中有個(gè) hal.linker 選項(xiàng),在該選項(xiàng)中有 5 個(gè)可選項(xiàng),其中第一個(gè)叫做 allow_code_at_reset。
15、這個(gè)選項(xiàng)是什么意思呢,就是允許代碼存放在復(fù)位向量處,好了我們回頭來想一下,上面我們說過,我們可以選擇 CPU 的 Reset Vector 為 EPCS,而這里又使能了allow_code_at_reset 選項(xiàng),所以程序編譯的時(shí)候就會將啟動程序部分編譯在EPCS 所在的地址段。這就是真真切切的將復(fù)位地址設(shè)置在了 EPCS 中。此種模式下我們無法調(diào)試的,如果強(qiáng)行調(diào)試一定會出現(xiàn)上述報(bào)錯。若有人反駁說他的工程此種情況下也能成功,那一定是因?yàn)槟阒耙呀?jīng)將EPCS 中燒寫過一次本程序了,所以你的 CPU 能夠啟動,是因?yàn)樵O(shè)定的啟動地址 EPCS中有能夠支持 CPU 啟動的程序,但能啟動不代表其他功能也
16、能正常運(yùn)行哦。一旦選擇該選項(xiàng),下面的 enable_alt_load 也要一并選上,選上之后 CPU 就能夠正常從 EPCS 中加載了。部分用戶在燒寫 SOF 和 ELF 到 EPCS 中進(jìn)行不成功,原因也與沒有勾選這兩個(gè)選項(xiàng)有關(guān)。時(shí)那么如果我們希望先在 RAM 中調(diào)試怎么辦呢,想必大家已經(jīng)想到了,不使能 allow_code_at_reset 和 enable_alt_load 就可以了。對的,當(dāng)我們希望在RAM 中調(diào)試的時(shí)候,將這兩個(gè)勾選項(xiàng)取消,那么程序編譯就會默認(rèn)將啟動代解決方法:調(diào)試時(shí)不勾選 allow_code_at_reset 和 enable_alt_load。燒寫時(shí)務(wù)必勾選這兩
17、個(gè)選項(xiàng)。4、FPGA 邏輯時(shí)序不滿足,CPU 無法運(yùn)行在指定的頻率下。注意,一般用戶在創(chuàng)建 NIOS II 的系統(tǒng)時(shí)候,系統(tǒng)頻率都在 100M 左右,而這個(gè)頻率下,如果不進(jìn)行時(shí)序約束,Quartus II 軟件默認(rèn)布局布線綜合出來的結(jié)果, 是很難運(yùn)行到這么高的頻率的,往往只能跑到 4080M 左右,因此,創(chuàng)建 NIOS IICPU 系統(tǒng)的時(shí)候,一定記得在 Quartus II 工程中添加SDC 時(shí)序約束文件,約束也并不復(fù)雜,對輸入時(shí)鐘和 PLL 生成時(shí)鐘進(jìn)行下約束就可以了,具體實(shí)例可以參見小梅哥 SOPC 公開課基于 SOPC 的 2.8 寸液晶顯示屏應(yīng)用1 小時(shí) 36始的內(nèi)容,或者小梅哥 2
18、017 培訓(xùn)班0825_01-(SOPC)LCD1602 與 NIOS 系統(tǒng)常見問題分析從第 7 分 30 秒開始的內(nèi)容。也可以參看第 5 章 RT-Thread 操作系統(tǒng)在 NIOS II 上的移植文檔中相關(guān)說明。解決方案:時(shí)序分析+時(shí)序約束5、固件器中已經(jīng)有對應(yīng)的 FPGA 固件和可以運(yùn)行的軟件程序,如果EPCS FLASHCPU 復(fù)位地址設(shè)置在 EPCS 中。之后 CPU 會默認(rèn)EPCS 中的程序,實(shí)際運(yùn)行的是 EPCS 中的運(yùn)行。的之前燒寫過的 elf 程序,導(dǎo)致調(diào)試時(shí)新的elf 無法解決方法:調(diào)試時(shí)不往 EPCS 中程序,如果已經(jīng),可以重新燒寫一個(gè)不含 elf 程序內(nèi)容的 jic 文
19、件到 EPCS 中覆蓋。推薦燒寫正在調(diào)試的工程的 sof 轉(zhuǎn)換得到的純 FPGA 硬件部分的 jic 文件。CPU 運(yùn)行一段時(shí)間后停止很多用戶在調(diào)試或者運(yùn)行 NIOS II CPU 程序的時(shí)候,可能最開始的時(shí)候程序能夠正確的運(yùn)行,但是過一會兒后 CPU 卻停下來了,例如本來做的一個(gè) LED 流水燈,結(jié)果流水了一兩分鐘后卻不再動了。這里是不是又是 NIOS II CPU 運(yùn)行不穩(wěn)定的一個(gè)佐證呢?實(shí)際上,這個(gè)問題的原因,個(gè)人總結(jié)主要有兩點(diǎn):第一點(diǎn),系統(tǒng)使用了 JTAG UART 作為調(diào)試串口打印數(shù)據(jù)。用戶在自己的軟件代碼中寫了有 printf 的代碼,例如每分鐘打印一次“Hello”,同時(shí)讓流水燈
20、閃爍。但是用戶可能在開發(fā)板運(yùn)行的過程中,突然拔掉或者斷開了 USB Blaster或者關(guān)閉了 nios ii 軟件開發(fā)工具。這就導(dǎo)致 JTAG UART 與 PC 間的器,斷開了。由于 JTAGUART 是基于 JTAG 協(xié)議的一個(gè)模擬串口,實(shí)際上我們使用的 jtag uart數(shù)據(jù)的時(shí)候,是先將數(shù)據(jù)寫在 jtag uart 的 fifo 中,然后 pc 端的 nios ii 開發(fā)軟件定時(shí)通過 jtag 協(xié)議fifo 中的數(shù)據(jù),以此模擬 jtag uart 的的。如果我們切斷了 nios ii 開發(fā)軟件與 jtag uart 之間的連接,或者關(guān)閉了 nios ii eds 軟件,使之不再去fif
21、o 中的數(shù)據(jù),那么 jtag uart 的 fifo 中的數(shù)據(jù)就會越積越多。當(dāng)fifo 滿之后,數(shù)據(jù)就再也寫不進(jìn)去了。而 jtag uart 的軟件驅(qū)動中,使用的是阻塞的方式數(shù)據(jù)的,即只有當(dāng)所有的數(shù)據(jù)都寫入fifo 之后,程序才會執(zhí)行下一步。,現(xiàn)在 fifo 中的數(shù)據(jù)一直是滿的,沒有被讀走,那么軟件就只能一直等在這個(gè)地方,等待 fifo 變成非滿。然后,就導(dǎo)致整個(gè) CPU 的運(yùn)行被阻斷在了這個(gè)地方。所以 NIOS 看起來就像是停止運(yùn)行了。有的是拔掉兒,這是因?yàn)?jtag uart 默認(rèn)是 64 字節(jié)的 fifo,剛剛拔掉器之后還能運(yùn)行一會器,fifo 還沒滿,程序運(yùn)行過程中間隔的寫入數(shù)據(jù)到 f
22、ifo 中,過了一會寫 fifo 滿了,然后 CPU 就停下來了。第二點(diǎn),用戶 C 水平不過關(guān)(不在少數(shù)),寫的代碼指針使用不合理,出現(xiàn)了指針越界行為,把正常的數(shù)據(jù)給損毀了,導(dǎo)致 CPU 的運(yùn)行數(shù)據(jù)在運(yùn)行過程中被損毀,然后就無法繼續(xù)運(yùn)行下去了。上述原因主要是用戶通過反復(fù)分析,總是找不出程序問題的時(shí)候考慮的幾點(diǎn)。至于本身程序就沒寫對導(dǎo)致的,那就還是回去深造C 語言吧。合理利用debug,幫助查找程序中存在的問題。程序運(yùn)行不正確有很多用戶在進(jìn)行 NIOS II 開發(fā)的時(shí)候經(jīng)常遇見程序到目標(biāo)板后,運(yùn)行不正確的情況,例如,中斷不響應(yīng),printf 無法打印,期望的功能無法實(shí)現(xiàn),這樣的問題一般分為兩類。
23、a、的 sof 與 elf 不屬于同一個(gè)工程,這個(gè)原因其實(shí)在我們第 1 個(gè)問題的第二種可能原因的時(shí)候已經(jīng)講到,即由于前后兩個(gè) quartus 的工程差別不大,或者說最新編輯的工程是在前一個(gè)工程的基礎(chǔ)上增刪修改部分功能后得到,兩個(gè) QSYS 系統(tǒng)中相同外設(shè)的地址都是一樣,這樣,當(dāng)我們創(chuàng)建 niosii 軟件工程的時(shí)候,選擇了上一個(gè)工程的 sopcinfo 文件,而了新的工程的 sof 文件,就會出現(xiàn),之前的功能是 OK 的,但是新增或者修改的功能總是無法實(shí)現(xiàn)。解決問題的方法就不說了,選擇正確的 sopcinfo 文件就行。b、 NIOS II Cache 的影響經(jīng)常有人反映說自己寫的代碼無法正常
24、工作,然后曬出自己的代碼來。經(jīng)過對用戶代碼的分析可以知道,他們都是參考了網(wǎng)絡(luò)上流傳的比較系統(tǒng)的兩份資料的方式,采用直接地址,即用指針的方式來直接操作外設(shè)里面的寄存器。這樣操作在不帶 Cache 的 NIOS II 版本中能夠很好的奏效,例如 NIOS II 的 e 版本和 s 版本,但是在 f 版本中,為了增強(qiáng)NIOS II 處理器的性能,加入了數(shù)據(jù) cache 和指令cache。如果用戶使用帶cache 的 CPU,卻還是像之前那樣,直接使用指針寄存器地址的方式,就會出現(xiàn)很多時(shí)候,我們希望寫入的數(shù)據(jù)并沒有直接寫入到外設(shè) IP 的寄存器中,而是寫入到了 cache 中,即外設(shè) IP 中并未立即
25、寫入我們希望寫入的值,也就執(zhí)行相應(yīng)的操作了。(關(guān)于 CACHE 是個(gè)啥東西,這里不做專門講解,有的請自行查閱相關(guān)資料)。那么為什么明明是要寫入到外設(shè) IP 寄存器中的數(shù)據(jù),卻寫入到了cache 中呢?這是因?yàn)?,NIOS II e 和 s 版有 31 位的地址線,f 版本有 32位地址線,但是這第 32 位地址線恰恰就是用來選擇 cache 的,當(dāng)?shù)?32位地址線為 0 的時(shí)候,選擇cache,當(dāng)?shù)?32 位地址線為 1 的時(shí)候,就旁路/cache,也就是說,當(dāng)我們還是繼續(xù)使用指針的方式操作外設(shè)寄存器,假設(shè)寄存器的地址為 0x00000001,那么在帶有 cache 的系統(tǒng)中,該地址實(shí)際是到了
26、cache 中,而真正的寄存器地址應(yīng)該是0x10000001,因?yàn)橐雽ぶ返綄?shí)際的寄存器地址,必須cache,即需要地址的最為 1。所以,如果我們還是用指針直接操作 0x00000001這個(gè)地址,當(dāng)然數(shù)據(jù)傳入實(shí)際的寄存器中,所以無法生效。那么怎么解決呢,個(gè)人觀點(diǎn)還是使用 Altera件里,提供了很多讀寫函數(shù):提供的 HAL 庫,如 io.h 這個(gè)文IORD_32DIRECT(BASE, OFFSET) /從某地址讀出 32 位的數(shù)據(jù)IORD_16DIRECT(BASE, OFFSET) /從某地址讀出 16 位的數(shù)據(jù)IORD_8DIRECT(BASE, OFFSET) /從某地址讀出 8 位的
27、數(shù)據(jù)IOWR_32DIRECT(BASE, OFFSET, DATA) /向某地址寫入 32 位的數(shù)據(jù)IOWR_16DIRECT(BASE, OFFSET, DATA) /向某地址寫入 16 位的數(shù)據(jù)IOWR_8DIRECT(BASE, OFFSET, DATA)/向某地址寫入 8 位的數(shù)據(jù)IORD(BASE, REGNUM)/從某地址按照CPU 數(shù)據(jù)位寬(32)這些函數(shù)在使用的時(shí)候,會自動CACHE,另外,針對每個(gè)特定的IP,Altera 也都提供了相應(yīng)的驅(qū)動文件,如 PIO 核,提供的驅(qū)動頭文件名叫“altera_avalon_pio_regs.h”,在這里面定義了對 PIO 外設(shè) IP
28、進(jìn)行讀寫和控制的所有驅(qū)動函數(shù),這些函數(shù)也都是自動了 CACHE 的。而且,使用這個(gè)函數(shù),能夠方便的在各種 NIOS II 版本的 CPU 之間移植,而不用擔(dān)心 CACHE 的問題。所以,個(gè)人強(qiáng)烈推薦使用如果用戶執(zhí)意要堅(jiān)持自己的觀點(diǎn),使用指針直接庫進(jìn)行 IP 核的使用。,那么請?jiān)诙x指針的時(shí)候,將地址最置為 1,例如, PIO_LED 的地址為 0x00000001,那么用戶定義該地址指針時(shí), 請用#define PIO_LED ( 0x00000001 |0x80000000),或者#define PIO_LED (PIO_LED_BASE | 0x80000000),其中 PIO_LED_B
29、ASE 在 system.h 頭文件中定義。這樣再操作就了。有問題c、自定義驅(qū)動與 NIOS II BSP 工程提供的 HAL 驅(qū)動。常見現(xiàn)象為外設(shè)不受控,如看門狗不受用戶程序控制,定時(shí)器不受用戶程序控制,串口數(shù)據(jù)/接收丟失數(shù)據(jù)或亂碼等。這是因?yàn)?,?dāng)我們的 QSYS 系統(tǒng)中添加了這些 IP 外設(shè)后,在 NIOS II EDS 軟件中創(chuàng)建模版工程時(shí)候,如果選擇標(biāo)準(zhǔn)工程,如Hello World 模版工程,則會自動添加所有外設(shè)的驅(qū)動程序,并在 alt_main()函數(shù)中調(diào)用 alt_sys_init()函數(shù)(位于bsp 工程下 alt_sys_init.c 文件中)中將這些外設(shè)初始化,這些初始化就
30、包括了外設(shè)驅(qū)動。因此,當(dāng)我們在用戶程序中再使用直接操作寄存器的方式來控制外設(shè)時(shí)候,則會出現(xiàn)用戶程序和系統(tǒng)已經(jīng)的標(biāo)準(zhǔn)驅(qū)動程序相。例如,對于串口接受,系統(tǒng)驅(qū)動已經(jīng)默認(rèn)將接受到的數(shù)據(jù)接收到了其緩存中(系統(tǒng)驅(qū)動使用中斷方式接收,因此我們看不到直接的過程),可是這些是底層驅(qū)動實(shí)現(xiàn)的,我們并不知道,當(dāng)我們再去讀串口接收狀態(tài)寄存器,就沒法查到對應(yīng)的接收成功狀態(tài)寄存器是否有效,因?yàn)榻邮盏阶x出數(shù)據(jù)IOWR(BASE, REGNUM, DATA) /向某地址按照 CPU 數(shù)據(jù)位寬(32)寫入的數(shù)據(jù)數(shù)據(jù)后該狀態(tài)已經(jīng)被系統(tǒng)驅(qū)動函數(shù)給清零了,所以我們用戶程序就出現(xiàn)了無法接收到串口收到的數(shù)據(jù)的現(xiàn)象。出現(xiàn)數(shù)據(jù)丟失。當(dāng)然,這
31、個(gè)情況會在接收數(shù)據(jù)一段時(shí)間后消失,用戶程序又能讀到狀態(tài)和數(shù)據(jù)了,這是因?yàn)橄到y(tǒng)驅(qū)動函數(shù)將讀到的數(shù)據(jù)先暫存在一個(gè) fifo 數(shù)組中。讀了一段數(shù)據(jù)后,fifo 中的數(shù)據(jù)由于沒有被用戶程序及時(shí)取走使用,因此 fifo 滿了,驅(qū)動程序就再去主動接收串口數(shù)據(jù),也就去及時(shí)清除狀態(tài),所以我們用戶自己狀態(tài)寄存器,就能讀到正確的狀態(tài)了。那么怎么解決這個(gè)問題呢?很簡單,兩種方式,第一種是我們手動修改 alt_sys_init()函數(shù)中的內(nèi)容,將系統(tǒng)驅(qū)動函數(shù)這部分代碼給掉,例如默認(rèn)的,該文件中的內(nèi)容如下所示:我們可以看到,該函數(shù)將 4 個(gè)串口默認(rèn)都初始化了,這個(gè)初始化函數(shù)中就有驅(qū)動的功能。因此如果我們對某個(gè)外設(shè)不希望
32、使用系統(tǒng)提供的驅(qū)動,就可以直接將該外設(shè)的初始化函數(shù)注釋掉。例如,我們不希望UART_RS485A 和 UART_RS485B 使用系統(tǒng)提供的默認(rèn)驅(qū)動,就可以將該函數(shù)中ALTERA_AVALON_UART_INIT ( UART_RS485A, uart_rs485a);和ALTERA_AVALON_UART_INIT ( UART_RS485B, uart_rs485b);兩個(gè)調(diào)用注釋掉。修改完成后的該函數(shù)如下所示:void alt_sys_init( void )ALTERA_AVALON_UART_INIT ( DEBUG_UART, debug_uart); ALTERA_AVALON_
33、UART_INIT ( UART_RS232, uart_rs232);/ALTERA_AVALON_UART_INIT ( UART_RS485A, uart_rs485a);void alt_sys_init( void )ALTERA_AVALON_UART_INIT ( DEBUG_UART, debug_uart); ALTERA_AVALON_UART_INIT ( UART_RS232, uart_rs232); ALTERA_AVALON_UART_INIT ( UART_RS485A, uart_rs485a); ALTERA_AVALON_UART_INIT ( UART_
34、RS485B, uart_rs485b);這樣,這兩個(gè)外設(shè)的驅(qū)動由于沒有初始化,因此工作,這個(gè)時(shí)候我們就可以使用讀寫寄存器的方式操作該外設(shè)了,如一個(gè)字節(jié)的數(shù)據(jù)可以寫為:此種方式在用戶執(zhí)行 generate bsp 操作后會失效,因?yàn)槲覀兏牡舻拇a會被重新覆蓋為默認(rèn)內(nèi)容。該種方法用個(gè)成語說叫做揚(yáng)湯止沸,無法根除問題,因此不推薦大家使用。第二種方式,屬于治根,那就是在 BSP 工程中取消生成對應(yīng)設(shè)備的驅(qū)動。由于alt_sys_init.c 文件中的內(nèi)容都是根據(jù) bsp 設(shè)置中的相關(guān)選項(xiàng)對應(yīng)生成的,因此,要想每次重新 generate bsp 后都不包含不希望初始化的設(shè)備代碼,可以在 bsp 中設(shè)置
35、不使能生成該設(shè)備的驅(qū)動,方法為,在 BSP Editor 中,切換到 Drivers 選項(xiàng)卡,針對不希望生成驅(qū)動的設(shè)備,在其后面的 Enable 欄中,去掉勾項(xiàng)即可。當(dāng)設(shè)置完成后,alt_sys_init.c 文件會被自動更新,如果我們當(dāng)前本來就是在alt_sys_init.c 文件打開的界面然后去設(shè)置 bsp 的,那么當(dāng)你設(shè)置完成,回到這個(gè)文件,系統(tǒng)會提示該文件已經(jīng)被更改,然后我們選擇 yes,以更新文件內(nèi)容,就可以發(fā)現(xiàn),之前的 RS485A 和 RS485B 兩個(gè)設(shè)備的驅(qū)動初始化代碼已經(jīng)不存在了。/等待寄存器可用while (!(ALTERA_AVALON_UART_STATUS_TRDY
36、_MSK& IORD_ALTERA_AVALON_UART_STATUS(UART_RS485A_BASE);/寫入待的數(shù)據(jù)IOWR_ALTERA_AVALON_UART_TXDATA(UART_RS485A_BASE, 0x88);/ALTERA_AVALON_UART_INIT ( UART_RS485B, uart_rs485b);更新完成后,alt_sys_init 函數(shù)中原本對 RS485A 和 RS485B 兩個(gè)端口的初始化代碼已經(jīng)不在了:更新前更新后解決 NIOS II 工程移動在磁盤上位置后 project 無法編譯問題說明:本文檔于 2017 年 3 月 4 日由小梅哥更新部
37、分內(nèi)容,主要是增加了講解以 Quartus II13.0 為代表的經(jīng)典版本和以 15.1 為代表的更新版本之間,解決問題的一些小的差異。如果用戶只是想快速解決問題,不想分析產(chǎn)生問題的原因并和我一起探尋解決問題的思路,可以直接跳到 6.4 節(jié)解決方案步驟總結(jié)。針對目錄改變時(shí),Nios II project 無法編譯的問題,網(wǎng)上有多種解決方法,不過都操作相對繁瑣,這里,小梅哥進(jìn)過探索,針對 11.0 及以后的版本,找到了一種簡單可靠的解決辦法,整個(gè)過程只需要簡單的四步操作即可搞定,分別為:切換工作空間(workspace),移除舊版工程,修改 bsp 文件,重新導(dǎo)入(import)工程。6.1 更
38、改 NIOS II Project 目錄原因網(wǎng)上木易前輩的話,“我們常會有各種理由會改變原來 project 的目錄名稱或目錄位置”例如:1.為了管理方便,可能將原來在 d:project的所有 project 移到 e:project下2.同事將 project 整個(gè)目錄壓縮給我,因?yàn)槲也⒉恢涝?project 放在同事計(jì)算機(jī)什么工作目錄下,所以我將壓縮文件解壓縮到的工作目錄下3.從網(wǎng)絡(luò)上整包范例程序的壓縮文件后,因?yàn)槲也⒉恢涝痉独绦蛩娣诺哪夸?,所以我將壓縮文件解壓縮到的工作目錄下4.從書上光盤范例程序到硬盤,因?yàn)槲也⒉恢涝痉独绦蛩娣诺哪夸?,所以我將范例程序到的工作目錄?
39、.新的 project 與舊的 project 類似,想從舊的 project 去做修改即可,開了一個(gè)新的目錄,將舊的 project 所有到新的目錄下6.為了管理方便,想改變原本 project 的目錄名稱6.2 更改 NIOS II Project 目錄的問題Quartus II 的工程在更改了路徑后是存在問題的,我們可以直接編譯更改,而在 NIOS II EDS 中的工程卻沒這么簡單,Nios II EDS 是用Eclipse 去改的,用的是 Eclipse 的 workspace 概念,很類似 Visual Studio 的*.sln 概念,但又全一樣。Eclipse 允許你在一個(gè) w
40、orkspace 下,去管理多個(gè) project,workspace 記住的 是 project 的絕對路徑,所以當(dāng)你 Nios II project 目錄名稱改變,或者目錄位置改變,該 workspace 自然就找不到了?;蛘?,如果你的新工程是從老工程過來的,那么一切表面看起來出現(xiàn)任何問題,所有的軟件工程仍然可以“正常打開”,我們依舊可以編譯,重新生產(chǎn) bsp 文件,。然而,這種方式存在更大的風(fēng)險(xiǎn),因?yàn)檫@樣,你修改的還是原來路徑下的文件,因此,這樣就有極大的風(fēng)險(xiǎn)使得你在希望更改新的軟件工程的時(shí)候,把原本的工程給改了。很多朋友表示 NIOS II 開發(fā)中存在各種各樣的問題,例如無法elf 文件
41、,后軟件不能執(zhí)行或者執(zhí)行報(bào)錯。經(jīng)過這段時(shí)間的輔導(dǎo)答疑,發(fā)現(xiàn)他們出問題大部分也都是這個(gè)原因。6.3 解決方案詳解因此,為了讓各位 NIOS II 用戶快速上手,避免遇到這個(gè)問題而耽誤太多的時(shí)間,小梅哥這里介紹一種最簡單的解決辦法。整個(gè)過程只需要簡單的四步操作即可搞定,分別為:切換工作空間(workplace),移除舊版工程,修改 bsp 文件,重新導(dǎo)入(import)工程。這里,我將我電腦中 E:easy_sopcNiosOnlyExp03_pio_int 這個(gè)文件夾拷貝到桌面(C:UsersAdministratorDesktop03_pio_int)上,以符合更改路徑這一前提,然后,打開其中
42、的 Quartus II 工程“CoreCourse_GHRD.qpf”,工程打開后,選擇tools-Nios II Software Build Tools For Eclipse。然后在彈出的工作空間選擇框中,可以看到,工作空間還是上次的工作空間路徑,這里,工作空間切換到 C:UsersAdministratorDesktop03_pio_int,如下圖所示:然后選擇 OK 就會打開工程,打開后我們可以看到,軟件自動加載了一個(gè)軟件工程和一個(gè) bsp 工程,該工程名字與前的工程(E:easy_sopcNiosOnlyExp03_pio_intsoftware)中的軟件工程名字一致(注意,如果
43、用戶磁盤上舊位置不存在該工程,例如該工程是從其他電腦拷貝過來的,工程將顯示,無法打開,這個(gè)雖然會影響我們后續(xù)一步一步分析問題原因,但是不影響我們解決問題,如果各位自己電腦上無法打開,可以找一個(gè)原本存在的工程測試,或者跳過分析問題步驟,直接看解決方案總結(jié))。這時(shí)候,我們鼠標(biāo)右鍵選中 key_int_bsp,選擇 NIOS II - BSP Editor在彈出的 BSP 設(shè)置界面中我們可以看到,BSP target direction 還是E:easy_sopcNiosOnlyExp03_pio_intsoftwarekey_int_bsp,即前的路徑。因此可知,如果此時(shí)我們在當(dāng)前工程的 Qsys
44、 中更改了 NIOS II 系統(tǒng)的架構(gòu)或者增刪了東西,重新生產(chǎn) Qsys 文件,然后我們回到Eclipse 中選擇 generate BSP時(shí),軟件會根據(jù)新的 Qsys 信息重新生產(chǎn) bsp 文件,而這個(gè) bsp 文件還是保存在之前的 E:easy_sopcNiosOnlyExp03_pio_intsoftwarekey_int_bsp 中,因此就導(dǎo)致原本的之前的工程內(nèi)容被更改,即本來我們是想把整個(gè)工程到另一個(gè)地方進(jìn)行單獨(dú)修改的,然而卻實(shí)質(zhì)上把原路徑下的工程文件給更改了,到最后導(dǎo)致原版和后的工程都被改變。為了解決這個(gè)問題,接下來新打開的工作空間中已經(jīng)存在的兩個(gè)工程移除。選中已經(jīng)存在的工程和工程
45、對應(yīng)的 bsp,右鍵選擇 Delete:在彈出的框中,點(diǎn)擊 OK。不過大家一定要注意的是,千萬不要勾選上面的那個(gè)“Delete project contents on disk(cannot be undone)”,因?yàn)檫@個(gè)是刪除軟件工程的源文件,如果選擇了這個(gè),那么在刪除時(shí)就會將原本沒有之前的路徑下的軟件源工程給刪除掉,那么原版工程就被徹底破壞掉了,我們所需要做的,只是把這兩個(gè)工程從工作空間中移除,而不是將原工程刪掉,這點(diǎn)大家要切記。移除了工程之后,我們回到新的工程下的 key_int_bsp 文件夾下(C:UsersAdministratorDesktop03_pio_intsoftwar
46、ekey_int_bsp),找到settings.bsp 文件,使用任意一個(gè)文本編輯器打開:注意,不同版本的 Quartus II 軟件該文件稍有差別。對于 Quartus II13.0 版本,BSP 文件中兩個(gè)位置了工程絕對路徑,而對于 15.1 或以上,則只有一個(gè)位置絕對路徑,另一個(gè)位置已經(jīng)改進(jìn)為相對路徑了(相對路徑是相對當(dāng)前工程,因此無需修改)(其他版本我暫時(shí)未檢驗(yàn))。首先我們看一個(gè) 13.0 版本的工程該文件的 7 和 9 兩行都是使用的絕對位置的,因此在 Quartus II13.0 版本的軟件中需要修改這兩個(gè)位置都為新的路徑,修改后如下圖所示:而對于 15.1 版本的工程,打開文件
47、后我們可以看到,該文件下的第 7 行左右,BspGeneratedLocation 指定的還是對路徑了:前的路徑,第 9 行已經(jīng)改進(jìn)為采用相于是,這里只需將第 7 行這個(gè)地方更改為我們后的新路徑C:UsersAdministratorDesktop03_pio_intsoftwarekey_int_bsp,第 9 行不變即可更改后的文件內(nèi)容如下所示:然后保存文件,回到 NIOS II Eclipse 中,選擇 File - Import在彈出的窗口中,選擇 General 下的 Existing Projects into Workspace:在彈出的窗口中,選擇 Select root di
48、rectiory,點(diǎn)擊 Browse,Workspace 目錄(這里也就是 Quartus II 工程目錄)到C:UsersAdministratorDesktop03_pio_int可以看到,軟件會自動找到該目錄下存在的軟件工程,然后點(diǎn)擊 finish 即可將工程導(dǎo)入進(jìn)來。導(dǎo)入進(jìn)來后,再次進(jìn)入 BSP Editor,發(fā)現(xiàn) BSP target direction就已經(jīng)是現(xiàn)在的新路徑了。為了區(qū)這樣更改后是否還會對未前的工程造成影響,這里我將未前的工程剪切到了另一個(gè)地方放著,這樣如果在重新編譯的時(shí)候還是要對未前的工程進(jìn)行操作,那么因?yàn)樵こ桃呀?jīng)不在了,就會告或則報(bào)錯。而事實(shí)上,當(dāng)我再次編譯時(shí)并沒
49、有報(bào)任何警告和錯誤。修改 C 代碼后,重新編譯生產(chǎn) elf 文件,到芯航線 FPGA 開發(fā)板上,也能夠正常的運(yùn)行。打開原版工程(已經(jīng)將原版工程拷貝回原路徑了),還是之前的內(nèi)容,編譯也沒問題。因此該問題得以完美解決。6.4 解決方案步驟總結(jié)好了,說了這么多,各種推理和驗(yàn)證,導(dǎo)致真正有用的操作步驟被弱化了,不容易區(qū)分,這里,我再總結(jié)下:6.4.1切換工作空間(workspace)切換工作空間前:切換工作空間后:6.4.2移除舊版工程注意: 千萬不要勾選上面的那個(gè)“Delete project contents on disk (cannot beundone)”,6.4.3修改 bsp 文件在新的
50、工程下的 key_int_bsp 文件夾下(C:UsersAdministratorDesktop03_pio_intsoftwarekey_int_bsp),找到settings.bsp 文件,使用任意一個(gè)文本編輯器打開:第 7 行左右,將 BspGeneratedLocation 指定路徑由原版路徑改為更改后的新路徑:13.0 版本更改前:更改后15.1 及以上版本更改前更改后然后保存文件。6.4.4重新導(dǎo)入(import)工程N(yùn)IOS II Eclipse 中,選擇 File - Import在彈出的窗口中,選擇 General 下的 Existing Projects into Wor
51、kspace:在彈出的窗口中,選擇 Select root directiory,點(diǎn)擊 Browse,Workspace 目錄(這里也就是 Quartus II 工程目錄)到C:UsersAdministratorDesktop03_pio_int點(diǎn)擊 finish 即可將工程導(dǎo)入進(jìn)來。接下來就可以放心的更改 Qsys 系統(tǒng)和軟件工程啦。小梅哥芯航線電子2016 年 1 月 21 日四初創(chuàng)2017 年 3 月 4 日六日更新sof 與 NIOS II 的 elf 固件合并 jic 得到文件7.1 為什么需要將 Sof 與 elf 合并得到 jic 文件我們在學(xué)習(xí)和調(diào)試 NIOS II 工程的時(shí)
52、候,一般都是先使用 Quartus II 軟件中提供的 Quartus Programmer 來燒寫 FPGA 配置文件(SOF),然后 NIOS II EDS 中提供的 Flash Programmer 工具來進(jìn)行燒寫 NIOS II 的。這對于開發(fā)者來說,并沒有什么不便,反而因?yàn)檫@種方式的靈活,為開發(fā)帶了了很大的便利。然而,當(dāng)我們的已經(jīng)設(shè)計(jì)完成并量產(chǎn)的時(shí)候,就需要將固件燒寫到中。生產(chǎn)線上進(jìn)行燒錄時(shí),總希望能夠用最簡單的方式實(shí)現(xiàn)。試想,如果生產(chǎn)線上在進(jìn)行燒寫時(shí),還需要幾個(gè)工具換來換去,等待很久,效率自然就下去了。因此這種 QuartusProgrammer+Flash Programmer
53、的方式并不適合生產(chǎn)。小梅哥在最近的工作中也遇到了這樣的問題。我們新設(shè)計(jì)的一批開發(fā)板,在工廠生產(chǎn)完畢后,都要進(jìn)行出廠測試。然而 SMT 廠家卻并不熟悉我們的這種Quartus Programmer+Flash Programmer 燒寫方式。再說了,要使用這種方式還得安裝 Quartus Programmer 和 NIOS II EDS 軟件。廠家表示使用這種方式對他們來說有一定難度,而且效率也不高。所以我就根據(jù) Altera上的一個(gè)帖子,進(jìn)行了轉(zhuǎn)換,將 SOF 文件和 NIOS II 的 elf 固件合并并生成了一個(gè) jic 文件,這樣,廠家就只需要使用 Quartus Programmer
54、來燒寫這個(gè) jic 文件就能實(shí)現(xiàn)同時(shí)燒寫FPGA 配置文件和 NIOS II 固件的功能了,簡化步驟,節(jié)省時(shí)間。從 SOF 文件和 ELF 文件得到 JIC 文件的原帖地址如下:/support/support-resources/knowledge-base/solutions/rd10132010_126.html7.2 本章示例介紹因?yàn)橛薪?jīng)驗(yàn)不足的朋友反映在看了這個(gè)后還是不知道怎么操作,總是不成功,因此這里小梅哥使用我們芯航線 FPGA 的開發(fā)板,一步一步演示這個(gè)實(shí)現(xiàn)過程,將整個(gè)過程具體化。先說明下我這個(gè)設(shè)計(jì)工程的結(jié)構(gòu):EPCS16:用來FPGA 配置文件和 NIOS 的固件,本例中最終轉(zhuǎn)換得到的 JIC文件也是燒寫到該器件中。512K 字節(jié)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年春季小學(xué)《弟子規(guī)》教案發(fā)布
- 凍干食品合作協(xié)議合同范本
- 統(tǒng)編版小學(xué)語文五年級下冊第二單元試卷
- 2024簡易協(xié)議管理軟件解決方案
- 5《秋天的懷念》同步練習(xí)含答案統(tǒng)編版語文七年級上冊
- 戀愛賣身合同范本
- Visio2024教程:自動化辦公解決方案
- 崇文區(qū)?;房爝f合同范本
- 城區(qū)改造渣土清理與運(yùn)輸服務(wù)協(xié)議樣本
- 與他人合伙開店的合同范本
- 醫(yī)院健康教育培訓(xùn)課件
- GH/T 1419-2023野生食用菌保育促繁技術(shù)規(guī)程灰肉紅菇
- 鼻咽癌的放射治療課件
- 明孝端皇后九龍九鳳冠
- 注塑車間規(guī)劃方案
- 營養(yǎng)不良五階梯治療
- 標(biāo)本運(yùn)送培訓(xùn)課件
- 護(hù)士與醫(yī)生的合作與溝通
- GB 42295-2022電動自行車電氣安全要求
- 產(chǎn)品系統(tǒng)設(shè)計(jì)開發(fā) 課件 第4、5章 產(chǎn)品系統(tǒng)設(shè)計(jì)類型、產(chǎn)品系統(tǒng)設(shè)計(jì)開發(fā)綜合案例
- 1編譯原理及實(shí)現(xiàn)課后題及答案
評論
0/150
提交評論