說明trochilirtos實驗手冊_第1頁
說明trochilirtos實驗手冊_第2頁
說明trochilirtos實驗手冊_第3頁
說明trochilirtos實驗手冊_第4頁
說明trochilirtos實驗手冊_第5頁
已閱讀5頁,還剩161頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

TrochiliRTOS實驗手Copyright(C)目一TrochiliRTOS實驗手Copyright(C)目一二 LED驅(qū)動開 三 1/ 2/TrochiliRTOSTrochiliRTOS布,無需任何版權(quán)費(fèi)用。英文名稱TROCHILI取善鳴的小鳥之意,意味著體積小巧、動作支持最多有32支持常見IPC機(jī)制,semaphore、mailbox、message、mutex、IPC控制結(jié)構(gòu)和操作流程,做了完整APIISR中調(diào)《嵌入式實時操作系統(tǒng)原理與最佳實踐》一書已通過機(jī)械工業(yè)出版社出版,RTOS原4TROCHILIRTOS的技術(shù)細(xì)節(jié)。官方同時也提供TrochiliRTOS斷嵌套等。為了方便移植,大部分的RTOS代碼是用C語言寫的。出于對性能的追求或者3/TrochiliRTOS移植到ARMCORTEXM3處理器上。具體采用的SOC是意法半導(dǎo)體公司的STM32F107系列的處理器。2.1TrochiliRTOS移植到ARMCORTEXM3處理器上。具體采用的SOC是意法半導(dǎo)體公司的STM32F107系列的處理器。2.14/Reset_HandlerPROCEXPORTReset_Handler ;從外部文件中引入main SystemInitIMPORTSystemInitSystemInit r0(SystemInit main R0,=main 從從10行定義了SYSCLK_FREQ_72MHz條件編譯的標(biāo)識符,所以在SetSysClock()函數(shù)中將調(diào)SetSysClockTo72()函數(shù)把芯片的系統(tǒng)時鐘SYSCLK設(shè)置72MHz當(dāng)然,前提是輸入的外部時鐘源HSE的振蕩頻率要為8MHz。5/#ifdefined(STM32F10X_LD_VL)||(definedSTM32F10X_MD_VL)||(defined/*#define HSE_VALUE#defineSYSCLK_FREQ_24MHz/*#define HSE_VALUE/*#defineSYSCLK_FREQ_24MHz24000000/*#defineSYSCLK_FREQ_36MHz36000000/*#defineSYSCLK_FREQ_48MHz48000000/*#defineSYSCLK_FREQ_56MHz56000000#defineSYSCLK_FREQ_72MHz1.staticvoidSetSysClock(void)2.{#ifdef#elifdefined#elifdefined#elifdefined#elifdefined#elifdefined17./*Ifnoneofthedefineaboveisenabled,theHSIisusedasSystemclocksource(defaultafterreset)*/2.2ColibriTrochiliRTOS則可以通過各種Arduinoshield來進(jìn)行功能擴(kuò)展。2-1Colibri開發(fā)2.2.1LED驅(qū)動開Colibri開發(fā)板上有3個用戶LED燈。LED燈的控制是2.2ColibriTrochiliRTOS則可以通過各種Arduinoshield來進(jìn)行功能擴(kuò)展。2-1Colibri開發(fā)2.2.1LED驅(qū)動開Colibri開發(fā)板上有3個用戶LED燈。LED燈的控制是通過操作STM32芯片的I/O引6/1STM32F107VCT6、64KSRAM、256K23SWD接口,1個正版JLINK4567USB轉(zhuǎn)串口引出82MSPI91TFSPI1usbdevice11ArduinoUNO2-1開發(fā)板LED2-1開發(fā)板LEDGPIO輸出電壓的高低來控制LED7/#include#include#include#include#include7. 10.void11./*定義一個GPIO_InitTypeDef類型的結(jié)構(gòu)體8/8//*開啟GPIOC的外設(shè)時鐘/*選擇要控制的GPIOC引腳GPIO_Pin_6|/*設(shè)置引腳模式為通用推挽輸出GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;/*調(diào)用庫函數(shù),初始化/*led燈GPIO_SetBits(GPIOC,GPIO_Pin_5|GPIO_Pin_6|35.36.*LED37.38.voidEVB_LEDControl(intindex,int39. if(index== if(cmd== elseif(index== if(cmd== LED設(shè)備初LED設(shè)備初在開啟外設(shè)時鐘之前,我們首先要配置好系統(tǒng)時鐘SYSCLK,而SYSCLK已經(jīng)由數(shù)LED設(shè)備9/ elseif(index== if(cmd== if(cmd== 88.GPIOGPIOx_BSRRGPIOGPIOx_BSRR寄存器相應(yīng)的位寫入控制參數(shù)就可以了??梢杂肧TGPIO_SetBits()控制輸出高電平,用在LED_GPIO_Config()函數(shù)中,我們在調(diào)用GPIO_Init()函數(shù)之后就曾調(diào)用了2.2.2外部按鍵驅(qū)動開個用戶KEY圖2-2開發(fā)板外部按鍵硬GPIORCC片上外設(shè),由于還使用到了中斷,所以要多使用兩個庫文件,分別為stm32f10x_exti.c和misc.c,需要把這兩個文件也添加到工程之中。其中2-4key10/ #include11/11/#include#include#include *配置PE5為線中斷口,并設(shè)置中斷優(yōu)先 void10.GPIO_InitTypeDefEXTI_InitTypeDef/*configtheextiline(PD13)clockandAFIOclockRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO,/*configP[A|B|C|D|E]13NVIC_InitStructure.NVIC_IRQChannel=NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=NVIC_InitStructure.NVIC_IRQChannelSubPriority=NVIC_InitStructure.NVIC_IRQChannelCmd=/*EXTIlinegpioconfig(PD13)GPIO_InitStructure.GPIO_Pin=GPIO_InitStructure.GPIO_Mode=/*EXTIline(PD13)modeconfig EXTI_InitStructure.EXTI_Line=EXTI_InitStructure.EXTI_Mode=EXTI_InitStructure.EXTI_Trigger=EXTI_InitStructure.EXTI_LineCmd=36.}38. *檢查是否有外部按鍵事件產(chǎn) 41.int42. intvalue=在函數(shù)EVB_KeyConfig()中,配置I/O為EXTI中斷主要有以下步驟在函數(shù)EVB_KeyConfig()中,配置I/O為EXTI中斷主要有以下步驟使能EXTIx線的時鐘和第二功能AFIORCC_APB2PeriphClockCmd()GPIOD時鐘和AFIOAFIO(alternate-functionI/OGPIOGPIOGPIO都有一個默認(rèn)復(fù)用功能。當(dāng)把GPIO用作EXTI外部中斷或使用重映射功能的時候,必須開啟AFIO時鐘,而在使用默認(rèn)復(fù)用功能的時候,就不必開啟AFIO時鐘了。配置EXTIx線的中斷優(yōu)通過調(diào)用NVIC_PriorityGroupConfig()庫函數(shù),把NVIC中斷優(yōu)先級分組設(shè)置為第1組。.NVIC_IRQChannel=EXTI15_10_IRQn表示要配置的為EXTI第10~15線的中斷向量。因為按鍵PD13對應(yīng)的EXTI線為EXTI13,而EXTI10~EXTI15線共同使用一個中斷向量的,所以只能寫入EXTI15_10_IRQn這個參數(shù)。GPIO_InitGPIODPin13EXTI_Line13PD13EXTI_Line13EXTI_ModeEXTI_Mode_Interrupt(EXTI_Trigge_FllingEXTI_LineCmdEXTI_LineCmd12/ if(EXTI_GetITStatus(EXTI_Line13)!= value= return52.)把EXTI設(shè)置中我們把)把EXTI設(shè)置中我們把PD13連接到內(nèi)部的EXTI13,GPIO配置為上拉輸入,工作在下降沿中斷。在外圍電路上我PD13接到KEY上。當(dāng)按鍵沒有按下時,PD13始終為高,當(dāng)按函數(shù)EVB_KeyScan()用來檢測是否真的有中斷產(chǎn)生,進(jìn)入中斷后,調(diào)用庫函數(shù)EXTI_GetITStatus()來重新檢查是否產(chǎn)生了EXTI_Line中斷,如果是則調(diào)用2.2.32-3開發(fā)板串口stm32f10x_rcc.c、stm32f10x_usart.c。下面我們實際來編寫UARTBSP驅(qū)動代碼。2-5uart13/#include#include#include#include14/14/ GPIO_InitTypeDef/*configUSART1clockRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,/*USART1GPIOconfig*//*ConfigureUSART1Tx(PA.09)asalternatefunctionpush-pullGPIO_InitStructure.GPIO_Pin=GPIO_InitStructure.GPIO_Mode=GPIO_InitStructure.GPIO_Speed=/*ConfigureUSART1Rx(PA.10)asinputfloatingGPIO_InitStructure.GPIO_Pin=GPIO_InitStructure.GPIO_Mode=/*USART1modeconfigUSART_InitStructure.USART_BaudRate=USART_InitStructure.USART_WordLength=USART_InitStructure.USART_StopBits=USART_InitStructure.USART_Parity= USART_InitStructure.USART_Mode=USART_Mode_Rx| USART_Cmd(USART1, *1發(fā)送一個字函數(shù)EVB_Uart1Config()主要做了如下工函數(shù)EVB_Uart1Config()主要做了如下工作1配置usart1的I/Ousart1115200、81件流控制。即1152008-N-1。候,要開啟相應(yīng)的功能時鐘USART1。PA9和PA10用作串TxRx。Tx為發(fā)送端,輸出引腳,而且GPIO是使用復(fù)用功.USART_BaudRate=分頻因子。在這里把串口的波特率設(shè)置為115200.USART_WordLength=815/ voidEVB_Uart1SendByte(int while(!(USART1->SR USART1->DR=(ch *從串口1接收一個字 voidEVB_Uart1GetByte(char* while(!(USART1->SR *c=((int)(USART1->DR .USART_StopBits=1.USART_Parity=USART_Parity_NoUSART_Mode=USART_Mode_Rx|數(shù)USART_Cmd()來使能USART1外設(shè)。2.32-文件.USART_StopBits=1.USART_Parity=USART_Parity_NoUSART_Mode=USART_Mode_Rx|數(shù)USART_Cmd()來使能USART1外設(shè)。2.32-文件列表中,文件 是內(nèi)核的配置文件。在這個文件中,有很多內(nèi)核功能的宏開關(guān)16/目文功內(nèi)核timerAPI17/17/#ifndef#define/*內(nèi)核時鐘節(jié)拍配置,硬件定時器每秒中斷次數(shù)#define /*內(nèi)核調(diào)試功能使能配置#define #define #define #define #define #define #define #define #define #define #define #define #define /*內(nèi)核斷言功能使能配置#define #define #define #define #define #define #define #define #define #define #define #define #define #define /*供內(nèi)核調(diào)試和斷言功能使用的注釋#define #define #define #define 18/18/#define #define #define #define #define #define #define #define #define #define /*用戶線程優(yōu)先級范圍配置#define #define /*定時器功能使能配置#define #define /*IPC功能使能配置#define #define #define #define #define #define #define /*內(nèi)存管理使能配置#define /*中斷管理配置#define /*HOOK功能使能配置#define #define #endif/*_TOCHILI_CONFIG_Htcl.stm32f10x.a.asmtcl.stm32f10x.c就是我們在STM32處理器上tcl.stm32f10x.a.asmtcl.stm32f10x.c就是我們在STM32處理器上移植內(nèi)核的具體實現(xiàn),前者是用匯編實現(xiàn)的部分功能,后者則是C語言來實現(xiàn)的(因為編譯器會把同名PendSV中斷來將這個線程的上下文恢復(fù)到處理器,這樣就19/1.*功能線程棧和棧幀初始化函 *參數(shù):(1) 線程?;? (2) 線程棧頂?shù)? (3)pStack線程棧地 (4) 線程棧大小,以4字節(jié)為 (5)pEntry線程函數(shù)地 (6) 線程函數(shù)參 *返回: *說明線程堆棧起始地址必須4字節(jié)對 11.voiduCM3BuildThreadStack(TAddr*pBase,TAddr*pTopvoid* TWordsize,void*pEntry,void*14.*pBase=(TWord)pStack+pTemp=(TRegister*)(*pBase); /*偽造處理器中斷?,F(xiàn)場,在線程第一次被加載運(yùn)行時使用 *(pTemp)= /* *(--pTemp)= /*線程函 *(--pTemp)=(TRegister)0xFFFFFFFEU;/*R14 函功所在文cortexm3前面的章節(jié)中,沒有明確說明內(nèi)核在Cortexcortexm3前面的章節(jié)中,沒有明確說明內(nèi)核在CortexM3處理器上具體如何完成線程調(diào)度的。其實就是說,內(nèi)核發(fā)出的是線程調(diào)度請求,即觸發(fā)一次PendSV中斷,具體如何執(zhí)行還是要看涉及的技術(shù)細(xì)節(jié)特別多。PendSV中斷處理函數(shù)實現(xiàn)和注解如下:20/ ;Cortex-M3 進(jìn)入異常服務(wù)例程時,自動壓棧了R0-R3,R12,LR(R14,連接寄存器),PR(程序狀態(tài)寄存器)和;PSP不自動壓棧,不需要保存到棧中,而是保存到線程結(jié)構(gòu)函功所在文PendSV取消PendSV判斷PendSV設(shè)置PendSV *(--pTemp)=(TRegister)pData; /*線程參數(shù) 這幾個寄存器數(shù)值沒有什么意義,就算內(nèi)核的指紋吧 *(--pTemp)=(TRegister)0x00000054;/*R11 *(--pTemp)=(TRegister)0x00000052;/*R10 *(--pTemp)=(TRegister)0x0000004f;/*R9 *(--pTemp)=(TRegister)0x00000043;/*R8 *(--pTemp)=(TRegister)0x00000048;/*R7 *(--pTemp)=(TRegister)0x00000049;/*R6 *(--pTemp)=(TRegister)0x0000004c;/*R5 *(--pTemp)=(TRegister)0x00000049;/*R4,I *pTop=(TRegister)pTemp;42.21/21/;立刻關(guān)閉中 R0, ;保存r4- R0,R0, R0,{R4-;保存psp到線程結(jié) R1, R1, R0,使得uThreadCurrent R0, R1, R2, ;從uThreadCurrent中取得SP數(shù)值到R0 R0,[R2,#8] 從新線程棧中彈出r4- R0,{R4- ;psp指向中斷自動壓棧后的棧 R0,R0, ;上電后,處理器處于線程+特權(quán)模式+msp;對于第一次active任務(wù),當(dāng)引發(fā)pendsv中斷后,處理器進(jìn)入handler模式。使用;返回時,在這里準(zhǔn)備使用psp,從psp中彈出r0...這些寄存器所以需要修改LR,強(qiáng)制使用psp LR,LR,;開啟中 ;在這里有可能發(fā)生中斷,而此時新的當(dāng)前線程的上下文并沒有完全恢復(fù)。但和線程被中斷的情景相似:;硬件自動保存部分寄存器到線程棧中,其他寄存器還游離在處理器上下文中;假如在此時產(chǎn)生的中斷ISR中調(diào)用那些;(1)會將當(dāng)前線程從就緒隊列中移出的;(2)或者喚醒了更高優(yōu)先級的線程22/函 功 所在文 關(guān)閉處理中 打開處理器中 ;(3)調(diào)整當(dāng)前線程或者其他就緒線程的優(yōu)先;(4)系統(tǒng)定時器中斷,發(fā)生時間片輪;那么有可能導(dǎo)致一次新的PensSv請求被掛;當(dāng)下面的語句啟動異常返回流程時,會發(fā)生前后兩個 咬尾中斷;按照本函數(shù)流程,當(dāng)前線程的上下文中那些游離的寄存器會再次被保存到線程棧中,即不繼續(xù)彈棧,也就是;啟動異常返回流程,彈r0、r1、r2、r3寄存器,切換到任務(wù) 返回后,處理器使用線程+特權(quán)模式+psp。線程就在這種環(huán)境下運(yùn)行2.3.923/1.voidxKernelStart(void)2.{/*初始化內(nèi)核參數(shù)變量 SetSysTick(TCL_CPU_CLOCK_FREQ,SetPendSVPriority();}函功所在文函功所在文函功所在文24/24/uKernelVariable.InitialThread=(TThread*)NULL;#if/*HOOK函數(shù)初始化#if((TCL_HOOKS_ENABLE)&&/*初始化線程管理模塊/*定時器模塊初始 #if/*IDLE#ifuThreadNominee=uThreadCurrent=uKernelVariable.InitialThread;/*調(diào)用處理器初始化函數(shù)KNL_ASSERT((uKernelRoutine.CpuSetupEntry/*調(diào)用板級初始化函數(shù)KNL_ASSERT((uKernelRoutine.BoardSetupEntry /*調(diào)用用戶入口函數(shù),此時多線程機(jī)制尚未打開2525//*用戶應(yīng)用程序入口staticvoidEVB_LEDAppEntry(void) /*配置使能開發(fā)板上的LEDKEY設(shè)備/*設(shè)置和KEY相關(guān)的外部中斷向量/*初始化信號量TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_DUMMY);/*LED線程TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*激活LED線程21.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int25./*注冊處理器初始化函數(shù)到KNL_ASSERT((uKernelRoutine.UserMainEntry/*IDLE while 58.IDLEIDLE線程優(yōu)先級最低,所以TrochiliRTOSAPIIDLEIDLE線程優(yōu)先級最低,所以TrochiliRTOSAPI26//*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return42.3.1.1在下面的例子中,共有三個線程,線程ThreadLEDOn3.1.1在下面的例子中,共有三個線程,線程ThreadLEDOnLED設(shè)備開啟,線程在用戶初始化函數(shù)中,對這三個線程都進(jìn)行了初始化。但是只激活了ThreadCTRL。所以當(dāng)27//*LED設(shè)備參數(shù)#define #define /*用戶線程參數(shù)#define #define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程定義staticTThreadstaticTThread/*用戶線程堆棧staticTWordstaticTWord/*LEDOn while28/28/ EVB_LEDControl(LED_INDEX, /*LEDOff while EVB_LEDControl(LED_INDEX, /*CTRL while /*LED/*1秒/*LED/*LED/*1秒/*LED /*用戶應(yīng)用入口函數(shù)staticvoid /*LED2929//*LED/*LEDTclInitThread(&ThreadLEDOff,&ThreadLEDOffEntry,/*CTRL/*CTRL線程 int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return 下面的代碼演示了內(nèi)核中線程掛起和解掛功能,程序首先定義了2個應(yīng)用線程,一個下面的代碼演示了內(nèi)核中線程掛起和解掛功能,程序首先定義了2個應(yīng)用線程,一個實現(xiàn)LED燈按照1s的間隔(不是很精準(zhǔn))點亮和熄滅。程序代碼如下30//*LED設(shè)備參數(shù)#define #define /*創(chuàng)建線程時需要的參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #define #define /*用戶線程定義staticTThreadstaticTThread/*用戶線程棧定義staticTWordstaticTWord /*LED31/31/ EVB_LEDControl(LED_INDEX, /*LED while EVB_LEDControl(LED_INDEX, /*主控線程的主函數(shù) /*LED while /*LED點亮線程/*1秒/*LED點亮線程/*LED熄滅線程/*1秒/*LED熄滅線程 32/32/ /*用戶應(yīng)用入口函數(shù)staticvoid /*LED/*LED/*LEDTclInitThread(&ThreadLEDOff,&ThreadLEDOffEntry,/*CTRL/*LED點亮線程/*LED熄滅線程/*激活主控線程 int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核LED的3.1.3LED的3.1.3使得LED燈作出點亮-熄滅的閃爍效果。下面是具體代碼33//*LED設(shè)備參數(shù)#define #define /*創(chuàng)建線程時需要的參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define /*線程定義staticTThread/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return 34/34//*線程棧定義/*LED線程的線程函數(shù) while EVB_LEDControl(LED_INDEX,EVB_LEDControl(LED_INDEX, /*用戶應(yīng)用入口函數(shù)staticvoid /*LED/*LED/*LED int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核我們以COLIBRI開發(fā)板為例,下面我們以COLIBRI開發(fā)板為例,下面的代碼演示了如何使用該API。我們的目標(biāo)是在開35//*LED設(shè)備參數(shù)#define #define /*創(chuàng)建線程時需要的參數(shù)#defineTHREAD_LED_STACK_SIZE/*啟動內(nèi)核 return 36/36/#define #define /*線程定義staticTThreadstaticTThread/*線程棧定義staticTWord/*線程做無用操作,起到空轉(zhuǎn)效果 /*LEDOn while EVB_LEDControl(LED_INDEX, /*LEDOff while EVB_LEDControl(LED_INDEX, /*用戶應(yīng)用入口函數(shù)staticvoid /*LED37/37//*LED/*LEDTclInitThread(&ThreadLEDOff,&ThreadLEDOffEntry,/*LED/*LED int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return .538//*LED設(shè)備參數(shù)#define #define /*創(chuàng)建線程時需要的參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define /*線程定義staticTThreadstaticTThread/*線程棧定義staticTWord/*線程做無用操作,起到空轉(zhuǎn)效果 while(count-- /*LED139/39/ TByteturn=while EVB_LEDControl(LED_INDEX1,EVB_LEDControl(LED_INDEX1,turnif(turn== turn= /*LED2 TByteturn=while EVB_LEDControl(LED_INDEX2,EVB_LEDControl(LED_INDEX2,turnif(turn== turn= /*用戶應(yīng)用入口函數(shù)staticvoid /*LED /*LED140/40//*LED2THREAD_LED_PRIORITY+1,THREAD_LED_SLICE);/*LED1/*LED2 int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return109.}.6發(fā)板上通過三個獨(dú)立線程的時間片的變動,來實現(xiàn)LED亮/暗的不同占空比。41//*LED設(shè)備參數(shù)#define #define /*創(chuàng)建線程時需要的參數(shù)#define #define #define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*線程定義staticTThreadstaticTThread/*線程棧定義staticTWordstaticTWord/*LEDOn42/42/ while EVB_LEDControl(LED_INDEX, /*LEDOff while EVB_LEDControl(LED_INDEX, /*CTRL staticTTimerTickslice=while TclSetThreadSlice(&ThreadLEDOn,if(slice< slice+= slice= /*用戶應(yīng)用入口函數(shù)staticvoid /*LED/*CTRL43/43//*LED/*LEDTclInitThread(&ThreadLEDOff,&ThreadLEDOffEntry,/*CTRL線程/*LED/*LED int /*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return116.3.2LED3.2LED燈的點亮和熄在本例中,我們通過兩個線程的同步配合,實現(xiàn)LED1秒的間隔點亮和熄滅。其中1秒;LED線程則不停的以阻塞方式嘗試獲得信號量,第一次得到信號量后就點亮LED,然后等待下次得到信號量后就關(guān)閉LED,循環(huán)往復(fù)44/#include#include 信號量取消初始 支 支 信號量釋 支 支 信號量獲 支 支 線程阻塞終 支 支 信號量查 支 支45/45//*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義staticTWord/*用戶線程定義staticTThread/*用戶信號量定義/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*27.TErrnoTStatewhile /*LED線程以阻塞方式獲取信號量,得到后點亮LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if(state== EVB_LEDControl(LED1, /*LED線程以阻塞方式獲取信號量,得到后熄滅LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if(state== EVB_LEDControl(LED1, 46.}46/46//*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*51.TErrnowhile /*1/*主控線程釋放信TclReleaseSemaphore(&LedSemaphore,0,0, 61.}/*用戶應(yīng)用入口函數(shù)staticvoid66. /*配置使能評估板上的LED/*初始化信號量TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程90.}程序運(yùn)行后,LED程序運(yùn)行后,LED的變化如下圖所LED1,最后以非阻塞方式釋放信號量1,最后以阻塞方式獲得信號量2;LED線程2的執(zhí)行也依賴于LED線程1,因為它們的運(yùn)行都依賴于某個信號量的操作。47//*處理器BOOT之后會調(diào)用main函數(shù),必須提供int95./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return112.48/48/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define /*用戶線程棧定義staticTWord/*用戶線程定義staticTThread/*用戶信號量定義staticTSemaphore/*LED線程1的主函數(shù)staticvoidThreadLED1Entry(void*23. while /*LED線程1以阻塞方式獲取信號量1,如果成功就點亮TclObtainSemaphore(&LedSemaphore1,IPC_OPT_WAIT,0,/*LED線程11秒后關(guān)閉LED1TclDelayThread(uThreadCurrent,/*LED線程1以非阻塞方式釋放信2TclReleaseSemaphore(&LedSemaphore2,IPC_OPT_NONE,0, 39.}/*LED線程2的主函數(shù)staticvoidThreadLED2Entry(void*43.49/49/ while /*LED線程2點亮LED2/*LED線程21秒后關(guān)閉LED2TclDelayThread(uThreadCurrent,/*LED線程2以非阻塞方式釋放信1TclReleaseSemaphore(&LedSemaphore1,IPC_OPT_NONE,0,&errno);TclObtainSemaphore(&LedSemaphore2,IPC_OPT_WAIT,0, 61.}/*用戶應(yīng)用入口函數(shù)staticvoid66. /*配置使能評估板上的LED/*初始化信號量TclInitSemaphore(&LedSemaphore1,0,1,IPC_PROP_NONE,TclInitSemaphore(&LedSemaphore2,0,1,IPC_PROP_NONE,&errno);TclInitThread(&ThreadLED1,&ThreadLED1Entry,ThreadLED1Stack,TclInitThread(&ThreadLED2,&ThreadLED2Entry,ThreadLED2Stack,THREAD_LED_PRIORITY+1,THREAD_LED_SLICE);/*激活LED1ISRISRISR不能被阻塞,線程可以等待ISR不會等待信號量,也就不存在同步的問題。從實際應(yīng)用的角度講,ISR是ISR之50//*激活LED291.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int95./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return1個信號量。LED1個信號量。LED直接以ISR模式釋放信號量,然后退出。51/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義/*用戶線程定義/*用戶信號量定義/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*24.TErrnoTStatewhile /*LED線程以阻塞方式獲取信號量,如果成功則點亮LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if(state== EVB_LEDControl(LED1, /*LED線程以阻塞方式獲取信號量,如果成功則熄滅LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if(state== EVB_LEDControl(LED1,52/52/ 43.}/*評估板按鍵中斷處理函數(shù)staticvoidEVB_KeyISR(TVectorvector,TWord47. if /*KeyISR以非阻塞方式(必須)釋放信號量 53.}/*用戶應(yīng)用程序入口staticvoid57. /*配置使能評估板上的LEDKEY設(shè)備/*設(shè)置和KEY相關(guān)的外部中斷向量TclSetIntVector(KEY_INT_VECTOR,&EVB_KeyISR,0);/*初始化信號量TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE,&errno);/*LED線程TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*激活LED線程77.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int81./*注冊處理器初始化函數(shù)到.4因為時間片調(diào)度機(jī)制,如果沒有任何保護(hù)的話,2個線程在向串口發(fā)送字符串時,很可能還53/#include#include #defineTHREAD_SYNC_ENABLE/*用戶線程參數(shù)#defineTHREAD_UART_STACK_SIZE#define #define /*用戶線程棧定義staticTWord15./*用戶線程定義/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return98.}54/54/staticTThread/*用戶信號量定義/*字符打印函數(shù),通過BSP將字符串輸出到評估板的串口staticvoidPrintfString(char*24.TErrno/*當(dāng)前線程以阻塞方式獲取信號量,成功后通過BSP打印字符串#ifstate=TclObtainSemaphore(&UartSemaphore,IPC_OPT_WAIT,0,if(state== /*字符串完全打印后,當(dāng)前線程以非阻塞方式釋放信號量TclReleaseSemaphore(&UartSemaphore,0,0,errno=state=42.}/*打印大寫字符串線程的主staticvoidThreadUartLowCaseEntry(void*46. while 51.}/*打印小寫字符串線程的主staticvoidThreadUartUpCaseEntry(void*55. while 55/55/60.}/*用戶應(yīng)用程序入口{ /*初始化信號量TclInitSemaphore(&UartSemaphore,1,1,IPC_PROP_NONE,&errno);/*初始化UART設(shè)備控制線TclInitThread(&ThreadUartLowCase,&ThreadUartLowCaseEntry,ThreadUartLowCaseStack,/*初始化UART設(shè)備控制線TclInitThread(&ThreadUartUpCase,&ThreadUartUpCaseEntry,ThreadUartUpCaseStack,/*激活UART小寫線程/*激活UART大寫線程87.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int91./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核56//*啟動內(nèi)核 return108.LED線程的線程函數(shù)相似,都是以阻塞方式等待某個信號量(去獲LED線程的線程函數(shù)相似,都是以阻塞方式等待某個信號量(去獲57/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義staticTWordstaticTWordstaticTWord/*用戶線程定義staticTThreadstaticTThreadstaticTThread/*用戶信號量定義/*LED線程1的主函數(shù)staticvoidThreadLED1Entry(void*31.TErrnoTStatewhile /*LED1以阻塞方式獲取信號量,如果Flush則點亮對應(yīng)的LED58/58/state=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, /*LED1以阻塞方式獲取信號量,如果Flush則熄滅對應(yīng)的LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, 50.}/*LED線程2的主函數(shù)staticvoidThreadLED2Entry(void*54.TErrnoTStatewhile /*LED1以阻塞方式獲取信號量,如果Flush則點亮對應(yīng)的LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED2, /*LED1以阻塞方式獲取信號量,如果Flush則熄滅對應(yīng)的LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED2, 73.}/*LED線程3的主函數(shù)staticvoidThreadLED3Entry(void*77.TErrnoTStatewhile59/59/ /*LED1以阻塞方式獲取信號量,如果Flush則點亮對應(yīng)的LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED3, /*LED1以阻塞方式獲取信號量,如果Flush則熄滅對應(yīng)的LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED3, 96.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*101.TErrnowhile /*控制線程延時1秒后FLUSH信號量的線程阻塞隊列TclDelayThread(uThreadCurrent,TclFlushSemaphore(&LedSemaphore, /*用戶應(yīng)用入口函數(shù)staticvoid114. /*配置使能評估板上的LED/*初始化信號量TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED1,&ThreadLED1Entry,60/60/ThreadLED1Stack,/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED2,&ThreadLED2Entry,ThreadLED2Stack,/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED3,&ThreadLED3Entry,ThreadLED3Stack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int155./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核 /*啟動內(nèi)核程序運(yùn)行后,LED的變化如下程序運(yùn)行后,LED的變化如下圖所61/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義staticTWord/*用戶線程定義staticTThreadstaticTThread return172.62/62//*用戶信號量定義/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*26.TErrnoTStatewhile /*LED線程以阻塞方式獲取信號量,如果阻塞被強(qiáng)制解除則點亮LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, /*LED線程以阻塞方式獲取信號量,如果阻塞被強(qiáng)制解除則熄滅LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, 45.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*49.TErrnowhile /*1秒后強(qiáng)制解除LED線程的阻塞TclDelayThread(uThreadCurrent,TclAbortSemaphore(&LedSemaphore,&ThreadLED, 57.}/*用戶應(yīng)用程序入口staticvoid62. TErrno63/63//*配置使能評估板上的LED/*初始化信號量TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程85.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int89./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return106.程序運(yùn)行后,LED的變程序運(yùn)行后,LED的變化如下圖所64/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義staticTWord/*用戶線程定義staticTThread/*用戶信號量定義staticTSemaphore65/65//*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*26.TErrno while /*LED線程以阻塞方式獲取信號量,如果信號量被重置則點亮LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, /*LED線程以阻塞方式獲取信號量,如果信號量被重置則熄滅LEDstate=TclObtainSemaphore(&LedSemaphore,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, 46.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*50.TErrnowhile /*主控1秒后重TclDelayThread(uThreadCurrent,TclDeintSemaphore(&LedSemaphore,TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE, 59.}/*用戶應(yīng)用入口函數(shù)staticvoid64. /*配置使能評估板上的LED程序運(yùn)行后,程序運(yùn)行后,LED的變化如下圖所66/ TclInitSemaphore(&LedSemaphore,0,1,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程87.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int91./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return108.3.3點亮線程則不停的以阻塞方式嘗試獲取互斥量,得到互斥量后點亮LED13.3點亮線程則不停的以阻塞方式嘗試獲取互斥量,得到互斥量后點亮LED1秒后再釋67/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define /*用戶線程定義staticTThread/*用戶線程棧定義staticTWordstaticTWord 取消互斥量初始 支 支 互斥量獲 支 不支 互斥量釋 支 不支 線程阻塞終 支 支 68/68//*用戶互斥量定義/*LED點亮線程的主函數(shù)staticvoidThreadLEDOnEntry(void*22.TErrnoTStatewhile /*LED點亮線程以阻塞方式鎖定互斥量,如果成功則點亮LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if(state== /*LED點亮線程延時1秒/*LED點亮線程釋放互斥量TclFreeMutex(&LedMutex, 40.}/*LED熄滅線程的主函數(shù)staticvoidThreadLEDOffEntry(void*44.TErrno while /*LED熄滅線程以阻塞方式鎖定互斥量,如果成功則熄滅LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if(state== /*LED熄滅線程延時1秒 /*LED熄滅線程釋放互斥量69/69/ TclFreeMutex(&LedMutex, 63.}/*用戶應(yīng)用入口函數(shù)staticvoid67. /*配置使能評估板上的LED/*初始化互斥量TclInitMutex(&LedMutex,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLEDOn,&ThreadLEDOnEntry,ThreadLEDOnStack,/*初始化LED設(shè)備控制線TclInitThread(&ThreadLEDOff,&ThreadLEDOffEntry,ThreadLEDOffStack,THREAD_LED_PRIORITY+1,THREAD_LED_SLICE);/*激活LED點亮線程/*激活LED熄滅線程91.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int95./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到程序運(yùn)行后,LED的變化如下程序運(yùn)行后,LED的變化如下圖所程序?qū)?0/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程棧定義staticTThread/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return112.71/71//*用戶線程棧定義staticTWord/*用戶互斥量定義/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*26.TErrno while /*LED線程以阻塞方式獲取互斥量,被強(qiáng)制解除阻塞后點亮LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, /*LED線程以阻塞方式獲取互斥量,被強(qiáng)制解除阻塞后熄滅LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED1, 46.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*50. /*主控線程以阻塞方式獲取互斥量TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,while /*1秒后強(qiáng)制解除LED線程的阻塞TclDelayThread(&ThreadCTRL,TclAbortMutex(&LedMutex,&ThreadLED, 72/72/61.}/*用戶應(yīng)用程序入口staticvoid66. /*配置使能評估板上的LED/*初始化互斥量TclInitMutex(&LedMutex,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED設(shè)備控制線程/*激活主控線程90.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int95./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到程序運(yùn)行后,LED的變化程序運(yùn)行后,LED的變化如下圖所3.3.3結(jié)果是eIpcFlush則點亮LED;然后再次以阻塞方式嘗試獲取互斥量,如果返回結(jié)果是73/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #define #define /*用戶線程定義staticTThreadstaticTThreadThreadCTRL;/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return112.74/74//*用戶線程棧定義staticTWordstaticTWordThreadCTRLStack[THREAD_CTRL_STACK_SIZE];/*用戶互斥量定義staticTMutexLedMutex;/*LED線程的主函數(shù)26. TStatewhile state=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& state=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& /*主控線程的主函數(shù)51. /*主控線程首先獲取互斥量while TclDelayThread(&ThreadCTRL,TclFlushMutex(&LedMutex,75/75/ /*用戶應(yīng)用入口函數(shù)staticvoid67. /*板級初始化函數(shù)/*LED/*初始化信號量TclInitMutex(&LedMutex,IPC_PROP_NONE,&errno);/*LED/*CTRL線程/*LED線程/*激活主控線程int98./*注冊處理器初始化函數(shù)到內(nèi)核/*注冊板級初始化函數(shù)到內(nèi)核程序運(yùn)行后,LED的變化程序運(yùn)行后,LED的變化如下圖所3.3.4在本例中,兩個線程通過的互斥量的操作實現(xiàn)LED按照1秒的間隔點亮和熄滅。其中LED1sDeinit操作,然后重新初76/#include#include/*LED設(shè)備參數(shù)#define #define #defineLED_INDEX/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define /*注冊板級調(diào)試打印函數(shù)到內(nèi)核/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return115.77/77/#defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程定義staticTThread/*用戶線程棧定義staticTWord/*用戶互斥量定義/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*31.TErrnoTStatewhile /*LED線程以阻塞方式獲取互斥量,當(dāng)發(fā)現(xiàn)互斥量重置后點亮LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED_INDEX, /*LED線程以阻塞方式獲取互斥量,當(dāng)發(fā)現(xiàn)互斥量重置后熄滅LEDstate=TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,if((state!=eSuccess)&&(errno& EVB_LEDControl(LED_INDEX, 50.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*55. 78/78/ while /*主控線程初始化互斥量,然后提前獲得互斥量TclInitMutex(&LedMutex,IPC_PROP_NONE,TclLockMutex(&LedMutex,IPC_OPT_WAIT,0,&errno);/*主控線1秒,此后LED線程才得到運(yùn)行機(jī)會/*主控線程重置互TclDeinitMutex(&LedMutex, 70.}/*用戶應(yīng)用入口函數(shù)staticvoid75./*配置使能評估板上的LED/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程94.}/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int98./*注冊處理器初始化函數(shù)到程序運(yùn)行后,LED的變化如下圖所程序運(yùn)行后,LED的變化如下圖所79/函數(shù) 函數(shù)功 線程調(diào) ISR調(diào) 郵箱取消初始 支 支 接收郵 支 支 /*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return117.從而實現(xiàn)LED從而實現(xiàn)LED按照1秒的間隔點亮和熄滅。其中主控線程不停的以非阻塞方式發(fā)送郵件,每1秒;LED線程則不停的以阻塞方式嘗試接收郵件,然后根據(jù)郵件的內(nèi)容,即LED控制命令來點亮或者熄滅LED,循環(huán)往復(fù)。在這個例程里,LED80/#include#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #define #defineTHREAD_CTRL_STACK_SIZE#define #define /*用戶線程定義staticTThread/*用戶線程棧定義staticTWord/*用戶郵件類型定義typedef24.TIndexTByte/*用戶郵箱和郵件定義staticTMailBox/*LED線程的主函數(shù)staticvoidThreadLEDEntry(void*36.TErrnoTState81/81/ while state=TclReceiveMail(&LEDMailbox,IPC_OPT_WAIT,0,if(state== EVB_LEDControl(pMail->Index,pMail- 50.}/*主控線程的主函數(shù)staticvoidThreadCTRLEntry(void*54.TErrnoTLEDMail*pMail=&LEDMail; while /*控制線程通過郵箱發(fā)送LED點亮郵件,采用非阻塞方式發(fā)送LEDMail.Index=pMail->Value=TclSendMail(&LEDMailbox,IPC_OPT_WAIT,0,&errno);/*1/*控制線程通過郵箱發(fā)送LED熄滅郵件,采用非阻塞方式發(fā)送LEDMail.Index=pMail->Value=TclSendMail(&LEDMailbox,(TMail*)(&pMail),IPC_OPT_WAIT,0,&errno);/*1TclDelayThread(uThreadCurrent, 77.}/*用戶應(yīng)用程序入口staticvoid81. TErrno82/82//*配置使能評估板上的LED TclInitMailBox(&LEDMailbox,IPC_PROP_NONE,&errno);/*初始化LED設(shè)備控制線TclInitThread(&ThreadLED,&ThreadLEDEntry,ThreadLEDStack,/*CTRL線程TclInitThread(&ThreadCTRL,&ThreadCTRLEntry,ThreadCTRLStack,/*激活LED線程/*激活主控線程/*處理器BOOT之后會調(diào)用main函數(shù),必須提供int109./*注冊處理器初始化函數(shù)到/*注冊板級初始化函數(shù)到內(nèi)核/*注冊板級調(diào)試打印函數(shù)到/*注冊用戶初始化函數(shù)到內(nèi)核/*啟動內(nèi)核 return126.程序運(yùn)行后,LED程序運(yùn)行后,LED的變化如下圖所在本例中郵件被定義為LED的控制命令。然后一個LED線程從郵箱中接收郵件,郵件的內(nèi)容決定LED的點亮或者熄滅。用戶通過外部按鍵中斷來激活KeyISR,ISR中,會交替發(fā)送LED點亮和熄滅的郵件,從而實現(xiàn)LED按照用戶按鍵的操作點亮和熄滅。在這個例程里,LEDKeyISR的數(shù)據(jù)傳輸是單向的,并且是異步的。LED83/#include#include#if(EVB_EXAMPLE==#include/*用戶線程參數(shù)#defineTHREAD_LED_STACK_SIZE#define #def

溫馨提示

  • 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論