




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第1章嵌入式基礎(chǔ)知識(shí)1.1思政作業(yè):閱讀嵌入式系統(tǒng)發(fā)展歷史文獻(xiàn),了解嵌入式系統(tǒng)的發(fā)展歷程及其對(duì)社會(huì)進(jìn)步和科技發(fā)展的貢獻(xiàn),撰寫(xiě)一篇閱讀報(bào)告,其中報(bào)告格式不限,字?jǐn)?shù)不少于800字。答:回答合理即可1.2簡(jiǎn)述嵌入式系統(tǒng)國(guó)內(nèi)定義及國(guó)際定義。答:國(guó)際定義:用于控制、監(jiān)視或者輔助操作機(jī)器和設(shè)備的裝置。該定義是從應(yīng)用上考慮的,嵌入式系統(tǒng)是軟件和硬件的綜合體,還可以涵蓋機(jī)電等附屬裝置,只要是一個(gè)專用的工控系統(tǒng)都可以認(rèn)為是嵌入式系統(tǒng)。國(guó)內(nèi)定義:在國(guó)內(nèi),將嵌入式系統(tǒng)的一般定義是:是以應(yīng)用為中心,通過(guò)軟硬件裁減,適應(yīng)對(duì)功能、可靠性、成本、體積、功耗等要求的專用計(jì)算機(jī)系統(tǒng)。1.3簡(jiǎn)述ARM公司與芯片廠家的關(guān)系。答:ARM公司本身不進(jìn)行具體芯片生產(chǎn),它只負(fù)責(zé)設(shè)計(jì)處理器的構(gòu)架,即處理器最核心的部件,然后把這個(gè)核心部件技術(shù)授權(quán)給全球各大半導(dǎo)體廠家,芯片廠家在這個(gè)核心部件基礎(chǔ)上增加上外圍設(shè)備設(shè)計(jì)成具有特定功能的處理器,再賣給設(shè)備廠家。1.4簡(jiǎn)述STM32F40x最小系統(tǒng)包括哪幾部分電路。答:在結(jié)構(gòu)上由片內(nèi)/片上外設(shè)、板上外設(shè)構(gòu)成,在電路上由芯片、電源電路、復(fù)位電路、振蕩電路、啟動(dòng)電路組成。1.5舉例描述嵌入式系統(tǒng)的應(yīng)用領(lǐng)域。答:嵌入式系統(tǒng)幾乎包括了生活中的所有電器設(shè)備,如掌上PDA、移動(dòng)工控設(shè)備、電視機(jī)頂盒、手機(jī)、數(shù)字電視、多媒體、汽車導(dǎo)航儀、微波爐、數(shù)字相機(jī)、電梯控制器、空調(diào)控制器、安全控制系統(tǒng)、自動(dòng)售貨機(jī)、消費(fèi)電子設(shè)備、工業(yè)儀表與醫(yī)療儀器等。1.6總結(jié)馮·諾依曼體系結(jié)構(gòu)和哈佛結(jié)構(gòu)的特點(diǎn)。答:馮·諾依曼結(jié)構(gòu):把程序本身當(dāng)作數(shù)據(jù)來(lái)對(duì)待,程序和該程序處理的數(shù)據(jù)用同樣的方式存儲(chǔ),該結(jié)構(gòu)的主要特點(diǎn):?jiǎn)我淮鎯?chǔ)、統(tǒng)一編址、分時(shí)復(fù)用。哈佛結(jié)構(gòu):使用兩個(gè)獨(dú)立的存儲(chǔ)器模塊,分別存儲(chǔ)指令和數(shù)據(jù),每個(gè)存儲(chǔ)模塊都不允許指令和數(shù)據(jù)并存;使用獨(dú)立的兩條總線,分別作為CPU與每個(gè)存儲(chǔ)器之間的專用通信路徑,而這兩條總線之間毫無(wú)關(guān)聯(lián),也就是該結(jié)構(gòu)分開(kāi)存儲(chǔ)、獨(dú)立編址、兩倍帶寬、效率更高。第2章Keil開(kāi)發(fā)環(huán)境及調(diào)試方法2.1完成STM32F4的KEILARMMDK5開(kāi)發(fā)集成開(kāi)發(fā)環(huán)境的安裝。答:自選根據(jù)書(shū)本介紹,動(dòng)手實(shí)際安裝操作。2.2使用MDK5創(chuàng)建一個(gè)基本STM32F407工程,并且編寫(xiě)一個(gè)基本的main函數(shù)。答:請(qǐng)根據(jù)STM32F407軟件開(kāi)發(fā)環(huán)境搭建.pdf步驟完成。2.3擴(kuò)展:請(qǐng)自選查閱資料,理解CMSIS的含義及常用的規(guī)范說(shuō)明。答:CMSIS(CortexMicrocontrollerSoftwareInterfaceStandard),翻譯過(guò)來(lái)是ARMCortex?微控制器軟件接口標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)是ARM跟芯片廠商共同提出的,是為了不同芯片廠商生產(chǎn)的Cortex-M0/M3/M4芯片能在軟件上基本兼容,各芯片廠商只需要按照該標(biāo)準(zhǔn)實(shí)現(xiàn)自家芯片外設(shè)驅(qū)動(dòng)程序,就是兼容CMSIS標(biāo)準(zhǔn)的。CMSIS在規(guī)范內(nèi)容很多,比如系統(tǒng)函數(shù)的命名、芯片初始化啟動(dòng)流程等,如STM32的標(biāo)準(zhǔn)庫(kù)、HAL庫(kù)、LL庫(kù)驅(qū)動(dòng)程序就是根據(jù)該標(biāo)準(zhǔn)寫(xiě)的。關(guān)于CMSIS官方設(shè)備的框架結(jié)構(gòu)如下圖所示:
STM32F40x外設(shè)原理及控制方法3.1使用寄存器配置方式,如何使能端口F的硬件?答:查詢芯片手冊(cè)的外設(shè)時(shí)鐘寄存器可以知道F口在AHB1ENR寄存器的第5位,因此,只需要把RCC_AHB1ENR寄存器第5位設(shè)置為1即可:RCC->AHB1ENR|=1<<5;3.2使用寄存器配置方式,如何配置PF10為輸出模式、PE13為輸入模式?答: //開(kāi)GGPF口時(shí)鐘 RCC->AHB1ENR|=1<<5; //配置GPF10:01通用輸出模式 GPIOF->MODER&=~(3<<10*2);//對(duì)應(yīng)的兩位分別清0 GPIOF->MODER|=(1<<10*2);//對(duì)應(yīng)的兩位分別設(shè)置為01 //配置默認(rèn)輸出高電平 GPIOF->ODR|=1<<10; //開(kāi)GPE,口時(shí)鐘 RCC->AHB1ENR|=1<<4; //配置GPF10:00輸入模式 GPIOE->MODER&=~(3<<13*2);//對(duì)應(yīng)的兩位分別清0 //配置為:01:上拉--可選 GPIOE->PUPDR&=~(3<<13*2);//對(duì)應(yīng)的兩位分別清0 GPIOE->PUPDR|=(1<<13*2);//對(duì)應(yīng)的兩位分別設(shè)置為013.3使用寄存器配置方式,編寫(xiě)引腳電平輸出控制函數(shù)。答:/**********************************************************************函數(shù)名:gpio_x_output_ctrl*功能描述:控制指定引腳輸出電平*作者:ZhifaChen*參數(shù)說(shuō)明:gpio_obj:GPIO地址,如GPIOA,GPIOA,;*pin_num:本組引腳號(hào);value:1或0*返回值:無(wú)*修改記錄:無(wú)*其他:**********************************************************************/voidgpio_x_output_ctrl(GPIO_TypeDef*gpio_obj,intpin_num,intvalue){if(value){gpio_obj->ODR|=(1<<pin_num);//輸出高電平}else{gpio_obj->ODR&=~(1<<pin_num);//輸出低電平}}3.4使用寄存器配置方式,編寫(xiě)讀取輸入引腳電平的函數(shù)。答:/**********************************************************************函數(shù)名:gpio_x_read_pin*功能描述:讀取指定GPIO引腳電平*作者:ZhifaChen*參數(shù)說(shuō)明:gpio_obj:GPIO地址,如GPIOA,GPIOA,;*pin_num:本組引腳號(hào);*返回值:1:高電平,0低電平*修改記錄:無(wú)*其他:**********************************************************************/intgpio_x_read_pin(GPIO_TypeDef*gpio_obj,intpin_num){ //!!是把非1變成1,0還是0,因?yàn)橐粋€(gè)引腳值一定是0或1 return!!(gpio_obj->IDR&(1<<pin_num));}3.5使用寄存器配置方式,根據(jù)圖3.80原理圖,實(shí)現(xiàn)跑馬燈功能。圖3.80LED電路圖答案見(jiàn):homework-ch3-3.5l-leds工程3.6使用寄存器配置方式,根據(jù)圖3.81,實(shí)現(xiàn)按鍵控制燈的亮、滅,每個(gè)按鍵控制一個(gè)LED燈,實(shí)現(xiàn)按一下亮、再按一下滅,如此循環(huán)。圖3.81LED電路圖答案見(jiàn):homework-ch3-3.6-button-leds工程3.7結(jié)合圖3.80和圖3.81,編程實(shí)現(xiàn)4個(gè)按鍵中斷,正確控制LED1~LED4的亮、滅。答案見(jiàn):homework-ch3-3.7-button-leds-interrupt工程3.8編程實(shí)現(xiàn)三個(gè)按鍵中斷不同的搶占優(yōu)先級(jí),且分別控制LED1~LED3,它們中斷搶占優(yōu)先級(jí)分別設(shè)置如下:按鍵1:搶占優(yōu)先級(jí)1按鍵2:搶占優(yōu)先級(jí)2按鍵3:搶占優(yōu)先級(jí)3①若輪流按下按鍵3>按鍵2>按鍵1,請(qǐng)說(shuō)明LED1~LED3的亮、滅現(xiàn)象。②若輪流按下按鍵1>按鍵2>按鍵3,請(qǐng)說(shuō)明LED1~LED3的亮、滅現(xiàn)象。答案見(jiàn):homework-ch3-3.8-button-leds-interrupt-nest工程說(shuō)明:1.代碼中在中斷服務(wù)程序是人為加入1.5S的延時(shí),是為了方便模擬中斷執(zhí)行沒(méi)完時(shí)按鍵其他按鍵可以看到是否能嵌套中斷的效果。2.現(xiàn)象是按下KEY1,在1.5S內(nèi)按鍵KEY2或KEY3,都不會(huì)馬上響應(yīng),而是等待KEY1中斷程序執(zhí)行完成,會(huì)響應(yīng)KEY2,KEY3,按下的中斷程序,也就是低優(yōu)先級(jí)不能嵌套高優(yōu)先級(jí)。反之,按下KEY3,在1.5S內(nèi)按鍵K2或K1,會(huì)馬上響應(yīng),而是不需要等待KEY3中斷程序執(zhí)行完成,就響應(yīng)KEY2/KEY1的中斷程序,會(huì)馬上響應(yīng)KEY1,KEY2,按下的中斷程序,也就是高優(yōu)先級(jí)可以嵌套高優(yōu)先級(jí)。其他順序分析方法如上面一樣,請(qǐng)自選寫(xiě)。3.9描述串口數(shù)據(jù)幀中的起始位、數(shù)據(jù)位、停止位的作用。起始位:一幀數(shù)據(jù)中,用1個(gè)低電平位來(lái)表示通信的開(kāi)始;數(shù)據(jù)位:長(zhǎng)度是5~8位,通常是一個(gè)字節(jié)有效數(shù)據(jù),用來(lái)存放一幀要傳輸?shù)挠行?shù)據(jù)。停止位:傳輸一幀數(shù)據(jù)后停止1位或1.5位傳輸?shù)臅r(shí)間長(zhǎng)度,用于消除異步通信會(huì)產(chǎn)生的時(shí)間積累誤差,或者說(shuō)重新同步新的一幀數(shù)據(jù)傳輸,這樣才可以確保長(zhǎng)時(shí)間通信數(shù)據(jù)傳輸?shù)恼_性。3.10編程實(shí)現(xiàn)串口中斷,正確控制LED1~LED4的亮、滅,要求如下:①接收到數(shù)據(jù)0x00,則LED1點(diǎn)亮;接收到數(shù)據(jù)0xF0,則LED1熄滅?、诮邮盏綌?shù)據(jù)0x01,則LED2點(diǎn)亮;接收到數(shù)據(jù)0xF1,則LED2熄滅?、劢邮盏綌?shù)據(jù)0x02,則LED3點(diǎn)亮;接收到數(shù)據(jù)0xF2,則LED3熄滅!④接收到數(shù)據(jù)0x03,則LED4點(diǎn)亮;接收到數(shù)據(jù)0xF3,則LED4熄滅!答案見(jiàn):homework-ch3-3.9-leds-uart工程3.11描述I2C的起始信號(hào)、應(yīng)答信號(hào)、停止信號(hào)的細(xì)節(jié)。答:起始信號(hào):SCL和SDA初始化為高電平,開(kāi)始通信時(shí)SCL高電平期間SDA由高變成低,其作用相當(dāng)于總線復(fù)位,通知所有I2C從機(jī)準(zhǔn)備開(kāi)始通信了。應(yīng)答信號(hào):在每個(gè)字節(jié)傳輸后緊跟著一個(gè)應(yīng)答位,即第9個(gè)時(shí)鐘SCL高電平期間,SDA是低電平表示應(yīng)答信號(hào),即告訴發(fā)送方數(shù)據(jù)已經(jīng)成功接收。停止信號(hào):當(dāng)主機(jī)不想通信了,停止通信的條件是SCL高電平期間SDA由低電平變成高電平,其作用是終止通信。3.12根據(jù)課本I2C時(shí)序圖,編寫(xiě)代碼,實(shí)現(xiàn)向AT24C02的連續(xù)寫(xiě)入與連續(xù)讀取。答案見(jiàn):homework-ch3-3.12-at24c02工程3.13結(jié)合DMA和UART章節(jié)內(nèi)容,編寫(xiě)代碼,實(shí)現(xiàn)串口1通過(guò)DMA方式發(fā)送數(shù)據(jù)。答案見(jiàn):homework-ch3-3.13-uart-dma-send工程3.14綜合應(yīng)用:結(jié)合定時(shí)器、UART實(shí)現(xiàn)程序運(yùn)行時(shí)間統(tǒng)計(jì)并且存儲(chǔ),以及通過(guò)UART與上位機(jī)通信修改存儲(chǔ)EEPROM中運(yùn)行時(shí)間。答案見(jiàn):homework-ch3-3.14-runtime-save-eeprom工程分析:在EEPROM讀寫(xiě)工程基本上增加上定時(shí)器示例代碼記錄機(jī)器運(yùn)行時(shí)間,需要考慮新機(jī)器第一次運(yùn)行時(shí)是沒(méi)有正確的時(shí)間記錄的,而EEPROM中的數(shù)值是無(wú)法確定的,因此程序設(shè)計(jì)需要能識(shí)別當(dāng)前是否是已經(jīng)設(shè)置過(guò)正確的運(yùn)行時(shí)間,如果沒(méi)有設(shè)置過(guò)運(yùn)行時(shí)間,則表示是新機(jī)器,此時(shí)設(shè)置運(yùn)行時(shí)間為0,更新到EEPROM中。解決方法是在EERPOM中增加一個(gè)初始化的標(biāo)志值,開(kāi)機(jī)先讀取標(biāo)志位置,判斷是否是正確的初始化標(biāo)志值,如果是,則表示不是新機(jī)器,讀取此時(shí)的運(yùn)行時(shí)間做當(dāng)前起始時(shí)間,否則運(yùn)行時(shí)間設(shè)置為0。為方便管理運(yùn)行時(shí)間和已初始化標(biāo)志,我們把他們?cè)O(shè)定為一個(gè)結(jié)構(gòu)體,并且規(guī)定初始化標(biāo)志值,代碼片段如下所示:#defineRUNTIME_HAVE_INIT_VALUE0x12345678//已經(jīng)初始化過(guò)的標(biāo)志值typedefstructruntime_data{u32second;//運(yùn)行運(yùn)行時(shí)間u32have_init;//是否是初始化了}runtime_data_t;定義時(shí)間存放變量和存儲(chǔ)地址,代碼片段如下所示#defineRUN_TIME_POS0x10//存放運(yùn)行參數(shù)位置runtime_data_tg_runtime;//運(yùn)行運(yùn)行時(shí)間編寫(xiě)更新運(yùn)行時(shí)間和讀取時(shí)間函數(shù),調(diào)用AT24C02實(shí)現(xiàn)的讀寫(xiě)函數(shù)即可/**********************************************************************函數(shù)名:update_runtime*功能描述:更新運(yùn)行時(shí)間到EEPROM*作者:ZhifaChen*參數(shù)說(shuō)明:無(wú)*返回值:無(wú)*修改記錄:無(wú)*其他:;**********************************************************************/voidupdate_runtime(runtime_data_trtime){AT24C02_PageWrite(0xa0,RUN_TIME_POS,(u8*)&rtime,sizeof(runtime_data_t));}/**********************************************************************函數(shù)名:read_runtime*功能描述:從EEPROM讀取運(yùn)行時(shí)間*作者:ZhifaChen*參數(shù)說(shuō)明:無(wú)*返回值:無(wú)*修改記錄:無(wú)*其他:;**********************************************************************/intread_runtime(runtime_data_t*rtime){intret;ret=AT24C02_ReadBytes(0xa0,RUN_TIME_POS,(u8*)rtime,sizeof(runtime_data_t));returnret;}在定時(shí)器中斷程序中1秒中增加1,用來(lái)做運(yùn)行時(shí)間統(tǒng)計(jì)//定時(shí)器6中斷服務(wù)程序voidTIM6_DAC_IRQHandler(void){//由于定時(shí)器6和DAC模塊共用一個(gè)中斷入口地址,因此也共用一個(gè)中斷服務(wù)程序//這里先判斷是否是屬于定時(shí)器6產(chǎn)生的中斷,如果是再反轉(zhuǎn)LED燈if(TIM6->SR&(1<<0)){TIM6->SR&=~(1<<0);//清標(biāo)志g_second++;}}在主程序中每5秒保存一次運(yùn)行時(shí)間到EEPROM//每10秒保存一次運(yùn)行時(shí)間,每秒保存頻率太高,容易損壞EEPROMif(g_second-g_second_pre>=5){g_second_pre=g_second;g_runtime.second+=5;//當(dāng)前時(shí)間加5秒update_runtime(g_runtime);//寫(xiě)入EEPROM,更新時(shí)間}再根據(jù)UART控制LED燈亮滅的示例增加串口命令來(lái)修改EEPROM中的運(yùn)行時(shí)間,本示例有兩個(gè)清0運(yùn)行時(shí)間和設(shè)置運(yùn)行時(shí)間兩條指令:#defineCMD_RUN_TIME_CLR"RTM_CLR"http://清除運(yùn)行時(shí)間//設(shè)置運(yùn)行時(shí)間命令后面跟時(shí)間,單位秒,如RTM_SET123表示設(shè)置運(yùn)行時(shí)間是123秒#defineCMD_RUN_TIME_SET"RTM_SET"解析代碼片段://判斷命令是否合法,合法,則執(zhí)行命令if(!strncmp((char*)uart_recv_buf,CMD_RUN_TIME_CLR,strlen(CMD_RUN_TIME_CLR))){g_runtime.second=0;//清除運(yùn)行時(shí)間update_runtime(g_runtime);//寫(xiě)入EEPROM,更新時(shí)間}elseif(!strncmp((char*)uart_recv_buf,CMD_RUN_TIME_SET,strlen(CMD_RUN_TIME_SET))){//命令示例:RTM_SET123g_runtime.second=atoi((char*)&uart_recv_buf[7]);//提示時(shí)間值數(shù)據(jù)update_runtime(g_runtime);//寫(xiě)入EEPROM,更新時(shí)間}μC/OS-III實(shí)時(shí)操作系統(tǒng)原理及實(shí)踐4.1基于μC/OS-III,編寫(xiě)一個(gè)任務(wù),實(shí)現(xiàn)跑馬燈。答:分析說(shuō)明:在本節(jié)基礎(chǔ)ucOS示例代碼基礎(chǔ)上進(jìn)行修改,增加LED任務(wù)代碼即可。把裸機(jī)編寫(xiě)的LED代碼添加到工作當(dāng)中在main.c定義新增加的LED任務(wù)的相關(guān)變量,函數(shù)聲明,優(yōu)先級(jí)定義#defineTASK_LED_PRIO6//任務(wù)優(yōu)先級(jí)#defineTASK_LED_STK_SIZE128//任務(wù)堆棧大小OS_TCBtask_led_tcb;//任務(wù)控制塊CPU_STKtask_led_stk[TASK_LED_STK_SIZE];//任務(wù)堆棧voidtask_led_task(void*p_arg);//任務(wù)函數(shù)在start_task函數(shù)中增加一個(gè)任務(wù)創(chuàng)建,創(chuàng)建led任務(wù)//創(chuàng)建TaskLed任務(wù)OSTaskCreate((OS_TCB*)&task_led_tcb,//任務(wù)控制塊(CPU_CHAR*)"Taskled",//任務(wù)名字(OS_TASK_PTR)task_led_task,//任務(wù)函數(shù)(void*)0,//傳遞給任務(wù)函數(shù)的參數(shù)(OS_PRIO)TASK_LED_PRIO,//任務(wù)優(yōu)先級(jí)(CPU_STK*)&task_led_stk[0],//任務(wù)堆?;刂?CPU_STK_SIZE)TASK_LED_STK_SIZE/10,//任務(wù)堆棧深度限位(CPU_STK_SIZE)TASK_LED_STK_SIZE,//任務(wù)堆棧大小(OS_MSG_QTY)0,//任務(wù)內(nèi)部消息隊(duì)列能夠接收的最大消息數(shù)目,為0時(shí)禁止接收消息(OS_TICK)0,//當(dāng)使能時(shí)間片輪轉(zhuǎn)時(shí)的時(shí)間片長(zhǎng)度,為0時(shí)為默認(rèn)長(zhǎng)度,(void*)0,//用戶補(bǔ)充的存儲(chǔ)區(qū)(OS_OPT)OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,//任務(wù)選項(xiàng)(OS_ERR*)&err);//存放該函數(shù)錯(cuò)誤時(shí)的返回值編寫(xiě)led任務(wù)代碼,在其中編寫(xiě)流水燈程序//taskled任務(wù)函數(shù)voidtask_led_task(void*p_arg){u8task1_num=0;OS_ERRerr;CPU_SR_ALLOC();p_arg=p_arg;while(1){gpio_x_output_ctrl(LED1_GPIO,LED1_PIN,LED_ON);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED2_GPIO,LED2_PIN,LED_ON);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED3_GPIO,LED3_PIN,LED_ON);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED4_GPIO,LED4_PIN,LED_ON);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED1_GPIO,LED1_PIN,LED_OFF);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED2_GPIO,LED2_PIN,LED_OFF);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED3_GPIO,LED3_PIN,LED_OFF);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5sgpio_x_output_ctrl(LED4_GPIO,LED4_PIN,LED_OFF);OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_HMSM_STRICT,&err);//延時(shí)0.5s}}完整工程,見(jiàn):homework-ch4-4.1-ucos-leds4.2基于μC/OS-III,編寫(xiě)一個(gè)任務(wù)管理LED亮、滅,一個(gè)任務(wù)用于識(shí)別按鍵狀態(tài),這兩個(gè)任務(wù)配合實(shí)現(xiàn)按鍵控制LED的亮、滅。答:分析說(shuō)明:上一個(gè)示例代碼基礎(chǔ)上進(jìn)行修改:創(chuàng)建一個(gè)消息隊(duì)列,在按鍵任務(wù)中檢測(cè)到有按鍵按下是把按鍵值放入消息隊(duì)列中修改LED任務(wù):從消息隊(duì)列中讀取消息,轉(zhuǎn)換成按鍵值,根據(jù)按鍵值控制不同的LED燈新增加KEY任務(wù):每20ms掃描一次按鍵狀態(tài),如檢測(cè)到有按鍵按下發(fā)送到消息隊(duì)列完整工程,見(jiàn):homework-ch4-4.2-ucos-button-led4.3基于μC/OS-III,多任務(wù)利用互斥鎖實(shí)現(xiàn)串口發(fā)送數(shù)據(jù)的函數(shù)。答:分析說(shuō)明:裸機(jī)的串口多字節(jié)發(fā)送在任務(wù)中使用,有可能在發(fā)送數(shù)據(jù)過(guò)程中被高優(yōu)先級(jí)的任務(wù)搶占,而高優(yōu)先級(jí)任務(wù)里又調(diào)用了串口發(fā)送函數(shù),這樣就會(huì)存在沖突,導(dǎo)致低優(yōu)先級(jí)的數(shù)據(jù)沒(méi)有輸送完成就被高優(yōu)先級(jí)任務(wù)搶占。解決方法,只需要把串口函數(shù)使用互斥信號(hào)量進(jìn)行封裝一層即可。定義互斥信號(hào)量OS_MUTEXuart_debug_mutex;//定義一個(gè)互斥信號(hào)量在start_task任務(wù)中創(chuàng)建互斥信號(hào)量//創(chuàng)建一個(gè)互斥信號(hào)量OSMutexCreate((OS_MUTEX*)&uart_debug_mutex,(CPU_CHAR*)"uart_debug_mutex",(OS_ERR*)&err); 封裝串口發(fā)送函數(shù)/**********************************************************************函數(shù)名:os_uart_send_data*功能描述:加了互斥信號(hào)量保保護(hù)的串口發(fā)送函數(shù),可以防止任務(wù)搶占導(dǎo)致的數(shù)據(jù)混亂*作者:*參數(shù)說(shuō)明:無(wú)*返回值:無(wú)*修改記錄:無(wú)*其他:;**********************************************************************/intos_uart_send_data(u8*data,u16num){ OS_ERRerr; OSMutexPend(&uart_debug_mutex,0,OS_OPT_PEND_BLOCKING,0,&err);//請(qǐng)求互斥信號(hào)量 uart_send_bytes(data,num);//這里是你自己的多字節(jié)發(fā)送函數(shù),根據(jù)實(shí)際情況替換即可 OSMutexPost(&uart_debug_mutex,OS_OPT_POST_NONE,&err);//釋放互斥信號(hào)量}完整工程,見(jiàn):homework-ch4-4.3-ucos-mutex-uart4.4基于μC/OS-III,串口接收到的數(shù)據(jù)包通過(guò)消息隊(duì)列發(fā)送給任務(wù)處理。數(shù)據(jù)包如下:點(diǎn)亮LED1:”led-1-1#”熄滅LED1:”led-1-0#”點(diǎn)亮LED2:”led-2-1#”熄滅LED2:”led-2-0#”點(diǎn)亮LED3:”led-3-1#”熄滅LED3:”led-3-0#”點(diǎn)亮LED4:”led-4-1#”熄滅LED4:”led-4-0#”答:分析說(shuō)明:在main.c中定義一個(gè)消息隊(duì)列存放串口消息//消息隊(duì)列定義#defineUART_MSG_Q_NUM8//串口消息隊(duì)列的數(shù)量OS_Quart_data_msg;//定義一個(gè)消息隊(duì)列, 在start_task任務(wù)中創(chuàng)建消息隊(duì)列//創(chuàng)建消息隊(duì)列uart_data_msgOSQCreate((OS_Q*)&uart_data_msg,//消息隊(duì)列指針(CPU_CHAR*)"uart_data_msg",//消息隊(duì)列名稱,自定義(OS_MSG_QTY)UART_MSG_Q_NUM,//消息隊(duì)列長(zhǎng)度,(OS_ERR*)&err);//存放錯(cuò)誤碼由于串口收到的數(shù)據(jù)長(zhǎng)度可能不相同,收到后是放到消息隊(duì)列中,延后處理的,因此需要記錄實(shí)際數(shù)據(jù),為方便處理,我們可以定義一個(gè)結(jié)構(gòu)體來(lái)存放收到數(shù)據(jù)長(zhǎng)度,收到的數(shù)據(jù),然后把該結(jié)構(gòu)存數(shù)據(jù)包放入消息隊(duì)列中,延后處理就可以很方便取出數(shù)據(jù)長(zhǎng)度。在usart.h中添加以下結(jié)構(gòu)定義://定義串口消息結(jié)構(gòu),用來(lái)往消息隊(duì)列中存放typedefstruct{ u8data_len;//有效數(shù)據(jù)長(zhǎng)度 u8data[128];//存放數(shù)據(jù)緩沖區(qū)}uart_data_t;main.c中創(chuàng)建串口處理任務(wù),負(fù)責(zé)讀取隊(duì)列上的數(shù)據(jù),并且進(jìn)行解析,控制LED,任務(wù)函數(shù)如下://讀取UART隊(duì)列上的數(shù)據(jù)來(lái)處理,根據(jù)處理結(jié)果控制LEDvoidtask_uart(void*p_arg){u8task1_num=0;OS_ERRerr;uart_data_t*msg_data;OS_MSG_SIZEsize;p_arg=p_arg;while(1){ //讀取按鍵任務(wù)發(fā)來(lái)的消息 msg_data=OSQPend((OS_Q*)&uart_data_msg, (OS_TICK)0, (OS_OPT)OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE*)&size, (CPU_TS*)0, (OS_ERR*)&err); if(!strncmp("led-1-1#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED1_GPIO,LED1_PIN,LED_ON); }elseif(!strncmp("led-1-0#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED1_GPIO,LED1_PIN,LED_OFF); }elseif(!strncmp("led-2-1#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED2_GPIO,LED2_PIN,LED_ON); }elseif(!strncmp("led-2-0#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED2_GPIO,LED2_PIN,LED_OFF); }elseif(!strncmp("led-3-1#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED3_GPIO,LED3_PIN,LED_ON); }elseif(!strncmp("led-3-0#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED3_GPIO,LED3_PIN,LED_OFF); }elseif(!strncmp("led-4-1#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED4_GPIO,LED4_PIN,LED_ON); }elseif(!strncmp("led-4-0#",(char*)msg_data->data,msg_data->data_len)){ gpio_x_output_ctrl(LED4_GPIO,LED4_PIN,LED_OFF); } //回發(fā)給電腦顯示收到的結(jié)果 os_uart_send_data(msg_data->data,msg_data->data_len); }}在串口中斷服務(wù)中,當(dāng)接收到完整一幀數(shù)據(jù)后,封裝成數(shù)據(jù)包發(fā)送到消息隊(duì)列上即可,本示例是在串口的空閑中斷位置增加代碼,如下:#defineUART_DATA_ARR_SIZE8//定義8個(gè)元素uart_data_tuart_data_arr[UART_DATA_ARR_SIZE];//定義全局的消息隊(duì)列數(shù)據(jù)包存放空間,u8uapos_cur=0;//用來(lái)指示當(dāng)前使用的空閑位置voidUSART2_IRQHandler(void)//如果你使用UART1就是USART1_IRQHandler{省略//位4IDLE:檢測(cè)到空閑線路(IDLElinedetected)if(s&1<<4){省略u(píng)art2_recv_buf[index++%UART2_BUF_LEN]='\0';//添加接收字符串的結(jié)束標(biāo)志index=0;//清接收計(jì)數(shù)器 //復(fù)制數(shù)據(jù)到緩沖區(qū)中 memcpy(&uart_data_arr[uapos_cur].data,uart2_recv_buf,uart2_recv_cnt+1); uart_data_arr[uapos_cur].data_len= uart2_recv_cnt+1; //發(fā)送當(dāng)前數(shù)據(jù)到隊(duì)列中 externOS_Quart_data_msg;//聲明外部消息隊(duì)列 u8err; OSQPost((OS_Q*)&uart_data_msg, (void*)&uart_data_arr[uapos_cur], (OS_MSG_SIZE)sizeof(uart_data_t), (OS_OPT)OS_OPT_POST_FIFO, (OS_ERR*)&err); uapos_cur++; uapos_cur%=UART_DATA_ARR_SIZE;//更新下一個(gè)存儲(chǔ)位置 }}完整工程,見(jiàn):homework-ch4-4.4-ucos-uart-ledsFATFS文件系統(tǒng)移植FATFS到STM32F407ZGT6。答:省略說(shuō)明:請(qǐng)根書(shū)本描述完成文件系統(tǒng)移植操作,此處省略。使用FATFS的文件操作API實(shí)現(xiàn)創(chuàng)建目錄、文件復(fù)制、刪除文件、修改文件內(nèi)容、重命名文件。答:創(chuàng)建目錄復(fù)制文件#defineREAD_BUF_SIZE1024*4//定義緩沖區(qū)大小u8cpbuf[READ_BUF_SIZE];//定義緩沖區(qū)u8mf_copy(u8*psrc,u8*pdst){u8retry=0,res;u16br=0,bw=0;u8*fbuf=0;FIL_fsrc,_fdst;FIL*fsrc=&_fsrc,*fdst=&_fdst;fbuf=cpbuf;//復(fù)制數(shù)據(jù)臨時(shí)緩沖區(qū)//打開(kāi)源文件,如果文件不存在就出錯(cuò)res=f_open(fsrc,(constTCHAR*)psrc,FA_READ|FA_OPEN_EXISTING);if(res!=FR_OK){gotoout;}//以創(chuàng)建新文件形式打開(kāi)一個(gè)文件,即新文件res=f_open(fdst,(constTCHAR*)pdst,FA_WRITE|FA_CREATE_ALWAYS);if(res!=FR_OK){gotoout;}//循環(huán)從源文件中復(fù)制數(shù)據(jù)寫(xiě)入到新文件中while(res==FR_OK)//開(kāi)始復(fù)制{br=0;res=f_read(fsrc,fbuf,READ_BUF_SIZE,(UINT*)&br);//源頭讀出4096字節(jié)if(res!=FR_OK){gotoout;}//文件完成了退出循環(huán)if(!br){break;}res=f_write(fdst,fbuf,(UINT)br,(UINT*)&bw);//寫(xiě)入目的文件if(res||bw<br){gotoout;}}out:f_close(fdst);//closefilefdstf_close(fsrc);//closefilefsrcreturnres;}刪除文件:調(diào)用f_unlink函數(shù)即可刪除文件u8res=f_unlink(file_name);//刪除文件修改文件:以讀寫(xiě)方式打開(kāi)文件,然后讀取內(nèi)容出來(lái)到內(nèi)存中,修改內(nèi)存中的數(shù)據(jù)再回寫(xiě)即可,值得注意的是,回寫(xiě)數(shù)據(jù)前應(yīng)該先f(wàn)_lseek把讀寫(xiě)指令調(diào)整到文件開(kāi)頭。#defineREAD_BUF_SIZE1024*4//定義緩沖區(qū)大小u8cpbuf[READ_BUF_SIZE];//定義緩沖區(qū)u8modify_file_test(void){u8retry=0,res;u16br=0,bw=0;u8*fbuf=0;FIL_fsrc,_fdst;FIL*fsrc=&_fsrc;fbuf=cpbuf;//復(fù)制數(shù)據(jù)臨時(shí)緩沖區(qū)#defineFILE_NAME"1.txt"http://要修改的文件 //打開(kāi)源文件,如果文件不存在就出錯(cuò)res=f_open(fsrc,(constTCHAR*)FILE_NAME,FA_READ|FA_WRITE|FA_OPEN_EXISTING);if(res!=FR_OK){gotoout;}//循環(huán)從源文件中復(fù)制數(shù)據(jù)寫(xiě)入到新文件中if(res==FR_OK)//開(kāi)始復(fù)制{br=0;res=f_read(fsrc,fbuf,READ_BUF_SIZE,(UINT*)&br);//源頭讀出4096字節(jié)if(res!=FR_OK){gotoout;} //把修改后的數(shù)據(jù)重新寫(xiě)入文件 //這里可以修改已經(jīng)讀取到fbuf中的數(shù)據(jù)了,以下把源數(shù)據(jù)6開(kāi)始數(shù)據(jù)進(jìn)行修改 strcpy((char*)&fbuf[6],"ABCDEFGHIJKLMN\r\n"); res=f_lseek(fsrc,0);//把文件讀寫(xiě)指針移動(dòng)到文件開(kāi)頭if(res){gotoout;} res=f_write(fsrc,fbuf,(UINT)br,(UINT*)&bw);//寫(xiě)入目的文件if(res||bw<br){gotoout;}}out:f_close(fsrc);//closefilefsrcreturnres;}重新命名文件:調(diào)用f_rename函數(shù)即可修改文件名u8res=f_rename("oldname.txt","newname.txt");編寫(xiě)程序?qū)崿F(xiàn)接收電腦串口助手發(fā)送來(lái)的文件,并且保存到SD卡中。答:分析:以本章移植好的文件系統(tǒng)工程{smt32f407-sdio-fatfs-demo2}為基本模板,修改UART接收代碼,以及main.c中增加中增加把UART收到的數(shù)據(jù)寫(xiě)入到文件中的代碼設(shè)計(jì)思路:文件可能很大,所以UART接收代碼需要做一點(diǎn)變動(dòng),即收到不能一次性接收完成所有文件數(shù)據(jù)再一次性寫(xiě)入,這樣對(duì)RAM要求很大,解決方法是UART使用兩個(gè)接收緩沖區(qū),一個(gè)用來(lái)接收實(shí)時(shí)UART字節(jié)數(shù)據(jù),一個(gè)是存放等待寫(xiě)入文件的數(shù)據(jù)緩沖區(qū)。即接收到一定數(shù)量,如512字節(jié)后就把接收緩沖區(qū)1數(shù)據(jù)復(fù)制到接收緩沖2,并且記錄實(shí)際數(shù)據(jù)長(zhǎng)度,主程序判斷數(shù)據(jù)長(zhǎng)度大于0就把緩沖區(qū)2的數(shù)據(jù)寫(xiě)入到文件中。那文件發(fā)送完成一定是會(huì)進(jìn)入U(xiǎn)ART的空閑中斷里,因此,在空閑中斷中設(shè)置標(biāo)志,標(biāo)識(shí)這時(shí)候是文件的最后一筆數(shù)據(jù)即可。UART代碼關(guān)鍵部分://接收數(shù)據(jù)需要一個(gè)緩沖區(qū)存放u8uart1_recv_buf[UART1_BUF_LEN]={0};//定義接收緩沖區(qū)u8uart1_recv_buf2[UART1_BUF_LEN]={0};//定義接收緩沖區(qū)2uint32_tuart1_flag=0;//接收完成標(biāo)志uint32_tuart1_recv_index=0;//接收下標(biāo)計(jì)數(shù)器uint32_tuart1_recv_cnt=0;//本次要處理的數(shù)字字節(jié)數(shù)量//UART中斷服務(wù)程序voidUSART1_IRQHandler(void){uint32_ts;s=USART1->SR;//讀取狀態(tài)寄存器//位5RXNE:讀取數(shù)據(jù)寄存器不為空(Readdataregisternotempty)//收到一個(gè)數(shù)據(jù)產(chǎn)生一個(gè)中斷,讀取收到的數(shù)據(jù)存儲(chǔ)到接收緩沖區(qū)數(shù)組中if(s&1<<5){//清接收中斷標(biāo)志,請(qǐng)DR時(shí)候就清中斷標(biāo)志uart1_recv_buf[uart1_recv_index++]=USART1->DR;USART1->SR&=~(1<<5);//也可能手動(dòng)寫(xiě)0清0 //一次處理512字節(jié)數(shù)量 if(uart1_recv_index>=512){ uart1_recv_index-=512;//跳過(guò)已經(jīng)復(fù)制的數(shù)據(jù) uart1_recv_cnt=512;//本次復(fù)制512字節(jié)數(shù)據(jù) //復(fù)制到處理緩沖區(qū)等待寫(xiě)入sd卡 memcpy(uart1_recv_buf2,uart1_recv_buf,uart1_recv_cnt); }}//位4IDLE:檢測(cè)到空閑線路(IDLElinedetected)if(s&1<<4){//清空閑中斷標(biāo)志:該位由軟件序列清零(讀入U(xiǎn)SART_SR寄存器,然后讀入U(xiǎn)SART_DR寄存器)s=USART1->SR;//讀取狀態(tài)寄存器USART1->DR;//這樣就是讀,不接收結(jié)果uart1_recv_buf[uart1_recv_index]='\0';//添加接收字符串的結(jié)束標(biāo)志,可選的 uart1_recv_cnt=uart1_recv_index;//保存實(shí)際字節(jié)數(shù)量 uart1_recv_index=0;//清接收計(jì)數(shù)器 uart1_flag=1; //設(shè)置中斷處理標(biāo)志 //復(fù)制到處理緩沖區(qū)等待寫(xiě)入sd卡 memcpy(uart1_recv_buf2,uart1_recv_buf,uart1_recv_cnt);}}保存數(shù)據(jù)到文件的函數(shù) /********************************************************************* *函數(shù)名:gpio_x_read_pin *功能描述:把數(shù)據(jù)寫(xiě)入到文件中 *作者:ZhifaChen *參數(shù)說(shuō)明:fsrc:已經(jīng)打開(kāi)的文件結(jié)構(gòu)指針;data:要保存的數(shù)據(jù)指針; *num:本組引腳號(hào); *is_finish:是否是最后一筆數(shù)據(jù),1表示最后一筆數(shù)據(jù) *返回值:當(dāng)前寫(xiě)入的累積字節(jié)數(shù)量; *修改記錄:無(wú) *其他: **********************************************************************/ u32save_file_test(FIL*fsrc,u8*data,u16num,u8is_finish) { staticu32write_num=0; u8res=FR_OK; u16bw=0; u32size=write_num; write_num+=num; //累加原來(lái)寫(xiě)入的字節(jié) res=f_write(fsrc,data,(UINT)num,(UINT*)&bw);//寫(xiě)入目的文件 if(res||bw<num) { f_close(fsrc);//closefilefsrc } if(is_finish){ write_num=0;//最后一筆數(shù)字寫(xiě)入時(shí)清累計(jì)值 f_close(fsrc);//closefilefsrc } returnsize; }Main函數(shù)中關(guān)鍵代碼#defineFILE_NAME_MOD"uart-data.txt"http://保存的文件名intmain(void){原來(lái)的代碼省略 //打開(kāi)源文件,如果文件不存在就出錯(cuò) res=f_open(&fdst,(constTCHAR*)FILE_NAME_MOD,FA_READ|FA_WRITE|FA_CREATE_ALWAYS); if(res!=FR_OK) { printf("f_openerror\r\n"); Delay_ms(1000); } while(1) { //如果有數(shù)據(jù)來(lái)對(duì)執(zhí)行寫(xiě)入文件操作 if(uart1_recv_cnt) { save_file_test(&fdst,uart1_recv_buf2,uart1_recv_cnt,uart1_flag); uart1_recv_cnt=0; if(uart1_flag) { uart1_flag=0;//清接收完成標(biāo)志 f_close(&fdst);//關(guān)閉文件,這樣文件會(huì)全部寫(xiě)入sd卡 } } }}完整項(xiàng)目工程見(jiàn)homework-ch5-5.3-save-uart-data-to-file第6章分時(shí)操作系統(tǒng)Linux開(kāi)發(fā)環(huán)境6.1安裝虛擬機(jī)、Ubuntu。答:省略說(shuō)明:請(qǐng)根據(jù)配套完成PPT操作,此處省略。6.2配置Windows系統(tǒng)共享目錄。答:省略說(shuō)明:請(qǐng)根據(jù)配套完成PPT操作,此處省略。第7章Linux系統(tǒng)命令及Vim使用7.1在Ubuntu系統(tǒng)中使用命令創(chuàng)建用戶(用戶名為自己的姓名拼音)并附上詳細(xì)的創(chuàng)建過(guò)程與截圖。答:創(chuàng)建用戶完成后,就可以注銷,使用新用戶登陸了。說(shuō)明:sudouseradd-mxiaoming:表示創(chuàng)建新用戶xiaoming,并且自動(dòng)生成/home目錄下用戶家目錄sudopasswdxiaoming:表示修改新用戶密碼sudousermod-a-Gsudoxiaoming:表示把xiaoming用戶添加到sudo組中,后面該用戶才可以使用sudo提升權(quán)限。補(bǔ)充:在創(chuàng)建用戶時(shí)建議增加-s/bin/bash來(lái)指定用戶默認(rèn)shell,否則默認(rèn)shell可能不是bash,使用會(huì)不習(xí)慣,當(dāng)然可以通過(guò)后面修改,或動(dòng)態(tài)命令修改。7.2根據(jù)以下的步驟,使用命令補(bǔ)充對(duì)應(yīng)的內(nèi)容并附加截圖。示例:進(jìn)入根目錄 cd/①進(jìn)入Home目錄(注意:Home目錄必須對(duì)應(yīng)題1的用戶)②詳細(xì)顯示Home目錄下所有文件與文件夾③在當(dāng)前目錄下創(chuàng)建1.txt④升級(jí)系統(tǒng)(當(dāng)前系統(tǒng)必須正確聯(lián)網(wǎng),且源選用國(guó)內(nèi)阿里云,才能快速升級(jí)),顯示升級(jí)進(jìn)度即可。答:重啟Ubuntu系統(tǒng),使用上一步創(chuàng)建的新用戶登陸打開(kāi)命令終端,如果創(chuàng)建用戶時(shí)沒(méi)有指定默認(rèn)bash,則在命令中先選擇bash回車切換bashshell。以下開(kāi)始執(zhí)行題目要求:Linux系統(tǒng)應(yīng)用程序開(kāi)發(fā)基礎(chǔ)8.1C語(yǔ)言從源代碼到可執(zhí)行文件需要經(jīng)歷四個(gè)相互關(guān)聯(lián)的步驟。答:①預(yù)處理器將源文件中的宏進(jìn)行展開(kāi)還原;②編譯器gcc將c文件編譯成匯編文件;③匯編器as將匯編文件編譯成機(jī)器碼;④鏈接器將目標(biāo)文件和符號(hào)進(jìn)行鏈接,其中包括*.c生成的*.o、引導(dǎo)代碼、庫(kù)函數(shù)代碼,最終生成一個(gè)可執(zhí)行二進(jìn)制文件。8.2請(qǐng)寫(xiě)出Makefile文件格式。答:目標(biāo)1:依賴文件列表A#目標(biāo)名:依賴項(xiàng),其中目標(biāo)名自己定義TAB鍵命令#必須以tab鍵開(kāi)頭,然后寫(xiě)想要執(zhí)行的命令。目標(biāo)2:依賴文件列表B#目標(biāo)名:依賴項(xiàng),其中目標(biāo)名自己定義。TAB鍵命令#必須以tab鍵開(kāi)頭,然后寫(xiě)想要執(zhí)行的命令。目標(biāo)3:依賴文件列表C#目標(biāo)名:依賴項(xiàng),其中目標(biāo)名自己定義。TAB鍵命令#必須以tab鍵開(kāi)頭,然后寫(xiě)想要執(zhí)行的命令。8.3請(qǐng)總結(jié)出緩沖區(qū)I/O和非緩沖I/O的特點(diǎn)。答:(1)非緩沖I/O非緩存I/O是指對(duì)設(shè)備的讀寫(xiě)操作時(shí),數(shù)據(jù)在用戶空間中沒(méi)有緩沖區(qū),直接寫(xiě)入內(nèi)核空間緩沖區(qū)中。這類函數(shù)是Linux系統(tǒng)特有的文件I/O系統(tǒng)調(diào)用函數(shù),如read、write等,主要是針對(duì)數(shù)據(jù)實(shí)時(shí)性要求高的硬件設(shè)會(huì)采用非緩沖方式。(2)緩沖I/O對(duì)于緩沖I/O,在標(biāo)準(zhǔn)C庫(kù)里有一套專門的讀寫(xiě)函數(shù),如fread、fwrite等。應(yīng)用程序向硬盤寫(xiě)數(shù)據(jù),首先用戶將數(shù)據(jù)寫(xiě)入用戶空間的緩沖區(qū),等到緩沖區(qū)寫(xiě)滿或者調(diào)用fflush刷新緩沖才將數(shù)據(jù)寫(xiě)入內(nèi)核緩沖區(qū),再等到緩沖區(qū)寫(xiě)滿或者調(diào)用fsync函數(shù)強(qiáng)制刷新緩沖區(qū)才最后寫(xiě)入磁盤設(shè)備中。這種機(jī)制可以提高硬盤寫(xiě)入效率。8.4請(qǐng)寫(xiě)入統(tǒng)計(jì)1級(jí)深度目錄的所有文件大小,目錄名通過(guò)運(yùn)行程序時(shí)在命令行參數(shù)傳入。答:該題目實(shí)際就是考察目錄讀取函數(shù)readdir以及文件狀態(tài)函數(shù)stat的使用。代碼如下:#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<dirent.h>#include<sys/stat.h>intmain(intargc,char**argv){DIR*target_dir;structdirent*target_dir_info;if(argc<2){target_dir=opendir(".");//打開(kāi)當(dāng)前目錄}elseif(argc==2){target_dir=opendir(argv[1]);}else{printf("格式:%s目錄路徑\r\n",argv[0]);//打開(kāi)自定義目錄return0;}if(target_dir==NULL){perror("opendirerror!");//打開(kāi)目錄失敗return-1;}while((target_dir_info=readdir(target_dir))!=NULL){//只處理普通文件,不處理目錄if(target_dir_info->d_type==DT_REG){structstatsb;//讀取文件信息if(stat(target_dir_info->d_name,&sb)==-1){perror("staterror!!!");continue;} printf("%-40s%lldbytes\r\n",target_dir_info->d_name,(longlong)sb.st_size);}}return0;}完整工程,見(jiàn):homework-ch08-8.4-linux-io嵌入式LinuxRK3399開(kāi)發(fā)環(huán)境構(gòu)建9.1安裝GCC交叉編譯器、編譯U-Boot、編譯Linux內(nèi)核。答:省略說(shuō)明:請(qǐng)根據(jù)PPT完成交叉編譯器,U-boot,Linux內(nèi)核編譯。9.2燒錄U-boot、linux內(nèi)核和根文件系統(tǒng)到目標(biāo)板,并且使用串口終端登錄練習(xí)常用命令。答:省略說(shuō)明:請(qǐng)根據(jù)《01-RK3399開(kāi)發(fā)環(huán)境及系統(tǒng)燒寫(xiě)-note》完成系統(tǒng)固件下載,并且使用串口終端登陸開(kāi)發(fā)板上的Ubuntu系統(tǒng),按課本完成常用命令練習(xí)。嵌入式Linux系統(tǒng)驅(qū)動(dòng)程序設(shè)計(jì)10.1詳細(xì)描述主設(shè)備號(hào)、次設(shè)備號(hào)的用途。答:Linux系統(tǒng)字符設(shè)備和塊設(shè)備都有設(shè)備號(hào),設(shè)備號(hào)由主設(shè)備號(hào)和次設(shè)備號(hào)組成,主設(shè)備號(hào):在驅(qū)動(dòng)程序用來(lái)標(biāo)識(shí)一類設(shè)備次設(shè)備號(hào):在驅(qū)動(dòng)程序用來(lái)表示一類設(shè)備中具體哪一個(gè)設(shè)備比如,開(kāi)發(fā)板有5個(gè)串口設(shè)備,其設(shè)備文件的主設(shè)備號(hào)相同,而每個(gè)次設(shè)備號(hào)卻是不相同的,內(nèi)核就是通過(guò)主設(shè)備號(hào)和次設(shè)備號(hào)來(lái)找到驅(qū)動(dòng)程序正確操作具體的硬件設(shè)備。10.2寫(xiě)出初始化LED1、LED2、LED3、LED4對(duì)應(yīng)I/O引腳的驅(qū)動(dòng)代碼。答:分析說(shuō)明:假設(shè)LED1~LED4分別在GPIO0_B5,6,7,GPIO0_C0引腳上,我們可以仿照LED驅(qū)動(dòng)程序?qū)O口的使用方法寫(xiě)出初始化代碼。使用gpio_request申請(qǐng)gpio使用使用gpio_direction_output配置引腳為輸出方向代碼片段如下://定義led數(shù)據(jù)結(jié)構(gòu)structled_info{intid;//id,可選char*name;//名字,可選unsignedintgpio;//gpio編號(hào)};//實(shí)例化LED1~4使用到的GPIO引腳staticstructled_infoleds_data[]={{0,"led-0",8+5}/*GPIO0_B5*/{0,"led-0",8+6}/*GPIO0_B6*/{0,"led-0",8+7}/*GPIO0_B7*/{0,"led-0",8*2+0}/*GPIO0_C0,組偏移16*/ };//模塊初始化函數(shù)staticint__initxyd_rk3399_led_init(void){intret=0,i;for(i=0;i<ARRAY_SIZE(leds_data);i++){ret=gpio_request(leds_data[i].gpio,leds_data[i].name);//申請(qǐng)GPIOif(ret<0){printk("gpio_requesterror\n");gotoerror_gpio_request;}gpio_direction_output(leds_data[i].gpio,0);//配置為輸出方向,輸出低電平}其他無(wú)關(guān)代碼省略error_gpio_request:while(--i>=0){gpio_free(leds_data[i].gpio);}returnret;}10.3編寫(xiě)一個(gè)綜合應(yīng)用程序分別調(diào)用LED驅(qū)動(dòng)和按鍵驅(qū)動(dòng),實(shí)現(xiàn)按鍵控制LED燈亮滅。答:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<sys/ioctl.h>#include<sys/types.h>#include<errno.h>#include<poll.h>#include<sys/select.h>#include<sys/time.h>#include<sys/types.h>#include<unistd.h>//由于一個(gè)按鍵控制一個(gè)LED,因此定義的數(shù)量相同,//注意不能超過(guò)真實(shí)硬件LED和按鍵數(shù)量,同時(shí)還受你實(shí)現(xiàn)的驅(qū)動(dòng)程序限定的數(shù)量限制#defineBTN_SIZE1//按鍵數(shù)量#defineLED_NUMBTN_SIZE//LED燈數(shù)量//請(qǐng)根據(jù)自己編寫(xiě)的驅(qū)動(dòng)程序來(lái)修改#defineDEV_BTN"/dev/xyd-buttons"http://按鍵設(shè)備名#defineDEV_LED"/dev/xyd-leds"http://LED設(shè)備名intmain(intargc,char*argv[]){intfd_key,fd
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年互聯(lián)網(wǎng)信息審核員考試題庫(kù)及答案
- 2025年高考語(yǔ)文備考之名著閱讀整本書(shū)閱讀:《紅樓夢(mèng)》重要情節(jié)梳理
- 2025年帶貨直播考試題及答案
- 2025年中央紀(jì)委全會(huì)試題及答案
- 國(guó)辦公共數(shù)據(jù)資源開(kāi)發(fā)利用的意見(jiàn),描摹路徑
- 2025-2030年中國(guó)金屬絞接頂梁數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2025-2030年中國(guó)基站產(chǎn)品零部件數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 部編版一年級(jí)下冊(cè)語(yǔ)文試題 第五單元過(guò)關(guān)卷 (含答案)
- 語(yǔ)言學(xué)漢語(yǔ)古代文學(xué)試題及答案
- 北塔二中分班考數(shù)學(xué)試卷
- 2024解析:第十八章電功率-講核心(解析版)
- 測(cè)繪合同 GF-2000-0306規(guī)范
- 廣告品印刷行業(yè)發(fā)展概況及未來(lái)三年行業(yè)發(fā)展趨勢(shì)預(yù)測(cè)
- 電力建設(shè)項(xiàng)目檔案管理
- 招商及運(yùn)營(yíng)培訓(xùn)課件
- 學(xué)校校園花崗巖鋪設(shè)合同
- 2024年新疆區(qū)公務(wù)員錄用考試《行測(cè)》真題及答案解析
- 老年精神病的藥物護(hù)理
- 南京信息工程大學(xué)《流體力學(xué)Ⅰ》2022-2023學(xué)年第一學(xué)期期末試卷
- 英文在職證明模版
- 大學(xué)生職業(yè)素養(yǎng)訓(xùn)練(第六版)課件 第十二單元養(yǎng)成友善品格
評(píng)論
0/150
提交評(píng)論