linux培训资料.docx
- 文档编号:5580329
- 上传时间:2022-12-28
- 格式:DOCX
- 页数:20
- 大小:23.38KB
linux培训资料.docx
《linux培训资料.docx》由会员分享,可在线阅读,更多相关《linux培训资料.docx(20页珍藏版)》请在冰豆网上搜索。
linux培训资料
新人培训阶段学习资料
上海核心信息技术有限公司
Version0.02(2011.03)
课程介绍
本课程旨在发现具备开发Linux下驱动程序的人才,新入社员将通过一个月的时间参照本教程熟悉Linux下设备驱动开发必须的知识。
培训结束后符合要求的新人将进入公司具体项目组熟悉具体项目的开发方法。
课程大纲
本课程大纲内列出的任务基本由员工自己动手解决为主,通常每天上午指导人员将进行昨日实验结果评价及当日任务安排,对于工作任务不清楚的地方请及时向指导人员提出。
下午主要为新员工个人实验时间。
第一阶段Linux开发基础
2-3天
通过本课程的学习,使新员工能够了解Linux操作系统的概念,熟练掌握Linux下的基本命令、常用工具的使用方面的知识。
学习内容:
◆公司安全保密教育,日报格式说明
◆Linux常用命令,文本编辑器Vi,简单Shell脚本编程
◆嵌入式Linux开发环境基础:
Gcc,Gdb,Make和Makefile
GCCARM编译环境安装(SourceryG++LiteEditionforARM)
◆软件版本管理器Svn
◆嵌入式软件开发环境搭建与使用
x86linux内核编译
versatilearmlinux内核编译
QEMU运行linux
实验:
1.开发环境配置,安装ubuntu虚拟机,熟悉Linux使用
2.配置X86开发环境,编译x86Linux内核,在QEMU下运行
3.配置ARM开发环境,编译armLinux内核,在QEMU下运行
4.编写HelloWorld程序,在x86/armLinuxQEMU下运行
5.编写一个脚本,统计一个目录下面所有C代码的行数。
6.这些格式的如何去解压
.tar/bz2/tar.bz2/tar.gz/tar.tar/.Z/.zip/.rar
第二阶段嵌入式C语言编程强化
3-5天
本课程的主要目标是通过编写代码的方式,加强对于C语言编程和数据结构的掌握程度。
回答如下16道国外经典的面向嵌入式C语言面试题
1.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
2.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
3.预处理器标识#error的目的是什么?
4.嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?
5.用变量a给出下面的定义
a)一个整型数(Aninteger)
b)一个指向整型数的指针(Apointertoaninteger)
c)一个指向指针的的指针,它指向的指针是指向一个整型数(Apointertoapointertoaninteger)
d)一个有10个整型数的数组(Anarrayof10integers)
e)一个有10个指针的数组,该指针是指向一个整型数的(Anarrayof10pointerstointegers)
f)一个指向有10个整型数数组的指针(Apointertoanarrayof10integers)
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger)
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger)
6.关键字static的作用是什么?
7.关键字const是什么含意?
8.关键字volatile有什么含意并给出三个不同的例子。
9.嵌入式系统总是要用户对变量或寄存器进行位操作。
给定一个整型变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit3。
在以上两个操作中,要保持其它位不变。
10.嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。
在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。
编译器是一个纯粹的ANSI编译器。
写代码去完成这一任务。
11.中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。
具体所代表的事实是,产生了一个新的关键字__interrupt。
下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
__interruptdoublecompute_area(doubleradius)
{
doublearea=PI*radius*radius;
printf("Area=%f",area);
returnarea;
}
12.下面的代码输出是什么,为什么?
voidfoo(void)
{
unsignedinta=6;
intb=-20;
(a+b>6)puts(">6"):
puts("<=6");
}
13.评价下面的代码片断:
unsignedintzero=0;
unsignedintcompzero=0xFFFF;
/*1'scomplementofzero*/
不具备可移植性性
14.尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。
那么嵌入式系统中,动态分配内存可能发生的问题是什么?
char*ptr;
if((ptr=(char*)malloc(0))==NULL)
puts("Gotanullpointer");//1
else
puts("Gotavalidpointer");//2
输出2
这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。
这个主题已经在ESP杂志中被广泛地讨论过了(主要是P.J.Plauger,他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!
。
。
。
。
free
这是一个有趣的问题。
最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。
这就是上面的代码,该代码的输出是“Gotavalidpointer”。
我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。
15.Typedef在C语言中频繁用以声明一个已经存在的数据类型的同义字。
也可以用预处理器做类似的事。
例如,思考一下下面的例子:
#definedPSstructs*
typedefstructs*tPS;
以上两种情况的意图都是要定义dPS和tPS作为一个指向结构s指针。
哪种方法更好呢?
(如果有的话)为什么?
16.C语言同意一些令人震惊的结构,下面的结构是合法的吗,如果是它做些什么?
inta=5,b=7,c;
c=a+++b;
12
编程题
◆位操作练习
Description
假设你工作在一个32位的机器上,你需要将某一个外设寄存器的第X位设置成0(最低位为第0位,最高位为第31位),将第Y位开始的连续三位设置成110(从高位到低位的顺序),而其他位保持不变。
对给定的寄存器值R,及X,Y,编程计算更改后的寄存器值R。
Input
仅一行,包括R,X,Y,以逗号","分隔,R为16进制表示的32位整数,X,Y在0-31之间且Y>=3,(Y-X)的绝对值>=3,保证两次置位不会重合
Output
更改后的寄存器值R(16进制输出)
SampleInput
12345678,0,3
SampleOutput
1234567c
voidmain()
{
intR,X,Y;
scanf("%d,%d,%d",&R,&X,&Y);
R&=~(1< R|=6<<(Y-3); R&=~(1<<(Y-2)); printf("theRvalueis%d",R); } ◆排序 编写一个排序程序。 被排序的文件有8MB大小,一行一个随机整数(ASCII格式)。 要求对这些整数进行排序,并计算平均值,打印出排序所需的时间。 #include"stdio.h" #include"stdlib.h" #include"math.h" #include"time.h" voidrun(int*pData,intleft,intright) { inti,j; intmiddle,iTemp; i=left;j=right; middle=pData[left]; do{ while((pData[i] i++; while((pData[j]>middle)&&(j>left)) j--; if(i<=j) { iTemp=pData[i]; pData[i]=pData[j]; pData[j]=iTemp; i++; j--; } }while(i<=j); if(left run(pData,left,j); if(right>i) run(pData,i,right); } voidQuickSort(int*pData,longCount) { run(pData,0,Count-1); } intmain(intargc,char*argv[]) { clock_tstart,end; //time_ta,b; charfstr[20]; intm_data[1024]; longcount=0; longsum=0; longavr; longi; FILE*m_file; if(NULL==argv[0]) { exit (1); } m_file=fopen(argv[0],"r"); if(m_file==NULL) { printf("error"); exit (1); } while(NULL! =fgets(fstr,20,m_file)) { m_data[count]=atoi(fstr); count++; } start=clock(); //a=time(NULL); QuickSort(m_data,count); end=clock(); printf("%6.3fseconds\n",(double)(end-start)/18.2); //b=time(NULL); for(i=0;i { printf("\n%d",m_data[i]); sum+=m_data[i]; } avr=sum/count; ◆建立单向、双向、循环链表,进行相应操作 structNode{ intdata;//数据域 structNode*next;//指针域 }; 单向: structNode { intdata; structNode*next; }; structNode*Create_Node(intn)//CreateaNode,nmeansithasnchildnode; { structNode*p=(structNode*)malloc(sizeof(Node));//Createamemoryspaceforstruct memset(p,NULL,sizeof(Node));//setthestruct’svalueNULL; if(n>1) { p->next=Create_Node(n-1);//ifthenodehaschild,thenmakethep’snextlinkthenextnode } returnp;//returnthenode’saddress } voidDelete_Node(structNode*node)//freetheallnodetables { if(node->next! =NULL) { Delete_Node(node->next); } node->next=NULL; free(node); } 双向: structMuNode { intdata; structMuNode*pre;//Pointertopointtopreviousnode structMuNode*next;//Pointertopointtonextnode }; structMuNode*Create_MuNode(intn,structMuNode*pre) { structMuNode*p=(structMuNode*)malloc(sizeof(Node)); memset(p,NULL,sizeof(Node)); p->pre=pre; if(n>1) { p->next=Create_MuNode(n-1,p); } returnp; } voidDelete_MuNode(structMuNode*node) { if(node->next! =NULL) { Delete_MuNode(node->next); } node->next=NULL; node->pre=NULL; free(node); } 循环链表 structNode{ intdata;//数据域 structNode*next;//指针域 }; structNode*Create_CycleNode(intn,structNode*head)//CreateaNode,nmeansithasnchildnode; { structNode*p=(structNode*)malloc(sizeof(Node));//Createamemoryspaceforstruct memset(p,NULL,sizeof(Node));//setthestruct’svalueNULL; if(n>1) { p->next=Create_Node(n-1);//ifthenodehaschild,thenmakethep’snextlinkthenextnode } else { p->next=head; } returnp;//returnthenode’saddress } voidDelete_CycleNode(structNode*node,structNode*head) { if(node->next! =head) { Delete_Node(node->next); } node->next=NULL; free(node); } ◆队列基本操作(入队,出队) 循环队列类型定义 #defineQueueSize100//应根据具体情况定义该值 typedefcharDataType;//DataType的类型依赖于具体的应用 typedefstruct{ intfront;//头指针,队非空时指向队头元素 intrear;//尾指针,队非空时指向队尾元素的下一位置 intcount;//计数器,记录队中元素总数 DataTypedata[QueueSize]; }CirQueue; voidInitQueue(CirQueue*Q)//初始化队列 { Q->front=0; Q->count=0; Q->rear=0; } intQueueEmpty(CirQueue*Q) { return(Q->count==0) } intQueueFull(CirQueue*Q) { return(Q->count==QueueSize); } voidEnQueue(CirQueuq*Q,DataTypex) { if(! QueueFull(CirQueue*Q)) { Q->data[Q->rear]=x; Q->rear=(Q->rear+1)%QueueSize; Q->count++; } else { error("TheQueueisFull! now! \n"); } } DataTypeDeQueue(CirQueue*Q) { DataTypetemp; if(QueueEmpty((Q)) Error("Queueunderflow")//队空下溢 temp=Q->data[Q->front]; Q->count--;//队列元素个数减1 Q->front=(Q->front+1)%QueueSize;//循环意义下的头指针加1 returntemp; } DataTypeQueueFront(CirQueue*Q) { if(! QueueEmpty) returnQ[Q->front]; else { error("Queueisempty"); } } ◆栈基本操作(入栈,出栈) #defineDataTypeint #defineMAXSIZE1024 typedefstruct { DataTypedata[MAXSIZE]; inttop; }SeqStack; SeqStack*Init_SeqStack()//栈初始化 { SeqStack*p=(SeqStack*)malloc(sizeof(SeqStack)); memset(p,NULL,sizeof(SeqStack)); returnp; } intEmpty_SeqStack(SeqStack*s)//判栈空 { return(s->top==0); } intPush_SeqStack(SeqStack*s,DataTypex)//入栈 { if(s->top { s->data[s->top]=x; return1 } else return0; } intPop_SeqStack(SeqStack*s,DataType*x)//出栈 { if(s->top>0) { *x=s->data[s->top]; s->top--; return1; } else return0; } DataTypeTop_SeqStack(SeqStack*s)//取栈顶元素 { if(s->top>0) returns->data[s->top]; else error("Stackisempty"); } ◆其他 编写一个自己的完全C语言版本的memset函数,并且评价这个实现的性能和可移植性。 void*memset(void*source,intch,unsignedn);) { char*p=(char*)source; assert(NULL! =source); while(n--) { *p++=(char)c; } returnsource; } ◆代码风格 下面是一个16x16的黑白图标: staticunsignedshortstopwatch【】={ 0x07c6, 0x1ff7, 0x383b, 0x600c, 0x600c, 0xc006, 0xc006, 0xdf06, 0xc106, 0xc106, 0x610c, 0x610c, 0x3838, 0x1ff0, 0x07c0, 0x0000, }; 如何修改声明,可以使之在源代码中形象地表现出图形的模样 //C编程专家 #defineX)*2+1 #define_)*2 #defines((((((((((((((((0 staticunsignedshortstopwatch[]= { s_____XXXXX___XX_, s___XXXXXXXXX_XXX, s__XXX_____XXX_XX, s_XX________XXX__, s_XX________XXX__, sXX___________XX_, sXX___________XX_, sXX_XXXXX_____XX_, sXX_____X_____XX_, sXX_____X_____XX_, s_XX____X____XX__, s_XX____X____XX__, s__XXX_____XXX___, s___XXXXXXXXX____, s_____XXXXX______, s________________, }; 第三阶段Linux用户态开发 5天左右 熟悉Linux用户态开发的基本概念,通过编写一些实验程序加深理解。 用户态编程学习内容 系统调用方式访问文件 库函数访问文件 时间编程 进程原理 进程控制程序设计 进程间通讯 管道 信号 共享内存 消息队列 信号量 多线程程序设计 socket编程(TCP,UDP) Linux用户态编程实验内容: 编写应用程序,创建一个可读可写的文件。 程序名: CreateFile #include #include #include
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 培训资料