




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、目錄1系統(tǒng)定義與需求分析31.1系統(tǒng)定義31.1.1任務(wù)功能描述31.1.2 任務(wù)的優(yōu)先級分配41.1.3 任務(wù)間同步與通信的規(guī)則41.2 系統(tǒng)配置42詳細(xì)設(shè)計62.1 系統(tǒng)移植62.1.1移植os_cpu.h62.1.2 移植os_cpu_c.c72.2 最小系統(tǒng)的運行調(diào)試102.2.1 保證編譯正確,系統(tǒng)啟動正確112.2.2調(diào)試os_enter_critical()112.2.3 調(diào)試osstarthighrdy()122.2.4 調(diào)試osctxsw()122.2.5 調(diào)節(jié)時鐘節(jié)拍132.2.6 調(diào)試osintctxsw()和ostickisr()143 驅(qū)動程序的設(shè)計與調(diào)試153.1
2、基于c/os-ii的中斷設(shè)計153.2 基于c/os-ii的設(shè)備驅(qū)動程序設(shè)計153.3 基于c/os-ii的設(shè)備驅(qū)動程序測試164 系統(tǒng)集成與功能測試174.1 初始化任務(wù)174.2 鍵盤處理任務(wù)184.3 觸摸屏處理任務(wù)234.4 系統(tǒng)集成測試355參考文獻381系統(tǒng)定義與需求分析1.1系統(tǒng)定義電子詞典是一個典型的由外部輸入驅(qū)動的開環(huán)系統(tǒng),由鍵盤或觸摸屏輸入信息,處理器根據(jù)輸入的信息在lcd顯示屏上顯示相應(yīng)的內(nèi)容,顯示完成之后系統(tǒng)進入空閑狀態(tài)等待下一次輸入。根據(jù)這一處理過程,講電子詞典應(yīng)用分為3個主任務(wù)主執(zhí)行任務(wù),鍵盤任務(wù),觸摸屏任務(wù)。系統(tǒng)的總體設(shè)計如圖1-1所示。main()函數(shù)初始化任務(wù)
3、鍵盤任務(wù)主執(zhí)行任務(wù)觸摸屏任務(wù)光標(biāo)任務(wù)鍵盤isr觸摸屏isr時鐘節(jié)拍 圖1-1 c/os-ii系統(tǒng)總是從main()函數(shù)開始,通常在main()函數(shù)中指創(chuàng)建一個用戶任務(wù),即初始化任務(wù),這樣設(shè)計有利于系統(tǒng)管理,而且結(jié)構(gòu)也會更清晰。在初始化任務(wù)中啟動時鐘節(jié)拍,創(chuàng)建各個任務(wù)以及要用到的信號量或消息。1.1.1任務(wù)功能描述在電子詞典設(shè)計中,鍵盤任務(wù)和觸摸屏任務(wù)負(fù)責(zé)采集輸入信號,并將其轉(zhuǎn)換為鍵值告知主處理任務(wù)。主處理任務(wù)負(fù)責(zé)根據(jù)讀到的鍵值啟動相應(yīng)功能。而光標(biāo)任務(wù)則是用來展現(xiàn)時鐘節(jié)拍,讓目標(biāo)板上的led燈以指定的時間間隔進行閃爍。1.1.2 任務(wù)的優(yōu)先級分配系統(tǒng)中的優(yōu)先級分配按照最經(jīng)常發(fā)生的優(yōu)先級最高這一原
4、則進行,具體分配如下:優(yōu)先級03:分配優(yōu)先級時將最高的4個優(yōu)先級留給系統(tǒng)用戶;優(yōu)先級5:主處理任務(wù)優(yōu)先級最高為5級;優(yōu)先級6:鍵盤的使用概率大于觸摸屏,其優(yōu)先級定為6級;優(yōu)先級7:觸摸屏的優(yōu)先級為7級;優(yōu)先級8:光標(biāo)每隔一個固定的時間閃爍一次,這個時間可以由用戶自定義,優(yōu)先級為8級;最低優(yōu)先級-1:系統(tǒng)統(tǒng)計任務(wù)(可選);最低優(yōu)先級:系統(tǒng)空閑任務(wù)。1.1.3 任務(wù)間同步與通信的規(guī)則需要傳遞消息的任務(wù)是鍵盤與主執(zhí)行任務(wù)。觸摸屏與主執(zhí)行任務(wù)之間傳遞的都是按鍵值,且鍵值不用區(qū)分來源,所以使用一個消息郵箱即可。由于任務(wù)間不存在共享互斥資源的問題,所以不需要進行任務(wù)間的同步。鍵盤與觸摸屏都是由外界時間觸發(fā)
5、的,可以使用中斷機制設(shè)計驅(qū)動程序。在驅(qū)動程序的設(shè)計中,遵循中斷中處理的時間盡量短,講更多的事情交給任務(wù)區(qū)完成這一原則。1.2 系統(tǒng)配置c/os-ii并不提供列斯linux那樣的命令行形式的配置方法,而是通過對配置的內(nèi)容進行條件編譯來實現(xiàn)的。這是由于c/os-ii提供開放的源代碼,用戶可以直接使用#define constants語句來更改內(nèi)核的很多參數(shù)。系統(tǒng)中提供了以下配置項:事件標(biāo)志:包括使能或禁止事件標(biāo)志及其相關(guān)功能,通常以os_flag_為前綴;消息郵箱:包括使能或禁止消息郵箱及其相關(guān)功能,通常以os_mbox_為前綴;內(nèi)存管理:包括使能或禁止內(nèi)存管理及其相關(guān)功能,目前版本中只有兩個可配
6、置項os_mem_en和os_mem_query_en;互斥型信號量:包括使能或禁止互斥型信號量及其相關(guān)功能,通常以os_mutex_為前綴;消息隊列:包括使能或禁止消息隊列及其相關(guān)功能,通常以os_q_為前綴;信號量:包括使能或禁止信號量及其相關(guān)功能,通常以os_sem_為前綴;任務(wù)管理:系統(tǒng)提供兩個任務(wù)創(chuàng)建函數(shù),在配置文件中至少要對其中一個進行使能,另外還包括一些對任務(wù)其他相關(guān)屬性的配置,通常以os_task_為前綴;時鐘管理:c/os-ii中用戶可以使用操作系統(tǒng)的時鐘作為演示的基準(zhǔn),這里包括使能或禁止使用系統(tǒng)時鐘及其相關(guān)功能,通常以os_time_為前綴;雜項:包括配置任務(wù),事件,消息隊
7、列的最大個數(shù),任務(wù)堆棧的容量等。c/os-ii內(nèi)核默認(rèn)的是將系統(tǒng)配置為最大系統(tǒng),即使能所有功能,并且將認(rèn)為尿素時間按等設(shè)置為最大。在電子詞典的應(yīng)用中,只有13個任務(wù)(5個用戶任務(wù),8個系統(tǒng)預(yù)留任務(wù))、兩個事件標(biāo)志、一個消息郵箱,所以需要對默認(rèn)系統(tǒng)進行重新配置。需要更改的主要參數(shù)如下:os_max_events:最大可申請的事件控制塊數(shù)。系統(tǒng)中每個消息和信號量都需要一個事件控制塊。電子詞典中只用到一個消息郵箱,該值大于1即可。為了便于本系統(tǒng)擴展,將其設(shè)為5。os_max_flags:最大可申請的事件標(biāo)志數(shù)。當(dāng)前使用了倆各個事件標(biāo)志,該值大于2即可。為了便于本系統(tǒng)擴展將其設(shè)為5。os_max_ta
8、sks:最大可申請的用戶任務(wù)書。電子詞典中共定義了5個用戶任務(wù),該值大于5即可。為了便于本系統(tǒng)擴展將其設(shè)為10。os_lowest_prio:系統(tǒng)可分配的最低優(yōu)先級。系統(tǒng)根據(jù)該參數(shù)初始化任務(wù)控制塊,所以這個參數(shù)會影響系統(tǒng)對ram的占用 。電子詞典將此參數(shù)定義為15,其中5個用戶任務(wù)、8個系統(tǒng)任務(wù)、2個余量任務(wù)。各個功能的使能/禁止參數(shù)通常以_en為后綴,1為使能,0為禁止。在電子詞典中要使能消息郵箱(os_mbox_en)和信號量(os_sem_en),將其對應(yīng)的參數(shù)設(shè)為1,其余使能參數(shù)設(shè)為0,其他參數(shù)均使用默認(rèn)值即可。2詳細(xì)設(shè)計2.1 系統(tǒng)移植在移植c/os-ii之前,要確保目標(biāo)系統(tǒng)(主要是
9、處理器及其編譯環(huán)境)滿足如下要求:(1) 目標(biāo)系統(tǒng)所使用的編譯環(huán)境要包括標(biāo)準(zhǔn)的c交叉編譯器。(2) 目標(biāo)系統(tǒng)所使用的c編譯器支持在c程序中對中斷進行操作。(3) 處理器必須可以產(chǎn)生定時器中斷。(4) 處理器必須可容納一定數(shù)據(jù)存儲硬件堆棧。(5) 處理器中的寄存器與內(nèi)存之間可以相互讀/寫。2.1.1移植os_cpu.h在os_cpu.h里主要包括與處理器有關(guān)的數(shù)據(jù)類型、常量以及宏的定義。定義常量so_stk_growth。這個常量表示了棧的增長方向。1為向上遞減,棧底高地址入棧時指針減,出棧時指針加;0為向下遞增,棧底低地入棧時指針加,出棧時減。定義宏os_enter_critical()和os
10、_exit_critical()。這兩個宏是用來打開和關(guān)閉中斷的。當(dāng)c/os-ii需要處理不能被中斷打斷的段時,就要用到這兩個宏對其進行保護。由于不同的處理器對中斷的操作不盡相同,所以在這里對這兩個操作進行定義。關(guān)中斷宏代碼如下:#define os_enter_critical() _ _asmbl armdisableint 開中斷宏代碼如下:#define os_exit_critical() _ _asmbl armenableint 具體功能在os_cpu_a.s實現(xiàn),代碼如下:armdisableintmrsr0,cpsrstmfd sp!,r0 ;保存當(dāng)前處理器狀態(tài)orrr0,r
11、0,#0x80msrcpsr_c,r0 ;禁止中斷movpc,lrarmenableintldmfdsp!,r0 ;從棧中彈出處理器的狀態(tài)值msrcpsr_c,r0 ;恢復(fù)原始的處理器狀態(tài)movpc,lr2.1.2 移植os_cpu_c.cos_cpu_c.c包括10個簡單的c函數(shù)。與移植相關(guān)的只有ostaskstkinit()函數(shù),該函數(shù)負(fù)責(zé)對任務(wù)棧進行初始化。另外9個都是對各種任務(wù)進行擴展時用的,雖然必須定義,但可以不用包含任何代碼。這10個函數(shù)分別是:ostaskstkinit()、ostaskcreatehook()、ostaskdelhook()、ostaskswhook()、ost
12、askidlehook()、ostaskstathook()、ostimetickhook()、osinithookbegin()、osinithookend()和ostcbinithook()。ostaskstkinit()函數(shù)在創(chuàng)建任務(wù)時被ostaskcreate()或ostaskcreateexit()調(diào)用,以初始化任務(wù)棧結(jié)構(gòu),將所有的寄存器像剛發(fā)生中斷一樣保存在棧里。雖然arm對棧的方向并沒有特殊要求,但是由于ads編譯器僅支持滿減棧fd(full descending),即高地址為棧底,入棧時指針減1,棧指針指向最后一個入棧的數(shù)據(jù)元素,所以需要在os_cpu.h中將任務(wù)棧定義為減棧:
13、#define os_stk_growth 1/*內(nèi)存中棧的增長方向為從高到低*/其實際結(jié)構(gòu)如圖2-1所示。pdata是在人物創(chuàng)建時傳遞給任務(wù)的一個參數(shù)。代碼如下:os_stk*ostaskstkinit(viod(*task)(void*pd),void*pdata,os_stk*ptos,int16u opt)unsigned int * stk;opt=opt; stk=(unsigned int *)ptos; /*當(dāng)前棧指針*/*對新任務(wù)建立上下文環(huán)境*/*_ _stk=(unsigned int) task; /* pc*/*_ _stk=(unsigned int) task;
14、/* 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*/*_ _stk=(svc32mode|0x0;/* 禁用cpsr中的irq,fi
15、q*/*_ _stk=(svc32mode|0x0);/* 禁用spsr中的irq,fiq*/return(void*)stk;c/os-iic/os-ii中有4個與處理器相關(guān)的函數(shù)要用匯編語言實現(xiàn),這4個函數(shù)分別是:oostarthighrdy( )、osctxsw( )、osintctxsw( )和ostickisr( )。oostarthighrdy( )oostarthighrdy( )僅在osstart()函數(shù)中被調(diào)用。具體實現(xiàn)代碼如下: osstarthighrdybl ostaskswhookldrr4,=osrunningmovr5,#1strbr5,r4ldrr4,=osrc
16、bhighrdyldrr4,r4ldrsp,r4ldmfdsp!,r4msrspsr_c,r4ldmfdsp!,r4msr cpsr_c,r4ldmedsp!,r0-r12,lr,pc這段代碼中ostaskswhook()在文件os_cpu_c.c中定義,通過它用戶可以擴展任務(wù)切換代碼的功能。osctxsw( )osctxsw( )用來實現(xiàn)任務(wù)級的任務(wù)切換。具體實現(xiàn)代碼如下: osctxswstmfdsp!,lrstmfdsp!,r0-r12,lrmrsr4,cpsrstmfdsp!,r4mrsr4,spsrstmfdsp!,r4_osctxswbl ostaskswhookldrr4,=os
17、priocurldrr5,=ospriohighrdyldrbr6,r5strbr6,r4ldrr4,=ostcbcurldrr5,r4strsp,r5ldrr6,= ospriohighrdyldrr6,r6ldrsp,r6strr6,r4ldmfdsp!,r4msrspsr_cxsf,r4ldmfdsp!,r4msrcpsr_cxsf,r4ldmfdsp!,r0-r12,lr,pcosintctxsw( )osintctxsw( )由osintexit( )調(diào)用,在isr中實現(xiàn)任務(wù)切換功能。通常使用如下形式的代碼實現(xiàn)中斷級的任務(wù)切換: osintctxswldrr0,=osintctxsw
18、flagmovr1,#1strr1,r0movpc,lr以上這段代碼值設(shè)置了一個用以表示是否需要進行任務(wù)切換的標(biāo)志osintctxswflag,在中斷后的第一個時鐘節(jié)拍內(nèi)對此標(biāo)志進行判斷,根據(jù)判斷結(jié)果決定是都需要進行中斷級任務(wù)切換。ostixkisr( )ostixkisr( )時鐘節(jié)拍中斷的isr。在之前提到過的c/os-ii要求用戶提供一個稱為時鐘節(jié)拍的定時中斷,以實現(xiàn)延時與超時控制等功能。這個中斷頻率一般是10100hz。具體實現(xiàn)代碼如下:nointequ0xc0i_ispcequ0x1e00024timer0equ0x1ostickisrstmfdsp!,r0-r3,r12,lrblo
19、sintenterldrr0,=i_ispcmovr2,#timer0ldrr1,r0orrr1,r1,r2,lsl #13strr1,r0blostimetickblosintexitldrr0,=osintctxswflagldrr1,r0cmpr1,#1beq_intctxswidmfdsp!,r0-r3,r12,lrsubspc,lr,#4/*-以下代碼用于任務(wù)切換-*/_intctxswldrr0,=osintctxswflagmovr1,#0str r1,r0idmfdsp!,r0-r3,r12,lrstmfdsp!,r0-r3movr1,spaddspsubr2,lr,#4mrs
20、r3,spsrorrr0,r3,#nointmsrspsr_c,r0idrr0,=.+8movspc,r0stmfdsp!,r2stmfdsp!,r4-r12,lrmovr4,r1movr5,r3idmfdr4!,r0-r3stmfdsp!,r0-r3stmfdsp!,r5mrsr4,spsrstmfdsp!,r4b_osctxsw2.2 最小系統(tǒng)的運行調(diào)試最小系統(tǒng)主要是指如處理器、存儲器這些最基本的元素所組成的可運行的最小系統(tǒng),在增加了操作系統(tǒng)之后,可以認(rèn)為最小系統(tǒng)等于硬件最小能運行系統(tǒng)加上可運行的操作系統(tǒng)內(nèi)核。只有當(dāng)最小系統(tǒng)運行起來以后,才能進一步開發(fā)應(yīng)用程序。系統(tǒng)測試的過程要與系統(tǒng)運行過
21、程一致。系統(tǒng)上電后調(diào)用的啟動程序?qū)μ幚砥饕约按鎯ζ鬟@些硬件進行初始化,初始化完成之后跳轉(zhuǎn)至main()函數(shù),在此之前的工作基本與c/os-ii內(nèi)核無關(guān),所以對內(nèi)核的測試從main()函數(shù)開始。在main()函數(shù)中系統(tǒng)調(diào)用osinit()初始化c/os-ii中所有的變量和數(shù)據(jù)結(jié)構(gòu),為了使測試更加簡單,可以在系統(tǒng)配置中禁止系統(tǒng) 統(tǒng)計任務(wù)(#define os_task_stat_en 0)。于是,系統(tǒng)在初始化時至創(chuàng)建一個空閑任務(wù),并將其優(yōu)先級設(shè)置為最低,讓其永遠處于就緒狀態(tài)。測試之前建立的main()函數(shù)代碼如下:void main(void)target_init();osinit();osta
22、skcreate(starttask,(void*)0,&starttaskstktasksize-1,pro);osstart();代碼含義如下:初始化目標(biāo)板上載調(diào)試時要用到的基本硬件,如led;調(diào)用osinit(),初始化c/os-ii系統(tǒng)內(nèi)核;創(chuàng)建一個用戶任務(wù),用來測試多任務(wù)調(diào)度是否成功;調(diào)用osstart(),開始多任務(wù)調(diào)度。這里用到的與系統(tǒng)相關(guān)的函數(shù)有osinit()、ostaskcreate()、osstart(),只要這3個函數(shù)運行正常系統(tǒng)就算移植成功。下面開始測試代碼。2.2.1 保證編譯正確,系統(tǒng)啟動正確從最簡單的開始 ,這一步只要保證代碼沒有語法錯誤并且系統(tǒng)可正確啟動即可。
23、將main()函數(shù)進行如下改動:#include”includes.h”void main(void)target_init( );led_on( );在ads下編譯并運行這段代碼。如果指示燈被成功點亮,就說明沒有語法問題,而且硬件也已經(jīng)啟動完成了。這是一段用來驗證是否存在語法錯誤并且編譯、鏈接器以及匯編器是否配置正確的代碼。2.2.2調(diào)試os_enter_critical()講之前的測試程序進行如下更改,在之前的main()函數(shù)中加入osinit()函數(shù),即#include”includes.h”void main(void)target_init( );osinit( );led_on(
24、);系統(tǒng)函數(shù)osinit()用于初始化c/os-ii系統(tǒng),使用系統(tǒng)函數(shù)osinit()時不需要輸入?yún)?shù),直接調(diào)用即可。osinit()函數(shù)設(shè)計的移植代碼包括os_enter_critical( )、os_exit_critical()、ostaskstkinit()。在ads下編譯完成,啟動axd進行調(diào)試。以上3個函數(shù)都是在osinit()內(nèi)部創(chuàng)建系統(tǒng)空閑任務(wù)時被調(diào)用的。對這些函數(shù)分別使用單步雕飾的發(fā)那個發(fā),觀察寄存器中的值是否與設(shè)計一致。2.2.3 調(diào)試osstarthighrdy()在之前的main()函數(shù)中加入osstart()函數(shù),即#include”includes.h”void m
25、ain(void)target_init( );osinit( );led_on( );osstart( );系統(tǒng)函數(shù)osstart()用于啟動多任務(wù),使用時不需要輸入?yún)?shù),直接調(diào)用即可。進入調(diào)試器開始調(diào)試,執(zhí)行main()函數(shù)。如果移植正確,程序會從osstarthighrdy()運行至os_taskidle()。整個運行過程中需要關(guān)注的是移植中重寫的函數(shù)osstarthighrdy()。這里可以通過調(diào)試器觀察是否將優(yōu)先級最高的任務(wù)控制塊交付給當(dāng)前處理器,也就是os_taskidle( )任務(wù),并且將新任務(wù)的所有寄存器按與入棧相反的順序出棧。如果這里出現(xiàn)問題那么棧指針就會出錯,這是就要對os
26、starthighrdy()進行修改。從osstarthighrdy()中返回時應(yīng)該直接跳轉(zhuǎn)至os_taskidle(),如果沒有這樣,那么有可能是在初始化時系統(tǒng)調(diào)用的ostaskstkinit()沒能正確創(chuàng)建任務(wù)堆棧,這是只要檢查并改正就可以 。在ostaskidlehook()將指示燈的狀態(tài)取反,并在其后加上適當(dāng)延時。具體如下:void ostaskidlehook(void)led_turn( );delay(10);這樣如果指示燈能夠閃爍,那么就說明系統(tǒng)運行正常,osstarthighrdy()的移植是成功的。2.2.4 調(diào)試osctxsw()通過上面幾步可知ostaskstkinit
27、()對任務(wù)棧的初始化操作是正確的,下來就可以創(chuàng)建一個用戶任務(wù),并且通過osctxsw()使其被切換至os_taskidle(),以此驗證osctxsw()正確與否。首先更改主程序,即#include”include.h”os_stk taskstk100;void main(void)char idl=1;osinit( );led_on( );ostaskcreate(starttask,&idl,&taskstk99,4);osstart( ); void starttask(void* pdata)pdata=pdata;while(1)led_off( );ostimedly(1);系
28、統(tǒng)函數(shù)ostaskcreate()用于創(chuàng)建用戶任務(wù),有4個輸入?yún)?shù),它們分別是:第1個參數(shù):task指向任務(wù)代碼的指針,即在定義任務(wù)時使用的任務(wù)名;第2個參數(shù):pdata任務(wù)開始時傳遞給任務(wù)的參數(shù)指針;第3個參數(shù):ptos分配給任務(wù)棧的棧頂指針,任務(wù)棧需要提前聲明為os_stk類型的數(shù)組,這里的任務(wù)棧是容量為100的減棧。第4個參數(shù):prio任務(wù)優(yōu)先級,任務(wù)就是在這里獲得最初優(yōu)先級。系統(tǒng)函數(shù)ostimedly()用于系統(tǒng)延時時,有一個輸入?yún)?shù),int16u類型的ticks,用以表示要延時多少個時鐘節(jié)拍后再重新返回該任務(wù)。但是由于此時還沒有啟動時鐘節(jié)拍,所以系統(tǒng)無法從os_taskidle(0中
29、返回到startask()任務(wù)。編譯通過即可調(diào)試運行,同第3步一樣單步運行osstart()會發(fā)現(xiàn),程序會跳轉(zhuǎn)至新建立的任務(wù),這是因為新建立的任務(wù)優(yōu)先級高于os_taskidle();繼續(xù)單步運行starttask()至ostimedly(1),系統(tǒng)在ostimedly()的最后調(diào)用了任務(wù)調(diào)度器os_sched(),在調(diào)度器的最后用osctxsw()實現(xiàn)了任務(wù)級的任務(wù)切換;單步執(zhí)行至osctxsw(),在osctxsw()中可以看到當(dāng)前任務(wù)starttask()中所有寄存器已經(jīng)保存到它自己的任務(wù)棧中,os_taskidle()任務(wù)棧中的寄存器則被調(diào)入當(dāng)前處理器,從osctxsw()返回到so_
30、taskidle()。如果沒能運行到os_taskidle(),則需在osctxsw(0中查找原因并改正錯誤。當(dāng)全速欲行程序時,如果結(jié)果正確則可以看到指示燈先閃滅一次,然后開始以一個固定的頻率閃動。2.2.5 調(diào)節(jié)時鐘節(jié)拍由前面可知,任務(wù)棧的建立和初始化,以及任務(wù)級的任務(wù)調(diào)度都是正確的,還剩下系統(tǒng)時鐘ostickisr()和中斷級任務(wù)調(diào)度osintctxsw()這兩個移植項需要測試。在測試這兩個函數(shù)之前,首先要保證系統(tǒng)的時鐘節(jié)拍(定時器中斷)是否可以正常運行,對starttask()任務(wù)進行如下改正:void starttask(void*pdata)pdata=pdata;timer_ini
31、t( );while(1);將ostimetick()中調(diào)用的ostimetickhook()更改如下:void ostimetickhook(void)led_turn( );編譯通過后開始調(diào)試,全速運行。如果看到指示燈閃爍說明時鐘節(jié)拍沒有問題,否則要對ostickisr()進行單步調(diào)試。2.2.6 調(diào)試osintctxsw()和ostickisr()首先刪除ostimetickhook()和ostaskidlehook()中對指示燈的操作。其次對starttask()任務(wù)進行如下更改:void starttask(void*pdata)pdata = pdata;timer_init( )
32、;for(;)ostimedly(1);編譯通過后可以開始調(diào)試。如果osintctxsw()移植正確,全速運行指示燈閃爍,并且閃爍頻率與ostimedly(x)中的x成正比關(guān)系。否則就要針對osintctxsw()移植代碼進行調(diào)試更改。調(diào)試時仍用外部中斷代替定時器中斷。至此所有與移植相關(guān)的文件都已經(jīng)調(diào)試完成,移植的c/os-ii意見可以正常工作,下面將在這個移植好的操作系統(tǒng)上,重新實現(xiàn)之前的電子詞典應(yīng)用實例。3 驅(qū)動程序的設(shè)計與調(diào)試3.1 基于c/os-ii的中斷設(shè)計中斷使得處理器可以在事件發(fā)生時才予以處理,而不必連續(xù)不斷地查詢是否有事件發(fā)生,所以是設(shè)計驅(qū)動時一個很重要的方法。在實時環(huán)境中,關(guān)
33、中斷的事件應(yīng)盡量短。關(guān)中斷影響中斷響應(yīng)時間,關(guān)中斷時間太長可能會引起中斷丟失。中斷服務(wù)的處理時間應(yīng)該盡可能短,中斷服務(wù)所做的事情應(yīng)該盡可能少,應(yīng)該把大部分工作留給任務(wù)去做。c/os-ii系統(tǒng)內(nèi)核通過特殊函數(shù)os_enter_critical( )和os_exit_critical( )來開/關(guān)中斷,讓用戶決定什么情況下需要響應(yīng)中斷,什么情況下不需要。本設(shè)計中涉及到的中斷分為兩大類:定時器中斷和用戶中斷。定時器中斷:它作為系統(tǒng)的時鐘節(jié)拍為系統(tǒng)提供特定的周期性中斷,是系統(tǒng)任務(wù)調(diào)度的基礎(chǔ)。使得系統(tǒng)內(nèi)核可以將任務(wù)延時若干個時鐘節(jié)拍,以及當(dāng)任務(wù)要求等待時提供超時依據(jù)。用戶中斷:鍵盤中斷以及觸摸屏中斷。所
34、有基于c/os-ii的isr需要調(diào)用osintenter()和osintexit()使內(nèi)核進入/退出中斷處理狀態(tài)。3.2 基于c/os-ii的設(shè)備驅(qū)動程序設(shè)計將硬件分為主動式硬件和被動式硬件兩類。主動式硬件指可以接受外部信息要求軟件作出響應(yīng)的軟件,如本系統(tǒng)的鍵盤和觸摸屏。主動式硬件驅(qū)動設(shè)計可分為初始化、中斷服務(wù)以及請求處理3類。在中斷服務(wù)中使用信號量通知任務(wù)有事情發(fā)生,根據(jù)信號量的不同啟動相應(yīng)的任務(wù),在該任務(wù)中對發(fā)出信號的硬件進行處理。因此,在初始化具體硬件時需要創(chuàng)建用于通知系統(tǒng)的信號量。下面是相應(yīng)代碼:os_event *f_key;os_event *f_touch;os_event *k
35、ey_value;void device_drever_init(void)int8u err;f_key=ossemcreate(0);f_touch=ossemcreate(0);key_value=osmboxcreate(void*)0);gui_init( );keyboard_init( );touchscreen_init( );系統(tǒng)函數(shù)ossemcreate()用于創(chuàng)建信號量,只有一個int16u型的參數(shù)cnt用于表示該信號量的初始計數(shù)值,范圍是065535。信號量f_key和f_touch,分別用于表示鍵盤和觸摸屏。這兩個信號量都是用于表示有一個硬件輸入時間按發(fā)生所以在創(chuàng)建時
36、將cnt的初始值賦為0。系統(tǒng)函數(shù)osmboxcreate()用于創(chuàng)建消息郵箱,唯一的輸入?yún)?shù)msg是一個可以指向任意類型值的指針,這個指針?biāo)赶虻木褪青]箱的內(nèi)容。在調(diào)用此函數(shù)創(chuàng)建郵箱時必須定義指針的初始值。通常用null將這個郵箱初始化為空,也可以在初始化時就給郵箱中放入消息。該函數(shù)返回一個指向事件控制塊ebc的指針,相當(dāng)于這個郵箱的名字。觸摸屏中斷服務(wù)代碼如下:void_ _irq touchscreen_int (void)osintenter( );rintmsk|=bit_eint0;ri_ispc=bit_einto;ossempost(f_touch);osintexit( );3
37、.3 基于c/os-ii的設(shè)備驅(qū)動程序測試在開始設(shè)計任務(wù)之前,可借鑒調(diào)試最小系統(tǒng)的方法對完成的設(shè)備驅(qū)動進行測試,測試仍遵循由簡到繁的原則,先測試被動式硬件,再測試主動式硬件。將做好的驅(qū)動代碼加入之前的測試工程,在創(chuàng)建的starttask中加入要測試硬件的初始化代碼。代碼在pc機上啟動串口調(diào)試工具,設(shè)置參數(shù)。編譯并運行測試代碼,如果測試成功則會通過串口每隔一個固定時間間隔打印一條提示信息。在timer_init( )內(nèi)將時鐘節(jié)拍設(shè)置為100hz,ostimedly(100)就會使starttask任務(wù)每秒啟動一次,則打印的時間間隔應(yīng)該大約是1s。測試主動式硬件與此過程稍有不同,需要在任務(wù)中等待系
38、統(tǒng)發(fā)來的相應(yīng)信號,以鍵盤為例,仍然使用starttask任務(wù),代碼如下:代碼系統(tǒng)函數(shù)ossempend用于等待信號量。有3個輸入?yún)?shù)分別是:第1個參數(shù)為指向要等待的信號量對應(yīng)的事件控制塊的指針;第2個參數(shù)為int16u類型的timeout,代表等待超時的時間,以時鐘節(jié)拍為單位,如果設(shè)置為0,表示無限期等待;第3特參數(shù)認(rèn)為返回的err錯誤狀態(tài)。4 系統(tǒng)集成與功能測試4.1 初始化任務(wù)系統(tǒng)初始化任務(wù)通常在main()函數(shù)中創(chuàng)建,分配的優(yōu)先級可以是允許的優(yōu)先級中的任意一個,因為初始化任務(wù)通常只運行一次,運行完成后可以將其刪除,不會對其他任務(wù)優(yōu)先級分配造成影響。在main()函數(shù)中要對目標(biāo)板上的基本硬
39、件做初始化工作,如串口的初始化、中斷控制的初始化、s3c44b0x內(nèi)部緩存的初始化等。main()函數(shù)的代碼如下:void main(void)char idl=1;target_init( );uart_printf(0,”*=start test=*n);osinit( );ostaskcreate(inittask,&idl,&taskstk1taskstacksize-1,4);osstart( );硬件初始化:如lcd、鍵盤和觸摸屏。軟件初始化:創(chuàng)建所需的信號量、事件標(biāo)志組、消息郵箱、消息隊列中的一個或多個;創(chuàng)建用戶任務(wù),但可以不是所有的任務(wù),根據(jù)系統(tǒng)的需要而定。由于初始化任務(wù)并不需
40、要重復(fù)進行,所以在最后調(diào)用ostaskdel(so_prio_self)將其自身刪除即可。其代碼如下:/定義每個任務(wù)所要用到的棧os_stktaskstk1taskstacksize;os_stktaskstk2mintaskstacksize;os_stktaskstk3maxtaskstacksize;os_stktaskstk4taskstacksize;os_stktaskstk5taskstacksize;void inittask(void* pdata)char id2=2;char id3=3;char id4=4;char id5=5;ostaskcreate(coursor
41、task,&id2,&taskstk2mintaskstacksize-1,7); ostaskcreate(executtask,&id5,&taskstk3maxtaskstacksize-1,8);ostaskcreate(kbrecievetask,&id4,&taskstk4 taskstacksize-1,9);ostaskcreate(adconvertask,&id3,&taskstk5 taskstacksize-1,6);target_start( );ostaskdel(os_prio_self); 4.2 鍵盤處理任務(wù)對鍵盤的處理首先需要能對鍵盤動作做出響應(yīng),因此鍵盤處
42、理函數(shù)必須能夠響應(yīng)鍵盤中斷,并通過系統(tǒng)總線讀取鍵盤相應(yīng)信息,并將其打印出來。代碼如下:/鍵盤測試函數(shù):void keyboard_test(void)int i, j, k;uint8t ucchar, t;iic_init();/ set eint2 interrupt handler pisr_eint2 = (int)keyboard_int;for(;) f_nkeypress = 0;rintmsk = rintmsk & (bit_global|bit_eint2);/ enable eint2 intwhile(f_nkeypress = 0);iic_read(0x70, 0x
43、1, &ucchar);if(ucchar !=0)ucchar = key_set(ucchar);if(ucchar 10) ucchar += 0x30;else if(ucchar 16) ucchar += 0x37;if(ucchar 255)uart_printf(press key %cn, ucchar);if(ucchar = 0xff)uart_printf( press key fun (exit now)nr);return; while(1);其中f_nkeypress為全局變量,含義是是否有鍵盤中斷發(fā)生(0代表有,1代表沒有)。鍵盤中斷函數(shù)如下:void keyb
44、oard_int(void)uint8t ucchar; delay(1000);rintmsk = rintmsk | bit_eint2;/ disable eint2 int ri_ispc = bit_eint2; f_nkeypress = 1;對鍵盤數(shù)值進行轉(zhuǎn)換代碼如下:uint8t key_set(uint8t ucchar)switch(ucchar)case 1:case 2:case 3:case 4:case 5:ucchar-=1; break;case 9:case 10:case 11:case 12:case 13:ucchar-=4; break;case 17
45、:case 18:case 19:case 20:case 21:ucchar-=7; break;case 25: ucchar = 0xf; break;case 26: ucchar = +; break;case 27: ucchar = -; break;case 28: ucchar = *; break;case 29: ucchar = 0xff; break;default: ucchar = 0xfe;return ucchar;iic頭文件代碼:/* file:iic.h* author:embest* desc:iic header file* history:*/#i
46、fndef _iic_h_#define _iic_h_#endif /*_iic_h_*/系統(tǒng)總線iic的初始化函數(shù)如下:void iic_init(void)f_ngetack = 0; / enable interruptrintmod = 0x0;rintcon = 0x1;rintmsk = rintmsk & (bit_global|bit_iic); pisr_iic= (unsigned)iic_int;/ initialize iicriicadd = 0x10;/ s3c44b0x slave address riiccon = 0xe5;/ enable ack, int
47、errupt, iicclk=mclk/512, enable ack/64mhz/512/(15+1) = 8khz riicstat= 0x10;/ enable tx/rx iic的寫操作代碼如下:/* name:iic_write* func:write data to iic* para:unslaveaddr - input, chip slave address*unaddr- input, data address*ucdata - input, data value* ret:none* modify:* comment:*/void iic_write(uint32t un
48、slaveaddr,uint32t unaddr,uint8t ucdata)f_ngetack = 0; / send control byte riicds = unslaveaddr;/ 0xa0 riicstat = 0xf0; / master tx,start while(f_ngetack = 0);/ wait ack f_ngetack = 0; / send address riicds = unaddr; riiccon = 0xe5; / resumes iic operation.while(f_ngetack = 0);/ wait ack f_ngetack = 0; / send data riicds = ucdata; riiccon = 0xe5; / resumes iic operation. while(f_ngetack = 0);/ wait ack f_ngetack = 0; / end send riicstat = 0xd0;/ stop master tx condition riiccon = 0xe5;/ resumes iic operation.while(ri
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 語文S版語文三年級上冊第八單元練習(xí)卷(解析版)
- 鄂教版語文三年級上冊15 信任練習(xí)卷
- 人教新課標(biāo)版語文四年級上冊21 搭石練習(xí)卷(解析版)2
- 語文教材創(chuàng)新與應(yīng)用計劃
- 生物醫(yī)學(xué)研究中的隱私保護措施
- 高一生物課程評價與反思計劃
- 信息技術(shù)系統(tǒng)開發(fā)進度與措施
- 2025年秋季學(xué)期國際學(xué)校課程安排計劃
- 圖書館文明行為監(jiān)督崗職責(zé)
- 陽光體育大課間活動與心理健康計劃
- 遂寧遂寧市住房和城鄉(xiāng)建設(shè)局公開招聘編外人員筆試歷年參考題庫附帶答案詳解
- DBJ41-T311-2025 《人民防空節(jié)鎳型不銹鋼防護設(shè)備選用與安裝技術(shù)標(biāo)準(zhǔn)》
- 2025-2030年中國軍用機器人行業(yè)市場現(xiàn)狀供需分析及投資評估規(guī)劃分析研究報告
- 2025高考化學(xué)復(fù)習(xí)新題速遞之有機合成(解答大題)(2025年4月)
- 駕校掛靠合同協(xié)議書
- 2025年福建武夷旅游集團有限公司人才教育板塊自主招聘17人筆試參考題庫附帶答案詳解
- 新聞閱讀-2024年中考語文記敘文閱讀專項復(fù)習(xí)(原卷版)
- 2025-2030中國面粉行業(yè)市場深度調(diào)研及前景趨勢與投資研究報告
- 民法典進企業(yè)講稿課件
- 2025年計算機編程能力測試試卷及答案
- 2025信息技術(shù)系統(tǒng)維護服務(wù)合同范本
評論
0/150
提交評論