




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、目錄1系統定義與需求分析31.1系統定義31.1.1任務功能描述31.1.2 任務的優先級分配41.1.3 任務間同步與通信的規則41.2 系統配置42詳細設計62.1 系統移植62.1.1移植os_cpu.h62.1.2 移植os_cpu_c.c72.2 最小系統的運行調試102.2.1 保證編譯正確,系統啟動正確112.2.2調試os_enter_critical()112.2.3 調試osstarthighrdy()122.2.4 調試osctxsw()122.2.5 調節時鐘節拍132.2.6 調試osintctxsw()和ostickisr()143 驅動程序的設計與調試153.1
2、基于c/os-ii的中斷設計153.2 基于c/os-ii的設備驅動程序設計153.3 基于c/os-ii的設備驅動程序測試164 系統集成與功能測試174.1 初始化任務174.2 鍵盤處理任務184.3 觸摸屏處理任務234.4 系統集成測試355參考文獻381系統定義與需求分析1.1系統定義電子詞典是一個典型的由外部輸入驅動的開環系統,由鍵盤或觸摸屏輸入信息,處理器根據輸入的信息在lcd顯示屏上顯示相應的內容,顯示完成之后系統進入空閑狀態等待下一次輸入。根據這一處理過程,講電子詞典應用分為3個主任務主執行任務,鍵盤任務,觸摸屏任務。系統的總體設計如圖1-1所示。main()函數初始化任務
3、鍵盤任務主執行任務觸摸屏任務光標任務鍵盤isr觸摸屏isr時鐘節拍 圖1-1 c/os-ii系統總是從main()函數開始,通常在main()函數中指創建一個用戶任務,即初始化任務,這樣設計有利于系統管理,而且結構也會更清晰。在初始化任務中啟動時鐘節拍,創建各個任務以及要用到的信號量或消息。1.1.1任務功能描述在電子詞典設計中,鍵盤任務和觸摸屏任務負責采集輸入信號,并將其轉換為鍵值告知主處理任務。主處理任務負責根據讀到的鍵值啟動相應功能。而光標任務則是用來展現時鐘節拍,讓目標板上的led燈以指定的時間間隔進行閃爍。1.1.2 任務的優先級分配系統中的優先級分配按照最經常發生的優先級最高這一原
4、則進行,具體分配如下:優先級03:分配優先級時將最高的4個優先級留給系統用戶;優先級5:主處理任務優先級最高為5級;優先級6:鍵盤的使用概率大于觸摸屏,其優先級定為6級;優先級7:觸摸屏的優先級為7級;優先級8:光標每隔一個固定的時間閃爍一次,這個時間可以由用戶自定義,優先級為8級;最低優先級-1:系統統計任務(可選);最低優先級:系統空閑任務。1.1.3 任務間同步與通信的規則需要傳遞消息的任務是鍵盤與主執行任務。觸摸屏與主執行任務之間傳遞的都是按鍵值,且鍵值不用區分來源,所以使用一個消息郵箱即可。由于任務間不存在共享互斥資源的問題,所以不需要進行任務間的同步。鍵盤與觸摸屏都是由外界時間觸發
5、的,可以使用中斷機制設計驅動程序。在驅動程序的設計中,遵循中斷中處理的時間盡量短,講更多的事情交給任務區完成這一原則。1.2 系統配置c/os-ii并不提供列斯linux那樣的命令行形式的配置方法,而是通過對配置的內容進行條件編譯來實現的。這是由于c/os-ii提供開放的源代碼,用戶可以直接使用#define constants語句來更改內核的很多參數。系統中提供了以下配置項:事件標志:包括使能或禁止事件標志及其相關功能,通常以os_flag_為前綴;消息郵箱:包括使能或禁止消息郵箱及其相關功能,通常以os_mbox_為前綴;內存管理:包括使能或禁止內存管理及其相關功能,目前版本中只有兩個可配
6、置項os_mem_en和os_mem_query_en;互斥型信號量:包括使能或禁止互斥型信號量及其相關功能,通常以os_mutex_為前綴;消息隊列:包括使能或禁止消息隊列及其相關功能,通常以os_q_為前綴;信號量:包括使能或禁止信號量及其相關功能,通常以os_sem_為前綴;任務管理:系統提供兩個任務創建函數,在配置文件中至少要對其中一個進行使能,另外還包括一些對任務其他相關屬性的配置,通常以os_task_為前綴;時鐘管理:c/os-ii中用戶可以使用操作系統的時鐘作為演示的基準,這里包括使能或禁止使用系統時鐘及其相關功能,通常以os_time_為前綴;雜項:包括配置任務,事件,消息隊
7、列的最大個數,任務堆棧的容量等。c/os-ii內核默認的是將系統配置為最大系統,即使能所有功能,并且將認為尿素時間按等設置為最大。在電子詞典的應用中,只有13個任務(5個用戶任務,8個系統預留任務)、兩個事件標志、一個消息郵箱,所以需要對默認系統進行重新配置。需要更改的主要參數如下:os_max_events:最大可申請的事件控制塊數。系統中每個消息和信號量都需要一個事件控制塊。電子詞典中只用到一個消息郵箱,該值大于1即可。為了便于本系統擴展,將其設為5。os_max_flags:最大可申請的事件標志數。當前使用了倆各個事件標志,該值大于2即可。為了便于本系統擴展將其設為5。os_max_ta
8、sks:最大可申請的用戶任務書。電子詞典中共定義了5個用戶任務,該值大于5即可。為了便于本系統擴展將其設為10。os_lowest_prio:系統可分配的最低優先級。系統根據該參數初始化任務控制塊,所以這個參數會影響系統對ram的占用 。電子詞典將此參數定義為15,其中5個用戶任務、8個系統任務、2個余量任務。各個功能的使能/禁止參數通常以_en為后綴,1為使能,0為禁止。在電子詞典中要使能消息郵箱(os_mbox_en)和信號量(os_sem_en),將其對應的參數設為1,其余使能參數設為0,其他參數均使用默認值即可。2詳細設計2.1 系統移植在移植c/os-ii之前,要確保目標系統(主要是
9、處理器及其編譯環境)滿足如下要求:(1) 目標系統所使用的編譯環境要包括標準的c交叉編譯器。(2) 目標系統所使用的c編譯器支持在c程序中對中斷進行操作。(3) 處理器必須可以產生定時器中斷。(4) 處理器必須可容納一定數據存儲硬件堆棧。(5) 處理器中的寄存器與內存之間可以相互讀/寫。2.1.1移植os_cpu.h在os_cpu.h里主要包括與處理器有關的數據類型、常量以及宏的定義。定義常量so_stk_growth。這個常量表示了棧的增長方向。1為向上遞減,棧底高地址入棧時指針減,出棧時指針加;0為向下遞增,棧底低地入棧時指針加,出棧時減。定義宏os_enter_critical()和os
10、_exit_critical()。這兩個宏是用來打開和關閉中斷的。當c/os-ii需要處理不能被中斷打斷的段時,就要用到這兩個宏對其進行保護。由于不同的處理器對中斷的操作不盡相同,所以在這里對這兩個操作進行定義。關中斷宏代碼如下:#define os_enter_critical() _ _asmbl armdisableint 開中斷宏代碼如下:#define os_exit_critical() _ _asmbl armenableint 具體功能在os_cpu_a.s實現,代碼如下:armdisableintmrsr0,cpsrstmfd sp!,r0 ;保存當前處理器狀態orrr0,r
11、0,#0x80msrcpsr_c,r0 ;禁止中斷movpc,lrarmenableintldmfdsp!,r0 ;從棧中彈出處理器的狀態值msrcpsr_c,r0 ;恢復原始的處理器狀態movpc,lr2.1.2 移植os_cpu_c.cos_cpu_c.c包括10個簡單的c函數。與移植相關的只有ostaskstkinit()函數,該函數負責對任務棧進行初始化。另外9個都是對各種任務進行擴展時用的,雖然必須定義,但可以不用包含任何代碼。這10個函數分別是:ostaskstkinit()、ostaskcreatehook()、ostaskdelhook()、ostaskswhook()、ost
12、askidlehook()、ostaskstathook()、ostimetickhook()、osinithookbegin()、osinithookend()和ostcbinithook()。ostaskstkinit()函數在創建任務時被ostaskcreate()或ostaskcreateexit()調用,以初始化任務棧結構,將所有的寄存器像剛發生中斷一樣保存在棧里。雖然arm對棧的方向并沒有特殊要求,但是由于ads編譯器僅支持滿減棧fd(full descending),即高地址為棧底,入棧時指針減1,棧指針指向最后一個入棧的數據元素,所以需要在os_cpu.h中將任務棧定義為減棧:
13、#define os_stk_growth 1/*內存中棧的增長方向為從高到低*/其實際結構如圖2-1所示。pdata是在人物創建時傳遞給任務的一個參數。代碼如下:os_stk*ostaskstkinit(viod(*task)(void*pd),void*pdata,os_stk*ptos,int16u opt)unsigned int * stk;opt=opt; stk=(unsigned int *)ptos; /*當前棧指針*/*對新任務建立上下文環境*/*_ _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個與處理器相關的函數要用匯編語言實現,這4個函數分別是:oostarthighrdy( )、osctxsw( )、osintctxsw( )和ostickisr( )。oostarthighrdy( )oostarthighrdy( )僅在osstart()函數中被調用。具體實現代碼如下: 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中定義,通過它用戶可以擴展任務切換代碼的功能。osctxsw( )osctxsw( )用來實現任務級的任務切換。具體實現代碼如下: 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( )調用,在isr中實現任務切換功能。通常使用如下形式的代碼實現中斷級的任務切換: osintctxswldrr0,=osintctxsw
18、flagmovr1,#1strr1,r0movpc,lr以上這段代碼值設置了一個用以表示是否需要進行任務切換的標志osintctxswflag,在中斷后的第一個時鐘節拍內對此標志進行判斷,根據判斷結果決定是都需要進行中斷級任務切換。ostixkisr( )ostixkisr( )時鐘節拍中斷的isr。在之前提到過的c/os-ii要求用戶提供一個稱為時鐘節拍的定時中斷,以實現延時與超時控制等功能。這個中斷頻率一般是10100hz。具體實現代碼如下: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/*-以下代碼用于任務切換-*/_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 最小系統的運行調試最小系統主要是指如處理器、存儲器這些最基本的元素所組成的可運行的最小系統,在增加了操作系統之后,可以認為最小系統等于硬件最小能運行系統加上可運行的操作系統內核。只有當最小系統運行起來以后,才能進一步開發應用程序。系統測試的過程要與系統運行過
21、程一致。系統上電后調用的啟動程序對處理器以及存儲器這些硬件進行初始化,初始化完成之后跳轉至main()函數,在此之前的工作基本與c/os-ii內核無關,所以對內核的測試從main()函數開始。在main()函數中系統調用osinit()初始化c/os-ii中所有的變量和數據結構,為了使測試更加簡單,可以在系統配置中禁止系統 統計任務(#define os_task_stat_en 0)。于是,系統在初始化時至創建一個空閑任務,并將其優先級設置為最低,讓其永遠處于就緒狀態。測試之前建立的main()函數代碼如下:void main(void)target_init();osinit();osta
22、skcreate(starttask,(void*)0,&starttaskstktasksize-1,pro);osstart();代碼含義如下:初始化目標板上載調試時要用到的基本硬件,如led;調用osinit(),初始化c/os-ii系統內核;創建一個用戶任務,用來測試多任務調度是否成功;調用osstart(),開始多任務調度。這里用到的與系統相關的函數有osinit()、ostaskcreate()、osstart(),只要這3個函數運行正常系統就算移植成功。下面開始測試代碼。2.2.1 保證編譯正確,系統啟動正確從最簡單的開始 ,這一步只要保證代碼沒有語法錯誤并且系統可正確啟動即可。
23、將main()函數進行如下改動:#include”includes.h”void main(void)target_init( );led_on( );在ads下編譯并運行這段代碼。如果指示燈被成功點亮,就說明沒有語法問題,而且硬件也已經啟動完成了。這是一段用來驗證是否存在語法錯誤并且編譯、鏈接器以及匯編器是否配置正確的代碼。2.2.2調試os_enter_critical()講之前的測試程序進行如下更改,在之前的main()函數中加入osinit()函數,即#include”includes.h”void main(void)target_init( );osinit( );led_on(
24、);系統函數osinit()用于初始化c/os-ii系統,使用系統函數osinit()時不需要輸入參數,直接調用即可。osinit()函數設計的移植代碼包括os_enter_critical( )、os_exit_critical()、ostaskstkinit()。在ads下編譯完成,啟動axd進行調試。以上3個函數都是在osinit()內部創建系統空閑任務時被調用的。對這些函數分別使用單步雕飾的發那個發,觀察寄存器中的值是否與設計一致。2.2.3 調試osstarthighrdy()在之前的main()函數中加入osstart()函數,即#include”includes.h”void m
25、ain(void)target_init( );osinit( );led_on( );osstart( );系統函數osstart()用于啟動多任務,使用時不需要輸入參數,直接調用即可。進入調試器開始調試,執行main()函數。如果移植正確,程序會從osstarthighrdy()運行至os_taskidle()。整個運行過程中需要關注的是移植中重寫的函數osstarthighrdy()。這里可以通過調試器觀察是否將優先級最高的任務控制塊交付給當前處理器,也就是os_taskidle( )任務,并且將新任務的所有寄存器按與入棧相反的順序出棧。如果這里出現問題那么棧指針就會出錯,這是就要對os
26、starthighrdy()進行修改。從osstarthighrdy()中返回時應該直接跳轉至os_taskidle(),如果沒有這樣,那么有可能是在初始化時系統調用的ostaskstkinit()沒能正確創建任務堆棧,這是只要檢查并改正就可以 。在ostaskidlehook()將指示燈的狀態取反,并在其后加上適當延時。具體如下:void ostaskidlehook(void)led_turn( );delay(10);這樣如果指示燈能夠閃爍,那么就說明系統運行正常,osstarthighrdy()的移植是成功的。2.2.4 調試osctxsw()通過上面幾步可知ostaskstkinit
27、()對任務棧的初始化操作是正確的,下來就可以創建一個用戶任務,并且通過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、統函數ostaskcreate()用于創建用戶任務,有4個輸入參數,它們分別是:第1個參數:task指向任務代碼的指針,即在定義任務時使用的任務名;第2個參數:pdata任務開始時傳遞給任務的參數指針;第3個參數:ptos分配給任務棧的棧頂指針,任務棧需要提前聲明為os_stk類型的數組,這里的任務棧是容量為100的減棧。第4個參數:prio任務優先級,任務就是在這里獲得最初優先級。系統函數ostimedly()用于系統延時時,有一個輸入參數,int16u類型的ticks,用以表示要延時多少個時鐘節拍后再重新返回該任務。但是由于此時還沒有啟動時鐘節拍,所以系統無法從os_taskidle(0中
29、返回到startask()任務。編譯通過即可調試運行,同第3步一樣單步運行osstart()會發現,程序會跳轉至新建立的任務,這是因為新建立的任務優先級高于os_taskidle();繼續單步運行starttask()至ostimedly(1),系統在ostimedly()的最后調用了任務調度器os_sched(),在調度器的最后用osctxsw()實現了任務級的任務切換;單步執行至osctxsw(),在osctxsw()中可以看到當前任務starttask()中所有寄存器已經保存到它自己的任務棧中,os_taskidle()任務棧中的寄存器則被調入當前處理器,從osctxsw()返回到so_
30、taskidle()。如果沒能運行到os_taskidle(),則需在osctxsw(0中查找原因并改正錯誤。當全速欲行程序時,如果結果正確則可以看到指示燈先閃滅一次,然后開始以一個固定的頻率閃動。2.2.5 調節時鐘節拍由前面可知,任務棧的建立和初始化,以及任務級的任務調度都是正確的,還剩下系統時鐘ostickisr()和中斷級任務調度osintctxsw()這兩個移植項需要測試。在測試這兩個函數之前,首先要保證系統的時鐘節拍(定時器中斷)是否可以正常運行,對starttask()任務進行如下改正:void starttask(void*pdata)pdata=pdata;timer_ini
31、t( );while(1);將ostimetick()中調用的ostimetickhook()更改如下:void ostimetickhook(void)led_turn( );編譯通過后開始調試,全速運行。如果看到指示燈閃爍說明時鐘節拍沒有問題,否則要對ostickisr()進行單步調試。2.2.6 調試osintctxsw()和ostickisr()首先刪除ostimetickhook()和ostaskidlehook()中對指示燈的操作。其次對starttask()任務進行如下更改:void starttask(void*pdata)pdata = pdata;timer_init( )
32、;for(;)ostimedly(1);編譯通過后可以開始調試。如果osintctxsw()移植正確,全速運行指示燈閃爍,并且閃爍頻率與ostimedly(x)中的x成正比關系。否則就要針對osintctxsw()移植代碼進行調試更改。調試時仍用外部中斷代替定時器中斷。至此所有與移植相關的文件都已經調試完成,移植的c/os-ii意見可以正常工作,下面將在這個移植好的操作系統上,重新實現之前的電子詞典應用實例。3 驅動程序的設計與調試3.1 基于c/os-ii的中斷設計中斷使得處理器可以在事件發生時才予以處理,而不必連續不斷地查詢是否有事件發生,所以是設計驅動時一個很重要的方法。在實時環境中,關
33、中斷的事件應盡量短。關中斷影響中斷響應時間,關中斷時間太長可能會引起中斷丟失。中斷服務的處理時間應該盡可能短,中斷服務所做的事情應該盡可能少,應該把大部分工作留給任務去做。c/os-ii系統內核通過特殊函數os_enter_critical( )和os_exit_critical( )來開/關中斷,讓用戶決定什么情況下需要響應中斷,什么情況下不需要。本設計中涉及到的中斷分為兩大類:定時器中斷和用戶中斷。定時器中斷:它作為系統的時鐘節拍為系統提供特定的周期性中斷,是系統任務調度的基礎。使得系統內核可以將任務延時若干個時鐘節拍,以及當任務要求等待時提供超時依據。用戶中斷:鍵盤中斷以及觸摸屏中斷。所
34、有基于c/os-ii的isr需要調用osintenter()和osintexit()使內核進入/退出中斷處理狀態。3.2 基于c/os-ii的設備驅動程序設計將硬件分為主動式硬件和被動式硬件兩類。主動式硬件指可以接受外部信息要求軟件作出響應的軟件,如本系統的鍵盤和觸摸屏。主動式硬件驅動設計可分為初始化、中斷服務以及請求處理3類。在中斷服務中使用信號量通知任務有事情發生,根據信號量的不同啟動相應的任務,在該任務中對發出信號的硬件進行處理。因此,在初始化具體硬件時需要創建用于通知系統的信號量。下面是相應代碼: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( );系統函數ossemcreate()用于創建信號量,只有一個int16u型的參數cnt用于表示該信號量的初始計數值,范圍是065535。信號量f_key和f_touch,分別用于表示鍵盤和觸摸屏。這兩個信號量都是用于表示有一個硬件輸入時間按發生所以在創建時
36、將cnt的初始值賦為0。系統函數osmboxcreate()用于創建消息郵箱,唯一的輸入參數msg是一個可以指向任意類型值的指針,這個指針所指向的就是郵箱的內容。在調用此函數創建郵箱時必須定義指針的初始值。通常用null將這個郵箱初始化為空,也可以在初始化時就給郵箱中放入消息。該函數返回一個指向事件控制塊ebc的指針,相當于這個郵箱的名字。觸摸屏中斷服務代碼如下:void_ _irq touchscreen_int (void)osintenter( );rintmsk|=bit_eint0;ri_ispc=bit_einto;ossempost(f_touch);osintexit( );3
37、.3 基于c/os-ii的設備驅動程序測試在開始設計任務之前,可借鑒調試最小系統的方法對完成的設備驅動進行測試,測試仍遵循由簡到繁的原則,先測試被動式硬件,再測試主動式硬件。將做好的驅動代碼加入之前的測試工程,在創建的starttask中加入要測試硬件的初始化代碼。代碼在pc機上啟動串口調試工具,設置參數。編譯并運行測試代碼,如果測試成功則會通過串口每隔一個固定時間間隔打印一條提示信息。在timer_init( )內將時鐘節拍設置為100hz,ostimedly(100)就會使starttask任務每秒啟動一次,則打印的時間間隔應該大約是1s。測試主動式硬件與此過程稍有不同,需要在任務中等待系
38、統發來的相應信號,以鍵盤為例,仍然使用starttask任務,代碼如下:代碼系統函數ossempend用于等待信號量。有3個輸入參數分別是:第1個參數為指向要等待的信號量對應的事件控制塊的指針;第2個參數為int16u類型的timeout,代表等待超時的時間,以時鐘節拍為單位,如果設置為0,表示無限期等待;第3特參數認為返回的err錯誤狀態。4 系統集成與功能測試4.1 初始化任務系統初始化任務通常在main()函數中創建,分配的優先級可以是允許的優先級中的任意一個,因為初始化任務通常只運行一次,運行完成后可以將其刪除,不會對其他任務優先級分配造成影響。在main()函數中要對目標板上的基本硬
39、件做初始化工作,如串口的初始化、中斷控制的初始化、s3c44b0x內部緩存的初始化等。main()函數的代碼如下:void main(void)char idl=1;target_init( );uart_printf(0,”*=start test=*n);osinit( );ostaskcreate(inittask,&idl,&taskstk1taskstacksize-1,4);osstart( );硬件初始化:如lcd、鍵盤和觸摸屏。軟件初始化:創建所需的信號量、事件標志組、消息郵箱、消息隊列中的一個或多個;創建用戶任務,但可以不是所有的任務,根據系統的需要而定。由于初始化任務并不需
40、要重復進行,所以在最后調用ostaskdel(so_prio_self)將其自身刪除即可。其代碼如下:/定義每個任務所要用到的棧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 鍵盤處理任務對鍵盤的處理首先需要能對鍵盤動作做出響應,因此鍵盤處
42、理函數必須能夠響應鍵盤中斷,并通過系統總線讀取鍵盤相應信息,并將其打印出來。代碼如下:/鍵盤測試函數: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為全局變量,含義是是否有鍵盤中斷發生(0代表有,1代表沒有)。鍵盤中斷函數如下:void keyb
44、oard_int(void)uint8t ucchar; delay(1000);rintmsk = rintmsk | bit_eint2;/ disable eint2 int ri_ispc = bit_eint2; f_nkeypress = 1;對鍵盤數值進行轉換代碼如下: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_*/系統總線iic的初始化函數如下: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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 38403.3-2025皮革和毛皮防霉劑的測定第3部分:氣相色譜-質譜法(甲醇萃取)
- GB 21342-2025焦炭單位產品能源消耗限額
- 護理職業安全
- 關+于“三極模式”信息傳播格局探微
- 商務西服培訓體系構建
- 運輸租憑合同協議書
- 車站票款分成協議書
- 買賣車合同正規協議書
- 飯店欠款轉讓協議書
- 車輛相撞事故協議書
- SAP-TM運輸管理模塊操作手冊(S4系統)
- 斷親協議書模板
- 2023-2024學年山東省青島市西海岸新區6中英語七年級第二學期期末學業質量監測試題含答案
- 水利安全生產風險防控“六項機制”右江模式經驗分享
- 《在競爭中雙贏》教學設計 心理健康八年級全一冊
- 中外美術評析與欣賞智慧樹知到期末考試答案章節答案2024年湖南大學
- 《電力設備典型消防規程》(DL 5027-2015)宣貫
- MOOC 企業文化與商業倫理-東北大學 中國大學慕課答案
- (2024年)小學體育籃球規則課件
- 如何提高自身的網絡安全意識
- 中醫學理論體系的形成和發展
評論
0/150
提交評論