嵌入式LINUX_C基础08由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“嵌入式linux基础教程”。
ESD_DAY030_Elvis UNIX/LINUX 系统下的C高级编程 A.N.E.K 1.文件的基本操作
1.1使用 fcntl函数实现文件锁的功能
包含头文件unistd.h,fcntl.h 功能:(1)复制文件描述符(了解);
(2)操作文件描述符标识的功能(了解,少用);
(3)操作文件按状态标志的功能(了解);(4)实现建议锁的功能(掌握);
格式:int fcntl(int fd,int cmd,…/*arg*/); 注意:第一个参数:文件操作符,指定要操作的文件;
第二个参数:具体操作命令,即执行何种操作;
(了解)F_DUPFD--寻找一个大于等于arg参数最小并且可用的文件描述符来作为参数fd的副
(了解)F_GETFD/F_SETFD--获取/设置文件描述符的标志;
(了解)F_GETFL/F_SETFL--获取/设置文件的状态标志(如O_WRONLY,O_RDWR等);
F_GETLK/F_SETLK/F_SETLKW--获取/设置/延迟设置建议锁;
第三个参数:可变长参数,是否需要取决于cmd;
如果实现建议锁功能时,该参数是一个指向以下结构体类型的指针,结构体类型如下:struct 本,与dup2不同在于,不会强制解除已经占用的文件描述符;
flock {
...short l_type;(锁类型): F_RDLCK,(读锁)F_WRLCK,(写锁)F_UNLCK ;(解锁)
short l_whence;锁的起始位置:SEEK_SET, SEEK_CUR, SEEK_END
off_t l_start;
所得起始位置的偏移量
off_t l_len;
锁定的字节数
pid_t l_pid;
加锁的进程号(F_GETLK only)
...};返回值:F_DUPFD--成功返回新的文件的描述符;
F_GETFD--成功返回文件描述符的标志; F_GETFL--成功返回文件状态标志;
其他命令成功返回0;所有命令失败都返回-1,并设置errno;
(1)使用F_SETLCK作为函数的第二个参数
如果锁的类型是:F_RDLCK,F_WRLCK时,实现加锁的功能; 如果锁的类型是:F_UNLCK时,实现解锁的功能; 如果文件中已经存在相互冲突的锁,则加锁失败。
****使用fcntl函数给文件a.txt中的前10个字节加写锁,占用20秒之后再关闭文件,文件中的内容是:good good study,day day up!******************************* 嵌入式培训笔记 1 2015-09-10 ESD_DAY030_Elvis UNIX/LINUX 系统下的C高级编程 #include #include #include #include #include #include #include
int main(){
char arr[]=“Good good study,day day up!”;
//创建或打开一个文件
int fd=open(“a.txt”,O_RDWR|O_CREAT|O_TRUNC,0664);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“文件打开成功n”);
//写入文件
int res=write(fd,arr,strlen(arr));
if(-1==res)
{
perror(“write”);
exit(-1);
}
printf(“文件写入成功n”);
//准备一把写锁
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_whence=SEEK_SET;
lock.l_start=0;
lock.l_len=10;
lock.l_pid=0;
//为文件上锁
res=fcntl(fd,F_SETLK,&lock);
if(-1==res)
{
perror(“fcntl”);
exit(-1);嵌入式培训笔记 2 A.N.E.K
2015-09-10 ESD_DAY030_Elvis
}
UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“加锁成功,正在关闭文件...n”);
//进程占用
sleep(20);
//关闭文件,文件锁自动释放
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“文件成功关闭n”);
return 0;} ****测试文件在加锁的情况下能否写入***************************************** #include #include #include #include #include #include
int main(){
//1.打开文件
int fd=open(“a.txt”,O_WRONLY);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“成功打开文件n”);
//2.写入内容
int res=write(fd,“NARUKAKA”,9);
if(-1==res)
{
perror(“write”);
exit(-1);
}
printf(“成功写入数据,共写入%d字节n”,res);嵌入式培训笔记 3 2015-09-10 ESD_DAY030_Elvis
//3.关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“成功关闭文件n”);
return 0;
UNIX/LINUX 系统下的C高级编程 A.N.E.K }//在加锁的进程未结束时,可以看到也能写入
总结:由程序代码可知:文件的内容在加锁的情况下依然会被修改,也就是说文件锁并不能控制对文件的读写操作。只能锁定其他的锁,也就是加锁之后会导致第二次加锁失败。(读锁可以反复加)
如何采用文件锁来控制对文件的读写操作? 解决方案:一般来说,在执行读操作函数之前试图加读锁,在执行写操作函数之前试图加写锁,根据能否加锁来决定能否进行读写操作,从而实现文件锁影响读写操作的功能。****测试文件在加锁的情况下能否写入******************************************** #include #include #include #include #include #include
int main(){
//1.打开文件
int fd=open(“a.txt”,O_WRONLY);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“成功打开文件n”);
//2.准备一把锁
struct flock lock;嵌入式培训笔记 4 2015-09-10 ESD_DAY030_Elvis
lock.l_type=F_WRLCK;
lock.l_whence=SEEK_SET;
lock.l_start=0;
lock.l_len=10;
lock.l_pid=-1;
//3.使用fcntl函数试图加锁
UNIX/LINUX 系统下的C高级编程 A.N.E.K
int res=fcntl(fd,F_SETLK,&lock);
if(-1==res)
{
printf(“文件以被加锁,无法执行写操作n”);
}
else
{
//4.根据fcntl函数的结果,判断是否写入内容
res=write(fd,“NARUKAKA”,9);
if(-1==res)
{
perror(“write”);
exit(-1);
}
printf(“成功写入数据,共写入%d字节n”,res);
}
//5.关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“成功关闭文件n”);
return 0;}//在加锁的进程未结束时,可以看到没有写入
释放锁的方法:
a.使用close函数关闭文件/进程结束时会自动释放相关的文件锁; b.将锁的类型修改为:F_UNLCK,使用fcntl函数重新设置即可;
****使用F_UNLCK来实现解锁的功能********************************************** #include #include 嵌入式培训笔记 5 2015-09-10 ESD_DAY030_Elvis UNIX/LINUX 系统下的C高级编程 A.N.E.K #include #include #include #include
int main(){
//1.打开文件a.txt
int fd=open(“a.txt”,O_RDWR);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“文件打开成功n”);
//2.准备一把锁
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_whence=SEEK_SET;
lock.l_start=0;
lock.l_len=10;
lock.l_pid=-1;
//3.使用fcntl函数给文件加锁
int res=fcntl(fd,F_SETLK,&lock);
if(-1==res)
{
perror(“fcntl”);
exit(-1);
}
printf(“加锁成功,开始使用文件n”);
//4.模拟占用20秒
sleep(20);
printf(“使用文件结束,开始解锁...n”);
//5.使用F_UNLCK来实现解锁
lock.l_type=F_UNLCK;
res=fcntl(fd,F_SETLK,&lock);
if(-1==res)
{
perror(“fcntl”);
exit(-1);
}
printf(“解锁成功,暂时不关闭文件n”);
//6.模拟占用20秒
sleep(20);嵌入式培训笔记 6 2015-09-10 ESD_DAY030_Elvis UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“占用文件结束,下面开始关闭文件n”);
//7.关闭文件a.txt
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“文件已经成功关闭n”);
return 0;}(2)使用F_SETLKW作为函数的第二个参数 功能与F_SETLK类似,所不同的是如果文件中已经有冲突的锁,则并不是返回加锁失败,而是一直进行阻塞状态,知道可以加上锁时立即加锁加上为止。
****使用F_SETLKW作为第二个参数****************************************** #include #include #include #include #include #include
int main(){
//1.打开文件
int fd=open(“a.txt”,O_WRONLY);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“成功打开文件n”);
//2.准备一把锁
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_whence=SEEK_SET;
lock.l_start=0;
lock.l_len=10;
lock.l_pid=-1;嵌入式培训笔记 7 2015-09-10 ESD_DAY030_Elvis
//3.使用fcntl函数试图加锁
UNIX/LINUX 系统下的C高级编程 A.N.E.K
int res=fcntl(fd,F_SETLKW,&lock);
if(-1==res)
{
printf(“文件以被加锁,无法执行写操作n”);
}
else
{
//4.根据fcntl函数的结果,判断是否写入内容
res=write(fd,“NARUKAKA”,9);
if(-1==res)
{
perror(“write”);
exit(-1);
}
printf(“成功写入数据,共写入%d字节n”,res);
}
//5.关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“成功关闭文件n”);
return 0;}//在加锁的进程未结束时,程序并未报告加锁失败,//也没有报告成功写入数据
//当加锁的进程结束时,可以看到立即加锁成功,并写入数据
(3)使用F_GETLK作为第二个参数 fcntl函数中的第三个参数描述的是想要加到文件上的锁信息,如果该锁可以加到文件上,则不去加锁,而是将第三个参数的锁的类型更改为F_UNLCK,其他成员不变;如果该文件的锁不可以加到该文件上,则把文件中存的锁的信息输入到(替换到)第三个参数指定的锁的类型等信息(原本指定的锁信息丢失),并将l_pid设置为真正给文件加锁的进程的进程号。
****使用F_GETLK作为第二个参数************************************************ 嵌入式培训笔记
2015-09-10 ESD_DAY030_Elvis #include #include #include #include #include #include
int main(){
//打开文件
UNIX/LINUX 系统下的C高级编程 A.N.E.K
int fd=open(“a.txt”,O_RDWR);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“文件打开成功n”);
//准备一把锁
struct flock lock;
lock.l_type=F_WRLCK;
lock.l_whence=SEEK_SET;
lock.l_start=5;
lock.l_len=8;
lock.l_pid=-1;
//使用fcntl给文件加锁
int res=fcntl(fd,F_GETLK,&lock);
if(-1==res)
{
printf(“加锁失败n”);
}
else
{
printf(“加锁成功n”);
}
printf(“lock.l_type=%d,lock.l_start=%ld,lock.l_len=%ld,lock.l_pid=%dn”,lock.l_type,lock.l_start,lock.l_len,lock.l_pid);
printf(“F_RDLCK=%d,F_WRLCK=%d,F_UNLCK=%dn”,F_RDLCK,F_WRLCK,F_UNLCK);
//关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);嵌入式培训笔记 9 2015-09-10 ESD_DAY030_Elvis
exit(-1);
}
printf(“文件成功关闭n”);
return 0;}
UNIX/LINUX 系统下的C高级编程 A.N.E.K 1.2 使用stat函数/fstat函数查看文件的状态
使用时引入头文件unistd.h,sys/types.h,sys/stat.h 功能:获取参数指定文件的状态信息。
格式:int stat(const char*path(“文件路径”),struct stat*buf);
格式:int fstat(int fd,struct stat*buf);//除了第一个参数和stat()函数不同外,其他都相同;
注意:第一个参数:代表路径的字符串常量,即文件的路径;
第二个参数:类型为struct stat结构体的指针,用于将函数内部数据带出来; struct stat {...mode_t
st_mode;//文件的权限和类型,mode_t是unsigned int 型
off_t
st_size;//总大小,以字节为单位(重点)(off_t是long int型)
time_t
st_mtime;//最后一次修改时间 ,time_t是long int 型
...};在获得文件的类型时,需要使用带参宏S_ISREG(m):status is regular,成立,则是普通文件;
S_ISDIR(m):status is directory,成立,则是目录文件;
这里参数m是指st_mode;当获取文件的权限时,采用0777(000 111 111 111)和st_mode按位或可以得到权限值(八进制)返回值:成功返回0,失败返回-1,并设置errno。
****使用stat函数获取文件的状态信息*************************************** #include #include #include #include #include #include
int main(){
//准备结构体变量(结构体类型已有系统定义好,直接使用)
struct stat st={};
//使用stat函数获取状态信息
int res=stat(“a.txt”,&st);
if(-1==res)
{ 嵌入式培训笔记 10 2015-09-10 ESD_DAY030_Elvis
perror(“stat”);
exit(-1);
}
UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“st.st_mode=%o,st.st_size=%ld,st.st_mtime=%ldn”,st.st_mode,st.st_size,st.st_mtime);
printf(“-----------------------n”);
if(S_ISREG(st.st_mode))//判断文件类型
{
printf(“普通规则文件n”);
}
if(S_ISDIR(st.st_mode))
{
printf(“目录文件n”);
}
printf(“文件的权限是:%on”,st.st_mode&0777);//按位与提取数据
printf(“文件的的大小是:%ldn”,st.st_size);
printf(“文件最后修改时间:%sn”,ctime(&st.st_mtime));//使用ctime函数转换修改时间
struct tm*pt=localtime(&st.st_mtime);//使用localtime函数转换修改时间
printf(“文件的最
后
一
次
修
改
时
间是:%d-%d-%d %02d:%02d:%02dn”,pt->tm_year+1900,pt->tm_mon+1,pt->tm_mday,pt->tm_hour,pt->tm_min,pt->tm_sec);
return 0;} 扩展: 获取指定文件大小的主要方法有三种: a.调用stat/fstat函数来获取文件的大小;
b.使用lseek将文件读写位置置到文件尾,通过返回值来获取文件的大小; c.使用fseek将文件读写位置置到文件尾,使用ftell函数获取文件的大小; ctime()函数:使用时引入头文件time.h 功能:将整数类型的时间转换为字符串形式的时间。格式:char* ctime(const time_t*timep);
注意:一个参数:存储有整形时间的变量的地址,即stat函数的结构体struct stat的成员time_t 返回值:成功返回0,失败返回-1,并设置errno。st_mtime;可以自动换行
localtime()函数:使用时引入头文件time.h 功能:将整数类型的时间转换为结构体类型返回。格式:struct tm* localtime(const time_t*timep);
嵌入式培训笔记 11 2015-09-10 ESD_DAY030_Elvis
UNIX/LINUX 系统下的C高级编程 A.N.E.K 注意:一个参数:存储有整形时间的变量的地址,即stat函数的结构体struct stat的成员time_t
st_mtime;可以自动换行; struct tm {
int tm_sec;
/* seconds ,秒*/
int tm_min;
/* minutes,分 */
int tm_hour;
/* hours,小时 */
int tm_mday;
/* day of the month,日期 */
int tm_mon;
/* month,月份,范围是0-11,因此需要手动加1
int tm_year;
/* yea,年份,需要加上1900
int tm_wday;
/* day of the week,星期,星期日是第一天*/
int tm_yday;
/* day in the year *,一年中的第几天,范围是0-365
int tm_isdst;
/* daylight saving time,夏令时(了解)
};在获得文件的类型时,需要使用带参宏S_ISREG(m):status is regular,成立,则是普通文件;
S_ISDIR(m):status is directory,成立,则是目录文件;
这里参数m是指st_mtime;制)
返回值:成功返回0,失败返回-1,并设置errno。当获取文件的权限时,采用0777(000 111 111 111)和st_mtime按位与可以得到权限值(八进1.3 使用acce函数查看文件的权限
使用时引入头文件unistd.h
功能:检查一个文件中,真实用户的权限信息。
格式:int acce(const char*pathname,int mode); 注意:第一个参数:文件的路径名,双引号括起来;
第二个参数:文件的操作模式:
F_OK:文件是否存在,可以按位或以下模式,重点; R-OK:文件是否可读; W_OK:文件是否可写; X_OK:文件是否可执行;
返回值:成功返回0,失败返回-1,并设置errno。
****使用acce函数查看文件的权限信息********************************** #include #include #include #include
int main(){
if(0==acce(“a.txt”,F_OK))
{
printf(“文件存在n”);
} 嵌入式培训笔记 12 2015-09-10 ESD_DAY030_Elvis
if(0==acce(“a.txt”,R_OK))
{
printf(“文件可读n”);
}
if(0==acce(“a.txt”,W_OK))
{
printf(“文件可写n”);
}
if(0==acce(“a.txt”,X_OK))
{
printf(“文件可执行n”);
}
UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“F_OK=%d,R_OK=%d,W_OK=%d,X_OK=%dn”,F_OK,R_OK,W_OK,X_OK);
return 0;} 1.4 使用chmod函数改变文件的权限
使用时引入头文件sys/stat.h
功能:修改指定文件的新权限。
格式:int chmod(const char*path,mode_t mode); 注意:第一个参数:文件的路径名,双引号括起来;
第二个参数:想要修改的新权限(一般以八进制表示:如0664);返回值:成功返回0,失败返回-1,并设置errno。
1.5 使用truncate函数截取文件(掌握)使用时引入头文件unistd.h,sys/types.h 功能:将指定的文件截取大指定的大小。
格式:int truncate(const char*pathname,off_t length);
int ftruncate(int fd,off_t length);
第二个参数:文件的最新长度/大小;
如果截取后的文件大小小于原来的文件,则产生数据丢失;如果截取后的文件大于原来的文注意:第一个参数:文件的路径名,双引号括起来;文件描述符
件,则文件被扩大,扩大的区域读取到的是 ;返回值:成功返回0,失败返回-1,并设置errno。
****使用chmod函数和truncate函数设置文件的权限和大小***************** #include #include #include #include #include
嵌入式培训笔记 13 2015-09-10 ESD_DAY030_Elvis int main(){
//1.获取文件的权限和大小
struct stat st={};
int res=stat(“a.txt”,&st);
if(-1==res)
{
perror(“stat”);
}
UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“文件的权限是:%on”,st.st_mode&0777);
printf(“文件的大小是:%ldn”,st.st_size);
//2.修改文件的权限和大小
res=chmod(“a.txt”,0777);
if(-1==res)
{
perror(“chmod”);
}
res=truncate(“a.txt”,100);
if(-1==res)
{
perror(“truncate”);
}
//3.获得修改后文件的权限
res=stat(“a.txt”,&st);
if(-1==res)
{
perror(“stat”);
}
printf(“修改后的权限是:%on”,st.st_mode&0777);
printf(“修改后的大小是:%ldn”,st.st_size);
return 0;} 1.6 umask函数(了解)
1.7 使用mmap函数和munmap函数实现文件/设备到虚拟地址之间的映射 通过该方法可以将对文件的读写操作转换为对内存的读写操作,因此多了一种读写文件的方式。
****使用MMAP建立文件到虚拟地址之间的映射,并存储数据****************** 嵌入式培训笔记
2015-09-10 ESD_DAY030_Elvis #include #include #include #include #include #include #include #include
//定义员工的数据类型 typedef struct {
int id;
char name[20];
double salary;}Emp;
int main(){
//1.创建/打开文件Emp
UNIX/LINUX 系统下的C高级编程 A.N.E.K
int fd=open(“emp.dat”,O_RDWR|O_CREAT|O_TRUNC,0664);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“创建文件成功n”);//2.修改文件的大小为3个员工信息的大小
//这一步相当于分配实际的物理内存空间,使之与虚拟地址相对应,不可缺少的步骤
int res=ftruncate(fd,sizeof(Emp)*3);
if(-1==res)
{
perror(“ftruncate”);
exit(-1);
}
printf(“修改文件的大小成功n”);
//3.建立虚拟地址到文件emp.dat的映射
void *pv=mmap(NULL,sizeof(Emp)*3,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(MAP_FAILED==pv)
{
perror(“mmap”);
exit(-1);
}
printf(“映射创建成功n”);嵌入式培训笔记 15 2015-09-10 ESD_DAY030_Elvis UNIX/LINUX 系统下的C高级编程 A.N.E.K
//4.通过虚拟地址存放员工信息
//实际上是存放在了与虚拟地址映射的文件中
//映射了几个虚拟地址就只能使用几个虚拟地址
Emp*pe=pv;
pe[0].id=1001;
strcpy(pe[0].name,“Narukana”);
pe[0].salary=16500;
pe[1].id=1002;
strcpy(pe[1].name,“Komachi”);
pe[1].salary=17500;
pe[2].id=1002;
strcpy(pe[2].name,“Alika”);
pe[2].salary=22500;
//5.解除映射
res=munmap(pv,sizeof(Emp)*3);
if(-1==res)
{
perror(“munmap”);
exit(-1);
}
pe=NULL;
printf(“成功解除映射n”);
//6.关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
printf(“文件已经成功关闭n”);
return 0;} ****使用MMAP建立文件到虚拟地址之间的映射,并读取数据****************** #include #include #include #include #include #include 嵌入式培训笔记 16 2015-09-10 ESD_DAY030_Elvis #include #include
//定义员工的数据类型 typedef struct {
int id;
char name[20];
double salary;}Emp;
int main(){
//1.创建/打开文件Emp
UNIX/LINUX 系统下的C高级编程 A.N.E.K
int fd=open(“emp.dat”,O_RDWR);
if(-1==fd)
{
perror(“open”);
exit(-1);
}
printf(“创建文件成功n”);
//2.建立虚拟地址到文件emp.dat的映射
void *pv=mmap(NULL,sizeof(Emp)*3,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(MAP_FAILED==pv)
{
perror(“mmap”);
exit(-1);
}
printf(“映射创建成功n”);
//3.通过虚拟地址读出员工信息
//实际上是存放在了与虚拟地址映射的文件中
//映射了几个虚拟地址就只能使用几个虚拟地址
Emp*pe=pv;
int i=0;
for(i=0;i
{
printf(“%d %s %lfn”,pe[i].id,pe[i].name,pe[i].salary);
}
//4.解除映射
int res=munmap(pv,sizeof(Emp)*3);
if(-1==res)
{
perror(“munmap”);嵌入式培训笔记 17 2015-09-10 ESD_DAY030_Elvis
exit(-1);
}
pe=NULL;
printf(“成功解除映射n”);
//5.关闭文件
res=close(fd);
if(-1==res)
{
perror(“close”);
exit(-1);
}
UNIX/LINUX 系统下的C高级编程 A.N.E.K
printf(“文件已经成功关闭n”);
return 0;} 1.8 其他的文件操作函数
link()--创建硬链接; unlink()--删除硬链接; rename()--实现重命名文件; remove()--实现删除文件;
作业:编程实现函数generator_id(),main函数中调用该函数。每次执行该程序都能生成一个账号,并且自动递增。
嵌入式培训笔记 18 2015-09-10
今天老大让我针对一个面试者出些嵌入式方面的面试题,主要是想对他的技术深度进一步了解。我就出了下面这些问题,每个问题背后都是考察一个嵌入式程序员应该具备的相关技能。当......
河南机电高等专科学校嵌入式系统基础课程设计报告系 部: 电子通信工程系 专 业: 班 级: 学生姓名: 学 号:2012年 06月 嵌入式系统基础课程设计任务书1.时间:2012年06月11日~2012年06......
河南机电高等专科学校《嵌入式系统基础》 课程设计报告设计题目: 系 部: 电子通信工程系 班 级: 学 号: 学生姓名: 成 绩:2012年 05月 《嵌入式系统基础》课程设计任务书 1.时间:201......
嵌入式系统设计基础嵌入式系统设计基础结题报告学生1: 学生2: 学生3: 组长: 组长电话: 指导老师: 完成时间:嵌入式系统设计基础目录目录 ..............................................
刀豆文库小编为你整合推荐5篇计算机四级嵌入式系统开发基础试题,也许这些就是您需要的文章,但愿刀豆文库能带给您一些学习、工作上的帮助。......