版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
《通信嵌入式系統(tǒng)應用》實驗與程序設計教程戴虹編計算機與信息工程學院2023年6月目錄上篇Linux操作系統(tǒng)程序設計實驗一Linux下C語言編程入門實驗二Linux編程初步實驗三進程和進程間通信(1)實驗四進程間通信(2)與多線程程序設計實驗五網絡程序設計下篇基于ICETEK-AM3359-A的通信嵌入式系統(tǒng)實驗實驗一LED控制實驗實驗二按鍵控制實驗實驗三驅動模塊編寫實驗實驗四GPIO控制實驗實驗五內存設備模塊應用實驗實驗六LCD顯示實驗實驗七觸摸屏編程實驗實驗八Qt編程實驗參考文獻上篇Linux操作系統(tǒng)程序設計實驗一Linux下C語言編程入門實驗目的1.掌握在Linux下利用gcc編譯器編譯C語言程序。2.掌握利用Gdb調試器對C語言程序進行調試。2.掌握makefile文件編寫方法,對C語言程序進行編譯。二、實驗環(huán)境1.PC機2.虛擬機軟件:VMware3.Ubuntu10.04Linux操作系統(tǒng)(安裝在虛擬機上)三、實驗內容1.利用gcc編譯器編譯C語言程序(1)利用gcc編輯C語言程序啟動虛擬機,輸入密碼:1,打開終端,輸入:gedithello.c,從而打開了gedit編輯器:在gedit編輯器中輸入hello.c的源代碼(書p53):#include<stdio.h>main(){printf("helloworld!\n");}再回到終端界面。預處理(p53)輸入:gcc–Ehello.c–ohello.i實驗要求:在終端輸入:ls,顯示畫面:在gedit中讀取hello.i的內容,并顯示畫面:問:預處理的作用是什么?編譯(p53)輸入:gcc–Shello.i–ohello.s實驗要求:(1)在終端輸入:ls,顯示畫面:(2)在gedit中讀取hello.s的內容,并顯示畫面:(3)問:編譯的作用是什么?匯編(p54)輸入:gcc–chello.s–ohello.o實驗要求:(1)在終端輸入:ls,顯示畫面:(2)問:匯編的作用是什么?鏈接和運行(p55)輸入:gcchello.o–ohello實驗要求:(1)在終端輸入:ls,顯示畫面:(2)問:鏈接的作用是什么?(3)運行可執(zhí)行文件:hello,(命令:./hello)顯示結果畫面:2.利用Gdb調試器對C語言程序進行調試(1)gdb基本操作在命令行上鍵入gdb并按回車鍵,顯示出現(xiàn)的畫面:下表列出了利用GDB調試時會用到的一些命令。命令 命令描述break 在代碼里設置斷點,這將使程序執(zhí)行到這里時被掛起file 裝入想要調試的司可執(zhí)行文件kill 終止正在調試的程序list 列出產生執(zhí)行文件的源代碼的——部分make 使在退出gdb時就可以重新產生可執(zhí)行文件next 執(zhí)行—行源代碼但小進入函數(shù)內部print 顯示表達式的值quit 終止gdbrub 執(zhí)行當前被調試的程序shell 使能不離開gdb就執(zhí)行shell命令step 執(zhí)行一行源代碼而且進入函數(shù)內部watch 監(jiān)視一個變量的值而不管它何時被改變(2)利用gdb調試C語言程序[1](p30-31)調試test.c在gedit中輸入以下程序代碼:#include<stdio.h>intmain(){ charstr1[16]="Hello,world"; charstr2[16]; inti=0; for(i=0;i<16;i++) str2[i]='*'; str2[15]=0; i=0; while(str1[i]!='\0') { str2[i]=str1[i]; i++; } printf("Thestring1is:%s.\n",str1); printf("Thestring2is:%s.\n",str2); return0; } 實驗要求:(1)對test.c這個源程序進行編譯,編譯和執(zhí)行命令如下:gcc–g–otesttest.c./test顯示結果畫面:(2)在GDB命令輸入行輸入以下命令來調試該程序:#gdbtest再輸入:list,顯示畫面:(3)接下來要對程序中可能會出錯的地方設置斷點,設置斷點的方法如下,斷點設置在第16行,然后用run命令運行程序,顯示結果畫面:(gdb)break16(gdb)run(4)繼續(xù)調試程序:1)現(xiàn)在我們來看看到底str2的內容與str1的有何不同,顯示結果畫面:(gdb)printstr1(gdb)pstr22)上面我們用print命令(也可以簡寫成p)來分別顯示str1字符串和str2字符串的內容,可以發(fā)現(xiàn):str1字符串在最后一個字母d后面是字符串結束符0(用\000表示的),而str2的d后面仍然是*,這是因為程序少復制了一個字符所致。下面用next單步執(zhí)行命令查看程序輸出結果,再用continue命令繼續(xù)運行直到程序結束再退出GDB,顯示結果畫面:(gdb)next(gdb)n(gdb)continue(gdb)quit3)現(xiàn)在我們發(fā)現(xiàn)了程序的問題所在,將test.c的第11行和第15行修改一下:#include<stdio.h>intmain(){charstr1[]="Hello,world";charstr2[11]="";inti=0;do{str2[i]=str1[i];i++;}while(str1[i-1]!='\0');printf("Thestring1is:%s.\n",str1);printf("Thestring2is:%s.\n",str2);return0;}重新編譯運行,顯示結果畫面。*[2]采用同樣的方法調試p58)的test1.c程序,調試過程見p58-61),顯示調試過程中的各個結果畫面:
/*test.c*/#include<stdio.h>intsum(intm);intmain(){inti,n=0;sum(50);for(i=1;i<=50;i++)n+=i;printf("Thesumof1-50is%d\n",n);}intsum(intm){inti,n=0;for(i=1;i<=m;i++)n+=i;printf("Thesumof1-mis%d\n",n);}*參考資料:在保存退出后首先使用Gcc對test.c進行編譯,注意一定要加上選項“-g”,這樣編譯出的可執(zhí)行代碼中才包含調試信息,否則之后Gdb無法載入該可執(zhí)行文件。#gcc-gtest.c-otest雖然這段程序沒有錯誤,但調試完全正確的程序可以更加了解Gdb的使用流程。接下來就啟動Gdb進行調試。注意,Gdb進行調試的是可執(zhí)行文件,而不是如“.c”的源代碼,因此,需要先通過Gcc編譯生成可執(zhí)行文件才能用Gdb進行調試。#gdbtestGNUgdb6.8-debianCopyright(C)2008FreeSoftwareFoundation,Inc.LicenseGPLv3+:GNUGPLversion3orlater</licenses/gpl.html>Thisisfreesoftware:youarefreetochangeandredistributeit.ThereisNOWARRANTY,totheextentpermittedbylaw.Type"showcopying"and"showwarranty"fordetails.ThisGDBwasconfiguredas"i486-linux-gnu".(gdb)可以看出,在Gdb的啟動畫面中指出了Gdb的版本號、使用的庫文件等信息,接下來就進入了由“(gdb)”開頭的命令行界面了。<1>查看文件在Gdb中鍵入“l(fā)”(list)就可以查看所載入的文件,如下所示:(Gdb)l1#include<stdio.h>2intsum(intm);3intmain()4{5 inti,n=0;6 sum(50);7 for(i=1;i<=50;i++)8 {9 n+=i;10 }(Gdb)l11 printf("Thesumof1~50is%d\n",n);1213}14intsum(intm)15{16 inti,n=0;17 for(i=1;i<=m;i++)18 n+=i;19 printf("Thesumof1~mis=%d\n",n);20}可以看出,Gdb列出的源代碼中明確地給出了對應的行號,這樣可以大大地方便代碼的定位。<2>設置斷點設置斷點是調試程序中是一個非常重要的手段,它可以使程序到一定位置暫停它的運行。因此,程序員在該位置處可以方便地查看變量的值、堆棧情況等,從而找出代碼的癥結所在。在Gdb中設置斷點非常簡單,只需在“b”后加入對應的行號即可(這是最常用的方式,另外還有其他方式設置斷點)。如下所示:(Gdb)b6Breakpoint1at0x804846d:filetest.c,line6.要注意的是,在Gdb中利用行號設置斷點是指代碼運行到對應行之前將其停止,如上例中,代碼運行到第6行之前暫停(并沒有運行第6行)。<3>查看斷點情況在設置完斷點之后,用戶可以鍵入“infob”來查看設置斷點情況,在Gdb中可以設置多個斷點。(Gdb)infobNumTypeDispEnbAddressWhat1breakpointkeepy0x0804846dinmainattest.c:6<4>運行代碼接下來就可運行代碼了,Gdb默認從首行開始運行代碼,可鍵入“r”(run)即可(若想從程序中指定行開始運行,可在r后面加上行號)。(Gdb)rStartingprogram:/root/workplace/Gdb/testReadingsymbolsfromsharedobjectreadfromtargetmemory...done.LoadedsystemsuppliedDSOat0x5fb000Breakpoint1,main()attest.c:66sum(50);可以看到,程序運行到斷點處就停止了。<5>查看變量值在程序停止運行之后,程序員所要做的工作是查看斷點處的相關變量值。在Gdb中只需鍵入“p”+變量值即可,如下所示:(Gdb)pn$1=0(Gdb)pi$2=134518440在此處,為什么變量“i”的值為如此奇怪的一個數(shù)字呢?原因就在于程序是在斷點設置的對應行之前停止的,那么在此時,并沒有把“i”的數(shù)值賦為零,而只是一個隨機的數(shù)字。但變量“n”是在第四行賦值的,故在此時已經為零。<6>單步運行單步運行可以使用命令“n”(next)或“s”(step),它們之間的區(qū)別在于:若有函數(shù)調用的時候,“s”會進入該函數(shù)而“n”不會進入該函數(shù)。因此,“s”就類似于VC等工具中的stepin”,“n”類似與VC等工具中的“stepover”。它們的使用如下所示:(gdb)nThesumof1-mis12757 for(i=1;i<=50;i++)(gdb)s8 n+=i;可見,使用“n”后,程序顯示函數(shù)sum的運行結果并向下執(zhí)行,而使用“s”后則進入到sum函數(shù)之中單步運行。<7>恢復程序運行在查看完所需變量及堆棧情況后,就可以使用命令“c”(continue)恢復程序的正常運行了。這時,它會把剩余還未執(zhí)行的程序執(zhí)行完,并顯示剩余程序中的執(zhí)行結果。以下是之前使用“n”命令恢復后的執(zhí)行結果:(Gdb)cContinuing.Thesumof1-50is:1275Programexitedwithcode031.可以看出,程序在運行完后退出,之后程序處于“停止狀態(tài)”。Makefile文件編寫入門[1]Makefile基本結構Makefile是Make讀入的惟一配置文件,因此本節(jié)的內容實際就是講述Makefile的編寫規(guī)則。在一個Makefile中通常包含如下內容:需要由make工具創(chuàng)建的目標體(target),通常是目標文件或可執(zhí)行文件要創(chuàng)建的目標體所依賴的文件(dependency_file)創(chuàng)建每個目標體時需要運行的命令(command)它的格式為:target:dependency_filescommand例如,有兩個文件分別為hello.c和hello.h,創(chuàng)建的目標體為hello.o,執(zhí)行的命令為gcc編譯指令:gcc–chello.c,那么,對應的Makefile就可以寫為:#Thesimplestexamplehello.o:hello.chello.hgcc–chello.c–ohello.o接著就可以使用make了。使用make的格式為:maketarget,這樣make就會自動讀入Makefile(也可以是首字母小寫makefile)并執(zhí)行對應target的command語句,并會找到相應的依賴文件。如下:[davinci@davinci-desktop]#makehello.ogcc–chello.c–ohello.o[davinci@davinci-desktop]#lshello.chello.hhello.oMakefile可以看到,Makefile執(zhí)行了“hello.o”對應的命令語句,并生成了“hello.o”目標體。注意:在Makefile中的每一個command前必須有“Tab”符,否則在運行make命令時會出錯。實驗要求:根據(jù)上述方法操作,最終生成了Makefile文件,用gedit打開Makefile文件,顯示makefile文件內容畫面:*[2]makefile變量和規(guī)則(p65-69)實驗二Linux編程初步實驗目的掌握不帶緩存的文件I/O編程方法。掌握標準I/O編程方法(帶緩存)。掌握嵌入式Linux串口讀寫編程方法。實驗環(huán)境1.PC機2.虛擬機軟件VMware3.UbuntuLinux操作系統(tǒng)三、實驗內容1.不帶緩存的文件I/O編程(1)open和close函數(shù)(p77)/*open1.c*/#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>#include<stdio.h>intmain(void){intfd;/*調用open函數(shù),以可讀寫的方式打開,注意選項可以用“|”符號連接*/if((fd=open("/tmp/hello.c",O_CREAT|O_TRUNC|O_WRONLY,0600))<0){perror("open:");exit(1);}else{printf("Openfile:hello.c%d\n",fd);}if(close(fd)<0){perror("close:");exit(1);}elseprintf("Closehello.c\n");exit(0);}實驗要求:運行此程序,顯示運行結果界面,open和close函數(shù)的功能分別是什么?read,write和lseek函數(shù)(p79-80)/*write1.c*/#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#defineMAXSIZEintmain(void){inti,fd,size,len;char*buf="Hello!I'mwritingtothisfile!";charbuf_r[10];len=strlen(buf);/*首先調用open函數(shù),并指定相應的權限*/if((fd=open("/tmp/hello.c",O_CREAT|O_TRUNC|O_RDWR,0666))<0){perror("open:");exit(1);}elseprintf("openfile:hello.c%d\n",fd);/*調用write函數(shù),將buf中的內容寫入到打開的文件中*/if((size=write(fd,buf,len))<0){perror("write:");exit(1);}elseprintf("Write:%s\n",buf);/*調用lseek函數(shù)將文件指針移到文件起始,并讀出文件中的10個字節(jié)*/lseek(fd,0,SEEK_SET);if((size=read(fd,buf_r,10))<0){perror("read:");exit(1);}elseprintf("readfromfile:%s\n",buf_r);if(close(fd)<0){perror("close:");exit(1);}elseprintf("Closehello.c\n");exit(0);}實驗要求:1)運行此程序,顯示運行結果界面。2)read,write和lseek函數(shù)的功能分別是什么?(3)fcntl和lock函數(shù)(p82-85)/*fcntl_write.c測試文件寫入鎖主函數(shù)部分*/#include<unistd.h>#include<sys/file.h>#include<sys/types.h>#include<sys/stat.h>#include<stdio.h>#include<stdlib.h>/*lock_set函數(shù)*/voidlock_set(intfd,inttype);intmain(void){intfd;/*首先打開文件*/fd=open("hello",O_RDWR|O_CREAT,0666);if(fd<0){perror("open");exit(1);}/*給文件上寫入鎖*/lock_set(fd,F_WRLCK);getchar();/*給文件解鎖*/lock_set(fd,F_UNLCK);getchar();close(fd);exit(0);}/*lock_set函數(shù)*/voidlock_set(intfd,inttype){structflocklock;lock.l_whence=SEEK_SET;//賦值lock結構體lock.l_start=0;lock.l_len=0;while(1){lock.l_type=type;/*根據(jù)不同的type值給文件上鎖或解鎖*/if((fcntl(fd,F_SETLK,&lock))==0){if(lock.l_type==F_RDLCK)printf("readlocksetby%d\n",getpid());elseif(lock.l_type==F_WRLCK)printf("writelocksetby%d\n",getpid());elseif(lock.l_type==F_UNLCK)printf("releaselockby%d\n",getpid());return;}/*判斷文件是否可以上鎖*/fcntl(fd,F_GETLK,&lock);/*判斷文件不能上鎖的原因*/if(lock.l_type!=F_UNLCK){/*該文件已有寫入鎖*/if(lock.l_type==F_RDLCK)printf("readlockalreadysetby%d\n",lock.l_pid);/*該文件已有讀取鎖*/elseif(lock.l_type==F_WRLCK)printf("writelockalreadysetby%d\n",lock.l_pid);getchar();}}}實驗要求:1)在2個終端上運行此程序,顯示運行結果界面。2)fcntl和lock函數(shù)的功能是什么?3)同樣在兩個終端上運行以下讀取鎖程序,顯示結果畫面:/*fcntl_read.c測試文件讀取鎖主函數(shù)部分*/#include<unistd.h>#include<sys/file.h>#include<sys/types.h>#include<sys/stat.h>#include<stdio.h>#include<stdlib.h>voidlock_set(intfd,inttype);intmain(void){intfd;fd=open("hello",O_RDWR|O_CREAT,0666);if(fd<0){perror("open");exit(1);}/*給文件上讀取鎖*/lock_set(fd,F_RDLCK);getchar();/*給文件接鎖*/lock_set(fd,F_UNLCK);getchar();close(fd);exit(0);}/*lock_set函數(shù)*/voidlock_set(intfd,inttype){structflocklock;lock.l_whence=SEEK_SET;//賦值lock結構體lock.l_start=0;lock.l_len=0;while(1){lock.l_type=type;/*根據(jù)不同的type值給文件上鎖或解鎖*/if((fcntl(fd,F_SETLK,&lock))==0){if(lock.l_type==F_RDLCK)printf("readlocksetby%d\n",getpid());elseif(lock.l_type==F_WRLCK)printf("writelocksetby%d\n",getpid());elseif(lock.l_type==F_UNLCK)printf("releaselockby%d\n",getpid());return;}/*判斷文件是否可以上鎖*/fcntl(fd,F_GETLK,&lock);/*判斷文件不能上鎖的原因*/if(lock.l_type!=F_UNLCK){/*該文件已有寫入鎖*/if(lock.l_type==F_RDLCK)printf("readlockalreadysetby%d\n",lock.l_pid);/*該文件已有讀取鎖*/elseif(lock.l_type==F_WRLCK)printf("writelockalreadysetby%d\n",lock.l_pid);getchar();}}}(4)select函數(shù)(p87-89)/*select1.c*/#include<fcntl.h>#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<time.h>intmain(void){intfds[2];charbuf[7];inti,rc,maxfd;fd_setinset1,inset2;structtimevaltv;/*首先按一定的權限打開hello1文件*/if((fds[0]=open("hello1",O_RDWR|O_CREAT,0666))<0)perror("openhello1");/*再按一定的權限打開hello2文件*/if((fds[1]=open("hello2",O_RDWR|O_CREAT,0666))<0)perror("openhello2");if((rc=write(fds[0],"Hello!\n",7)))printf("rc=%d\n",rc);lseek(fds[0],0,SEEK_SET);/*取出兩個文件描述符中的較大者*/maxfd=fds[0]>fds[1]?fds[0]:fds[1];/*初始化讀集合inset1,并在讀集合中加入相應的描述集*/FD_ZERO(&inset1);FD_SET(fds[0],&inset1);/*初始化寫集合inset2,并在寫集合中加入相應的描述集*/FD_ZERO(&inset2);FD_SET(fds[1],&inset2);tv.tv_sec=2;tv.tv_usec=0;/*循環(huán)測試該文件描述符是否準備就緒,并調用select函數(shù)對相關文件描述符做對應操作*/while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2)){if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)perror("select");else{if(FD_ISSET(fds[0],&inset1)){rc=read(fds[0],buf,7);if(rc>0){buf[rc]='\0';printf("read:%s\n",buf);}elseperror("read");}if(FD_ISSET(fds[1],&inset2)){rc=write(fds[1],buf,7);if(rc>0){buf[rc]='\0';printf("rc=%d,write:%s\n",rc,buf);}elseperror("write");sleep(10);}}}exit(0);}實驗要求:1)運行此程序,顯示運行結果界面,體會I/o復用原理。2)select函數(shù)的功能是什么?2.標準I/O編程(1)文件的打開,關閉和寫入程序(p102):/*fwrite1.c*/#include<stdio.h>intmain(){FILE*stream;chars[3]={'a','b','c'};/*首先使用fopen打開文件,之后再調用fwrite寫入文件*/stream=fopen("what","w");i=fwrite(s,sizeof(char),nmemb,stream);printf("i=%d",i);fclose(stream);}實驗要求:1)運行此程序,顯示運行結果界面。2)fopen,fwrite和fclose函數(shù)的功能是什么?(2)輸入輸出函數(shù)(p104)/*gets1.c*/#include<stdio.h>main(){chars[80];/*同上例,把fgets的結果作為fputs的輸入*/fputs(fgets(s,80,stdin),stdout);}實驗要求:1)運行此程序,顯示運行結果界面。2)此處fputs和fgets函數(shù)的功能是什么?3.嵌入式Linux串口讀寫編程(p94-98)/*讀寫串口的主函數(shù)receive.c*/#include<stdio.h>#include<string.h>#include<sys/types.h>#include<errno.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<termios.h>#include<stdlib.h>/*讀串口程序*//*設置串口函數(shù)*/intset_opt(intfd,intnSpeed,intnBits,charnEvent,intnStop);/*打開串口函數(shù)*/intopen_port(intfd,intcomport);intmain(void){intfd;intnread,i;charbuff[]="Hello\n";if((fd=open_port(fd,1))<0) //打開串口{perror("open_porterror");return;}if((i=set_opt(fd,115200,8,'N',1))<0) //設置串口{perror("set_opterror");return;}printf("fd=%d\n",fd);fd=3;nread=read(fd,buff,8);//讀串口printf("nread=%d,%s\n",nread,buff);close(fd);return;}/*設置串口函數(shù)*/intset_opt(intfd,intnSpeed,intnBits,charnEvent,intnStop){structtermiosnewtio,oldtio;/*保存測試現(xiàn)有串口參數(shù)設置,在這里如果串口號等出錯,會有相關的出錯信息*/if(tcgetattr(fd,&oldtio)!=0){perror("SetupSerial1");return-1;}bzero(&newtio,sizeof(newtio));/*步驟一,設置字符大小*/newtio.c_cflag|=CLOCAL|CREAD;newtio.c_cflag&=~CSIZE;/*設置停止位*/switch(nBits){case7:newtio.c_cflag|=CS7;break;case8:newtio.c_cflag|=CS8;break;}/*設置奇偶校驗位*/switch(nEvent){case'O'://奇數(shù)newtio.c_cflag|=PARENB;newtio.c_cflag|=PARODD;newtio.c_iflag|=(INPCK|ISTRIP);break;case'E'://偶數(shù)newtio.c_iflag|=(INPCK|ISTRIP);newtio.c_cflag|=PARENB;newtio.c_cflag&=~PARODD;break;case'N'://無奇偶校驗位newtio.c_cflag&=~PARENB;break;}/*設置波特率*/switch(nSpeed){case2400:cfsetispeed(&newtio,B2400);cfsetospeed(&newtio,B2400);break;case4800:cfsetispeed(&newtio,B4800);cfsetospeed(&newtio,B4800);break;case9600:cfsetispeed(&newtio,B9600);cfsetospeed(&newtio,B9600);break;case115200:cfsetispeed(&newtio,B115200);cfsetospeed(&newtio,B115200);break;case460800:cfsetispeed(&newtio,B460800);cfsetospeed(&newtio,B460800);break;default:cfsetispeed(&newtio,B9600);cfsetospeed(&newtio,B9600);break;}/*設置停止位*/if(nStop==1)newtio.c_cflag&=~CSTOPB;elseif(nStop==2)newtio.c_cflag|=CSTOPB;/*設置等待時間和最小接收字符*/newtio.c_cc[VTIME]=0;newtio.c_cc[VMIN]=0;/*處理未接收字符*/tcflush(fd,TCIFLUSH);/*激活新配置*/if((tcsetattr(fd,TCSANOW,&newtio))!=0){perror("comseterror");return-1;}printf("setdone!\n");return0;}/*打開串口函數(shù)*/intopen_port(intfd,intcomport){char*dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};longvdisable;if(comport==1)//串口1{fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);if(-1==fd){perror("Can'tOpenSerialPort");return(-1);}}elseif(comport==2)//串口2{fd=open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);if(-1==fd){perror("Can'tOpenSerialPort");return(-1);}}elseif(comport==3)//串口3{fd=open("/dev/ttyS2",O_RDWR|O_NOCTTY|O_NDELAY);if(-1==fd){perror("Can'tOpenSerialPort");return(-1);}}/*恢復串口為阻塞狀態(tài)*/if(fcntl(fd,F_SETFL,0)<0)printf("fcntlfailed!\n");elseprintf("fcntl=%d\n",fcntl(fd,F_SETFL,0));/*測試是否為終端設備*/if(isatty(STDIN_FILENO)==0)printf("standardinputisnotaterminaldevice\n");elseprintf("isattysuccess!\n");printf("fd-open=%d\n",fd);returnfd;}實驗要求:1)運行此程序,顯示運行結果界面。2)問此處的set_opt()和open_port()子函數(shù)的功能是什么?3)讀
/寫串口分別用兩個函數(shù)?實驗三進程和進程間通信(1)實驗目的掌握進程基礎概念。掌握進程控制編程方法。掌握進程間通信方式之一:管道的編程方法。實驗環(huán)境1.PC機2.虛擬機軟件VMware3.UbuntuLinux操作系統(tǒng)三、實驗內容1.進程基礎編程實現(xiàn):獲得當前進程的進程號(PID)和父進程號(PPID),并顯示。(p105)/*process.c*/#include<stdio.h>#include<unistd.h>#include<stdlib.h>intmain(){/*獲得當前進程的進程PID和其父進程PPID*/printf("ThePIDofthisprocessis%d\n",getpid());printf("ThePPIDofthisprocessis%d\n",getppid());}實驗要求:運行此程序,顯示運行結果界面(不同計算機顯示的進程號是不同的)。getpid和getppid函數(shù)的功能分別是什么?進程控制編程進程創(chuàng)建[1]fork函數(shù)--從已存在的進程中創(chuàng)建一個新進程(子進程),而原進程是父進程。這兩個分別帶回它們各自的返回值,其中父進程的返回值是子進程的進程號,而子進程則返回0。下面是fork函數(shù)的實例(p108)/*fork1.c*/#include<sys/types.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>intmain(void){pid_tresult;/*調用fork函數(shù),其返回值為result*/result=fork();/*通過result的值來判斷fork函數(shù)的返回情況,首先進行出錯處理*/if(result==-1){perror("fork");exit;}/*返回值為0代表子進程*/elseif(result==0){printf("Thereturnvalueis%d\nInchildprocess!\nMyPIDis%d\n",result,getpid());}/*返回值大于0代表父進程*/else{printf("Thereturnvalueis%d\nInfatherprocess!\nMyPIDis%d\n",result,getpid());}}實驗要求:運行此程序,顯示運行結果界面。問:你的計算機父進程返回值是?子進程返回值是?[2]exec函數(shù)族:在一個進程中啟動另一個程序??梢愿鶕?jù)指定的文件名或目錄名找到可執(zhí)行文件,并用它來取代原調用進程的數(shù)據(jù)段、代碼段和堆棧段,在執(zhí)行完之后,原調用進程的內容除了進程號外,其他全部被新的進程替換了。例如:以下程序是使用文件名的方式來查找可執(zhí)行文件,同時使用參數(shù)列表的方式。這里用的函數(shù)是execlp。(p111)/*execlp1.c*/#include<unistd.h>#include<stdio.h>#include<stdlib.h>intmain(){if(fork()==0){/*調用execlp函數(shù),這里相當于調用了“ps-ef”命令*/if(execlp("ps","ps","-ef",NULL)<0)perror("execlperror!");}}實驗要求:運行此程序,顯示運行結果界面(部分)。問:本程序的功能是什么?直接在終端上輸入命令:ps-ef,顯示結果界面,問:3)與1)的結果是否一致?exit和_exit函數(shù)--終止進程。(p115)例1/*exit.c*/#include<stdio.h>#include<stdlib.h>intmain(){printf("Usingexit...\n");printf("Thisisthecontentinbuffer");exit(0);}例2/*_exit.c*/#include<stdio.h>#include<unistd.h>intmain(){printf("Using_exit...\n");printf("Thisisthecontentinbuffer");_exit(0);}實驗要求:分別運行例1和例2程序,顯示各自的結果界面。問:這兩個函數(shù)的功能有何區(qū)別?[4]waitpid函數(shù)--使得父進程阻塞,直到有子進程退出。例:(p117)首先使用fork新建一子進程,然后讓其子進程暫停5s(使用了sleep函數(shù))。接下來對原有的父進程使用waitpid函數(shù),并使用參數(shù)WNOHANG使該父進程不會阻塞。若有子進程退出,則waitpid返回子進程號;若沒有子進程退出,則waitpid返回0,并且父進程每隔一秒循環(huán)判斷一次。/*waitpid.c*/#include<sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>intmain(){pid_tpc,pr;pc=fork();if(pc<0) printf("Errorfork.\n");elseif(pc==0) /*子進程*/{/*子進程暫停5s*/sleep(5);/*子進程正常退出*/exit(0);}else /*父進程*/{/*循環(huán)測試子進程是否退出*/do{/*調用waitpid,且父進程不阻塞*/pr=waitpid(pc,NULL,WNOHANG);/*若子進程還未退出,則父進程暫停1s*/if(pr==0){printf("Thechildprocesshasnotexited\n");sleep(1);}}while(pr==0);/*若發(fā)現(xiàn)子進程退出,打印出相應情況*/if(pr==pc) printf("Getchild%d\n",pr);else printf("someerroroccured.\n");}}實驗要求:運行該程序,顯示結果畫面。問:經過幾次循環(huán)后,捕捉到了子進程的退出信號?子進程號等于多少?守護進程守護進程,也就是通常所說的Daemon進程,是Linux中的后臺服務進程。它是一個生存期較長的進程,通常獨立于控制終端并且周期性地執(zhí)行某種任務或等待處理某些發(fā)生的事件。守護進程常常在系統(tǒng)引導裝入時啟動,在系統(tǒng)關閉時終止。如果想讓某個進程不因為用戶或終端或其他的變化而受到影響,那么就必須把這個進程變成一個守護進程??梢?,守護進程是非常重要的。例:首先建立一個守護進程,然后讓該守護進程每隔10s在/tmp/dameon.log中寫入一句話。/*dameon.c創(chuàng)建守護進程實例*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>#defineMAXFILE65535intmain(){pid_tpc;inti,fd,len;char*buf="ThisisaDameon\n";len=strlen(buf);//第一步pc=fork();if(pc<0){printf("errorfork\n");exit(1);}elseif(pc>0)exit(0);/*第二步*/setsid();/*第三步*/chdir("/");/*第四步*/umask(0);/*第五步*/for(i=0;i<MAXFILE;i++) close(i);/*這時創(chuàng)建完守護進程,以下開始正式進入守護進程工作*/while(1){if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0){perror("open");exit(1);}write(fd,buf,len+1);close(fd);sleep(10);}}實驗要求:(p122)運行此程序,并在終端輸入:tail-f/tmp/dameon.log,顯示運行結果;在終端輸入:ps-ef|grepdameon,顯示運行結果:
3.進程間通信編程(1)管道管道是Linux中進程間通信的一種方式。這里所說的管道主要指無名管道,它具有如下特點:它只能用于具有親緣關系的進程之間的通信(也就是父子進程或者兄弟進程之間)。它是一個半雙工的通信模式,具有固定的讀端和寫端。管道也可以看成是一種特殊的文件,對于它的讀寫也可以使用普通的read、write等函數(shù),但是它不是普通的文件,并不屬于其他任何文件系統(tǒng),并且只存在于內存中。pipe--管道的創(chuàng)建(p127)/*pipe.c*/#include<unistd.h>#include<errno.h>#include<stdio.h>#include<stdlib.h>intmain(){intpipe_fd[2];/*創(chuàng)建一無名管道*/if(pipe(pipe_fd)<0){printf("pipecreateerror\n");return-1;}elseprintf("pipecreatesuccess\n");/*關閉管道描述符*/close(pipe_fd[0]);close(pipe_fd[1]);}實驗要求:運行此程序,顯示結果。2)該程序的功能是?管道的讀寫(p128-129)例:首先創(chuàng)建管道,之后父進程使用fork函數(shù)創(chuàng)建子進程,之后通過關閉父進程的讀描述符和子進程的寫描述符,建立起它們之間的管道通信。/*pipe_rw.c*/#include<unistd.h>#include<sys/types.h>#include<errno.h>#include<stdio.h>#include<stdlib.h>intmain(){intpipe_fd[2];pid_tpid;charbuf_r[100];char*p_wbuf;intr_num;memset(buf_r,0,sizeof(buf_r));/*創(chuàng)建管道*/if(pipe(pipe_fd)<0){printf("pipecreateerror\n");return-1;}/*創(chuàng)建一子進程*/if((pid=fork())==0){printf("\n");/*關閉子進程寫描述符,并通過使父進程暫停2秒確保父進程已關閉相應的讀描述符*/close(pipe_fd[1]);sleep(2);/*子進程讀取管道內容*/if((r_num=read(pipe_fd[0],buf_r,100))>0)printf("%dnumbersreadfromthepipeis%s\n",r_num,buf_r);/*關閉子進程讀描述符*/close(pipe_fd[0]);exit(0);}elseif(pid>0){/*關閉父進程讀描述符,并分兩次向管道中寫入HelloPipe*/close(pipe_fd[0]);if(write(pipe_fd[1],"Hello",5)!=-1)printf("parentwrite1success!\n");if(write(pipe_fd[1],"Pipe",5)!=-1)printf("parentwrite2success!\n");/*關閉父進程寫描述符*/close(pipe_fd[1]);sleep(3);/*收集子進程退出信息*/waitpid(pid,NULL,0);exit(0);}}實驗要求:運行此程序,顯示結果。問:管道的讀和寫分別用哪個函數(shù)?標準流管道與Linux中文件操作有基于文件流的標準I/O操作一樣,管道的操作也支持基于文件流的模式(popen和pclose函數(shù))。例:/*popen.c*/#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<fcntl.h>#defineBUFSIZE1000intmain(){FILE*fp;char*cmd="ps-ef";charbuf[BUFSIZE];/*調用popen函數(shù)執(zhí)行相應的命令*/if((fp=popen(cmd,"r"))==NULL) perror("popen");else{while((fgets(buf,BUFSIZE,fp))!=NULL)printf("%s",buf);pclose(fp);}exit(0);}實驗要求:運行此程序,顯示結果畫面。問:popen和pclose函數(shù)的功能是什么?FIFO(是有名管道)前面介紹的管道是無名管道,它只能用于具有親緣關系的進程之間,這就大大地限制了管道的使用。有名管道的出現(xiàn)突破了這種限制,它可以使互不相關的兩個進程實現(xiàn)彼此通信。該管道可以通過路徑名來指出,并且在文件系統(tǒng)中是可見的。在建立了管道之后,兩個進程就可以把它當作普通文件一樣進行讀寫操作,使用非常方便。不過值得注意的是,F(xiàn)IFO是嚴格地遵循先進先出規(guī)則的,對管道及FIFO的讀總是從開始處返回數(shù)據(jù),對它們的寫則把數(shù)據(jù)添加到末尾,它們不支持如lseek()等文件定位操作。有名管道的創(chuàng)建可以使用函數(shù)mkfifo(),該函數(shù)類似文件中的open()操作,可以指定管道的路徑和打開的模式。在創(chuàng)建管道成功之后,就可以使用open、read、write這些函數(shù)了。例:該示例包含了兩個程序,一個用于讀管道,另一個用于寫管道。其中在寫管道的程序里創(chuàng)建管道,并且作為main函數(shù)里的參數(shù)由用戶輸入要寫入的內容。讀管道讀出了用戶寫入管道的內容,這兩個函數(shù)用的是非阻塞讀寫管道。/*fifo_write.c*/#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#defineFIFO"/tmp/myfifo"main(intargc,char**argv)/*參數(shù)為即將寫入的字節(jié)數(shù)*/{intfd;charw_buf[100];intnwrite;if(fd==-1)if(errno==ENXIO)printf("openerror;noreadingprocess\n");/*打開FIFO管道,并設置非阻塞標志*/fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);if(argc==1) printf("Pleasesendsomething\n");strcpy(w_buf,argv[1]);/*向管道中寫入字符串*/if((nwrite=write(fd,w_buf,100))==1){if(errno==EAGAIN) printf("TheFIFOhasnotbeenreadyet.Pleasetrylater\n");}else printf("write%stotheFIFO\n",w_buf);}/*fifl_read.c*/#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#defineFIFO"/tmp/myfifo"main(intargc,char**argv){charbuf_r[100];intfd;intnread;/*創(chuàng)建有名管道,并設置相應的權限*/if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))printf("cannotcreatefifoserver\n");printf("Preparingforreadingbytes...\n");memset(buf_r,0,sizeof(buf_r));/*打開有名管道,并設置非阻塞標志*/fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);if(fd==-1){perror("open");exit(1);}while(1){memset(buf_r,0,sizeof(buf_r));if((nread=read(fd,buf_r,100))==-1){if(errno==EAGAIN)printf("nodatayet\n");}printf("read%sfromFIFO\n",buf_r);sleep(1);}pause();unlink(FIFO);}實驗要求:為了能夠較好地觀察運行結果,需要把這兩個程序分別在兩個終端里運行,在這里首先啟動讀管道程序。由于這是非阻塞管道,因此在建立管道之后程序就開始循環(huán)從管道里讀出內容。在啟動了寫管道程序后,讀進程能夠從管道里讀出用戶的輸入內容。終端一命令為:#./read顯示程序運行的結果畫面:終端二命令為:#./writehello#./readFIFO顯示程序運行的結果畫面:實驗四進程間通信(2)與多線程程序設計實驗目的掌握進程間通信方式:信號、共享內存和消息隊列編程方法。掌握Linux線程的基本概念。掌握多線程程序設計方法。實驗環(huán)境1.PC機2.虛擬機軟件VMware3.UbuntuLinux操作系統(tǒng)三、實驗內容1.進程間通信方式(2)(1)信號通信1)信號的發(fā)送與捕捉(p137kill.c,p139alarm.c)2)信號處理(p140mysignal.cp143sigaction.c)(2)共享隊列(p146shmadd.c)(3)消息隊列(p149msg.c)3.Linux線程及實現(xiàn)(1)線程的基本操作(p154thread.c,p157pthread.c)(2)線程的訪問控制(p160mutex.c,p164sem_mutex.c,sem_syn.c)實驗要求:運行上述程序,并顯示程序結果畫面。實驗五多線程程序設計與網絡程序設計實驗目的掌握網絡基礎編程方法。掌握網絡高級編程方法。*3.掌握ping源碼編程方法。實驗環(huán)境1.PC機2.虛擬機軟件VMware3.UbuntuLinux操作系統(tǒng)三、實驗內容1.網絡基礎編程1)名字地址轉化(p175getaddrinfo.c)2)socket基礎編程(p180-182server.c與client.c)2.網絡高級編程1)fcntl(p183-184fcntl.c)2)select(184-186select_socket.c)*3.掌握ping源碼編程方法(p186-200)實驗要求:運行上述程序,并顯示程序結果畫面。下篇基于ICETEK-AM3359-A的通信嵌入式系統(tǒng)實驗實驗設備的安裝AM3359是一款基于ARMCortexTM-A8內核的低功耗應用處理器。AM3359所具有的強健的操作系統(tǒng)支持,豐富的用戶界面,高處理性能和壽命,通過完全集成的混合處理器解決方案的靈活性,使得OEMs和ODMs能將產品迅速推向市場。同時,AM3359集成了高性能的ARMCortex-A8內核,使其在工業(yè)控制、便攜式通信設備、USB、網絡傳輸、高速編碼和電力設備等行業(yè)得到更廣泛的應用。ICETEK-AM3359-A開發(fā)套件采用A型底板與核心板相結合的方式,核心板尺寸較小,具有獨立供電模塊,板載HYNIXDDR3與NandFlash,能夠獨立運行。核心板所具有的100PIN插座可與A型底板連接,實現(xiàn)外擴接口的功能。A型底板則具有SD、網絡、LCD、UART、USB等多種接口,并外擴DSP引腳,既便于開發(fā)人員進行設計與調試,也便于學生進行學習和實驗,故采用基于ICETEK-AM3359-A的教學實驗箱進行通信嵌入式系統(tǒng)實驗。實驗開發(fā)環(huán)境的設置參照《ICETEK-AM3359-ALinux使用手冊》(見配套資源中的“補充參考手冊”)安裝構建評估板的Linux開發(fā)環(huán)境,因為本實驗中用到了TI的ti-sdk-am335x-evm-05.05.00.006的環(huán)境,來編譯可以在開發(fā)板上運行的QT程序,所以要參照其中的編譯dvsdk章節(jié),安裝,配置并編譯通過Ti的ti-sdk-am335x-evm-05.05.00.00。ICETEK-AM3359-A教學實驗箱的連接1.連接電源:打開實驗箱,取出三相電源連接線,將電源線的一端插入實驗箱外部左側箱壁上的電源插孔中。確認實驗箱面板上電源總開關(位于實驗箱底板左上角)處于“關”的位置(圓圈的一端按下為“關”的狀態(tài)),連接電源線的另一端至220V交流供電插座上,保證穩(wěn)固連接。2.使用電源連接線連接各模塊電源:確認實驗箱總電源斷開。連接ICETEK-CTR板上邊插座到實驗箱底板上標有+12V電源插座;ICETEK-CTR板下邊插座到實驗箱底板上標有+5V電源插座;(注意:此處一定要防止將+12V和+5V的插座插反)如使用PP(并口)型仿真器,則連接仿真器上插座到實驗箱底板上+5V電源插座;連接DSP評估板模塊電源插座到實驗箱底板上+5V電源插座。注意各插頭要插到底,防止虛接或接觸不良。3.連接DSP評估板信號線:當需要連接信號源輸出到A/D輸入插座時,使用信號連接線圖分別連接相應插座。4.接通電源:檢查實驗箱上220V電源插座(箱體左側)中保險管是否完好,在連接電源線以后,檢查各模塊供電連線是否正確連接,打開實驗箱上的電源總開關(位于實驗箱底板左上角),使開關位于“開”的位置(豎線的一端按下為“開”的狀態(tài)),電源開關右側的指示燈亮。實驗一LED控制實驗一、實驗目的掌握Linux下系統(tǒng)led的控制方法。了解Linux3.2中設備的屬性的查詢與控制。掌握Linux下的程序通過NFS測試的方法。二、實驗原理ICETEK-AM3359-A通過GPIO控制led的顯示,并且在Linux的內核里集成了這些led的系統(tǒng)驅動,這樣在系統(tǒng)的/sys/class/led/目錄下就可以看到各個led的配置文件,用戶只要通過簡單的命令行,對每個led的brightness進行操作,就可以控制系統(tǒng)led的亮滅。原理圖如下:圖5.1ICETEK-AM3359-Aled接口三、實驗設備ICETEK-AM3359-A,安裝了Ubuntu10.04虛擬機的PC機。以及相應設備的配套電源。四、實驗步驟(1)啟動虛擬機。(2)用如下命令進行測試程序工程目錄:realtimedsp@realtimedsp-desktop:~/$cd/home/realtimedsp/icetek-AM335x-kbma/projects/examples/app/leds(3)輸入如下命令查看程序源碼?!?gedit*.c在main.c中,利用文件操作函數(shù),打開各led的brightness文件,然后向里面寫1或者0來控制led的亮滅。(4)退出以上編輯窗口。(5)編譯:…$make(6)復制編譯后的可執(zhí)行程序到nfs目錄:…$sudocpled.out/opt/nfs/home/root[sudo]passwordforrealtimedsp:『輸入密碼,回車』(7)啟動nfs進行測試在斷電情況下連接ICETEK-AM3359-A板:ICETEK-AM3359-A板的串口J16的DB-9插座到開發(fā)主機COM1;連接ICETEK-AM3359-A板的網口J4相連的ICETEK-GNET到開發(fā)主機網卡,撥碼開關SW3的狀態(tài)撥為000110;在開發(fā)主機的Windows系統(tǒng)中啟動超級終端【Sitara】接通ICETEK-AM3359-A板電源按回車鍵暫停linux的起動輸入setenvbootcmd‘nandecchw2;nandread0x820000000x2800000x400000;bootm82000000’(不要輸入)輸入setenvbootargs'console=ttyO0,115200n8root=/dev/nfsnfsroot=03:/opt/nfs,nolockrwrootwaiticetek_board=a-rgmii1ip=:03::::eth0:offeth=d4:94:a1:39:88:da',如果使用者pc機的ip不在的子網內,請參見使用手冊的第一章第三節(jié)的注意事項。(不要輸入)輸入boot觀察【Sitara】中的輸出的起動信息輸入root登錄輸入cddemos進入測試目錄輸入./led.out運行測試程序,可以看到led,D1會不斷閃爍。關閉ICETEK-AM3359-A板電源,結束實驗。五、實驗結果Led的D1會不斷閃爍。六、問題與思考由于在Linux3.2中已經采用了新的內核驅動的編寫架構,不是必需在dev中建立掛載點,而是有sys中輸出驅動的屬性文件,這樣通過命令行的方式,用戶就可以控制一些驅動變化,所以用戶也可以通過在串口控制對口輸入如下的命令來控制led,echo1>/sys/class/leds/am335x::led1/brightness和echo0>/sys/class/leds/am335x::led1/brightness試運行一下這兩句命令,觀察實驗結果。
實驗二按鍵控制實驗實驗目的了解GPIO按鍵的用處;了解TMS320AM335X連接的控制GPIO按鍵方法;掌握Linux下系統(tǒng)對GPIO按鍵的控制方法。二、實驗原理ICETEK-AM3359-A通過GPIO來控制按鍵的,通過對對應的GPIO引腳的讀,可以知道按鍵的狀態(tài),再通過對GPIO控制led的顯示,把按鍵的狀態(tài)顯示出來。原理圖如下:圖5.2按鍵控制原理圖在Linux的內核中,缺省將這些GPIO配置為按鍵,也就是做為一個輸入設備,當按下或者抬起按鍵時,內核會收到事件,程序就會響應這個事件,去讀寫鍵盤輸入,就可以監(jiān)控并讀出按鍵當前的狀態(tài),并根據(jù)狀態(tài)和控制led的亮滅。三、實驗設備ICETEK-AM3359-A,安裝了WindowsXP和Linux虛擬機的PC機。以及相應設備的配套電源。四、實驗步驟啟動虛擬機(2)用如下命令進行測試程序工程目錄realtimedsp@realtimedsp-desktop:~/$cd/home/realtimedsp/icetek-AM335x-kbma/projects/examples/app/keypad-led(3)輸入如下命令查看程序源碼…$gedit*.c在keypad-led.c中,利用文件操作函數(shù),打開鍵盤輸入設備,然后讀鍵盤設備,當有按鍵產生時,讀函數(shù)返回,然后再判斷讀的是哪個按鍵,并根據(jù)該按鍵的狀態(tài),利用system執(zhí)行控制臺命令,來控制相應led燈的亮滅;(4)編譯…$make(5)復制編譯后的可執(zhí)行程序到nfs目錄…$sudocpkeypad-led.out/opt/nfs/home/root[sudo]passwordforrealtimedsp:『輸入密碼,回車』(6)啟動nfs進行測試在斷電情況下連接ICETEK-AM3359-A板:ICETEK-AM3359-A板的串口J16的DB-9插座到開發(fā)主機COM1;連接ICETEK-AM3359-A板的網口J4相連的ICETEK-GNET到開發(fā)主機網卡,撥碼開關SW3的狀態(tài)撥為000110。在開發(fā)主機的Windows系統(tǒng)中啟動超級終端【Sitara】接通ICETEK-AM3359-A板電源按回車鍵暫停linux的起動輸入setenvbootcmd'nandecchw2;nandread0x820000000x2800000x400000;bootm82000000'輸入setenvbootargs'console=ttyO0,115200n8root=/dev/nfsnfsroot=03:/opt/nfs,nolockrwrootwaiticetek_board=a-rgmii1ip=:03::::eth0:offeth=d4:94:a1:39:88:da',如果使用者pc機的ip不在的子網內,請參見使用手冊的第一章第三節(jié)的注意事項。輸入boot觀察【Sitara】中的輸出的起動信息。輸入root登錄輸入cddemos進入測試目錄輸入./keypad-led.out/dev/input/event1運行測試程序,按動按鍵SW1,可以看到led,D1會根據(jù)按鍵的當前狀態(tài)進行閃爍。關閉ICETEK-AM3359-A板電源,結束實驗五、實驗結果按動按鍵SW1,對應的led1燈會跟著亮滅。實驗三驅動模塊編寫實驗一.實驗目的掌握Linux驅動的編寫方法;掌握Linux驅動的測試方法;掌握Linux的驅動架構和編譯環(huán)境的配置。二.實驗原理Linux的驅動和大多數(shù)的系統(tǒng)的驅動驅動一樣,需要實現(xiàn)一些固定的函數(shù)接口,這樣系統(tǒng)才會知道,什么時候加載它,如何加載它,并通過系統(tǒng)API調用到它。一般Linux驅動,首先要聲明并實現(xiàn)一個初始化函數(shù),并且在初始化函數(shù)里,初始化配置相應的硬件設備,并設定這個設備的各種接口函數(shù)。三.實驗設備ICETEK-AM3359-A,安裝
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生物研究的報告范文
- 《保健蘆薈知識》課件
- 專題09 統(tǒng)計與概率(解析版)
- 部門供職報告范文
- 2025年防城港貨運從業(yè)資格證
- 范文研究報告
- 2025年南寧大車貨運資格證考試題
- 辭職報告范文 大全
- 《信息商品市場》課件
- 2025年邯鄲道路運輸從業(yè)資格證考試內容是什么
- 如何給小孩講保險知識講座
- 部編版四年級道德與法治上冊期末復習計劃
- 2023年中山市房地產市場年報(掃描版)-世聯(lián)行
- 公路工程檢測技術 課件 任務2.1無機結合料穩(wěn)定材料檢測
- 電影第一出品單位變更協(xié)議模板
- 國開01880-組織行為學機考復習資料
- 2023瑞幸員工合同協(xié)議書
- 增值稅銷售貨物或者提供應稅勞務清單(模板)
- 混合式教學模式
- 2023年《思想道德與法治》期末考試復習題庫(帶答案)
- 跳纖施工方案
評論
0/150
提交評論