linux培训学校

更新时间:2022-11-27 17:29:56 阅读: 评论:0


2022年11月27日发(作者:激活码英文)

linux培训资料

上海核心信息技术

Version0.02(2011.03)

名目

课程介绍.................................................................................................................................1

课程大纲.................................................................................................................................2

第一时期Linux开发基础..............................................................................................2

第二时期嵌入式C语言编程强化..................................................................................3

第三时期Linux用户态开发........................................................................................16

第四时期Linux内核态及驱动开发.............................................................................19

第五时期软件开发流程...............................................................................................20

课程介绍

本课程旨在发觉具备开发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/2///.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)一个指向指针的的指针,它指向的指针是指向一个整型数(Apointertoa

pointertoaninteger)

d)一个有10个整型数的数组(Anarrayof10integers)

e)一个有10个指针的数组,该指针是指向一个整型数的(Anarrayof10pointers

tointegers)

f)一个指向有10个整型数数组的指针(Apointertoanarrayof10integers)

g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(Apointerto

afunctionthattakesanintegerasanargumentandreturnsaninteger)

h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回

一个整型数(Anarrayoftenpointerstofunctionsthattakeanintegerargumentand

returnaninteger)

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

el

puts("Gotavalidpointer");//2

输出2

那个地点,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时刻等等。那个主题差不

多在ESP杂志中被广泛地讨论过了(要紧是r,他的说明远远超过我那个地点能提到

的任何说明),所有回过头看一下这些杂志吧!

。。。。free

这是一个有味的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的

指针之后,我才想到那个问题。这确实是上面的代码,该代码的输出是“Gotavalidpointer”。

我用那个来开始讨论如此的一问题,看看被面试者是否想到库例程如此做是正确。

f在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.3fcondsn",(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

memt(p,NULL,sizeof(Node));//tthestruct’svalueNULL;

if(n>1)

{

p->next=Create_Node(n-1);//ifthenodehaschild,thenmakethep’snextlinkthe

nextnode

}

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));

memt(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,nmeansit

hasnchildnode;

{

structNode*p=(structNode*)malloc(sizeof(Node));//Createamemoryspaceforstruct

memt(p,NULL,sizeof(Node));//tthestruct’svalueNULL;

if(n>1)

{

p->next=Create_Node(n-1);//ifthenodehaschild,thenmakethep’snextlinkthe

nextnode

}

el

{

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++;

}

el

{

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];

el

{

error("Queueimpty");

}

}

◆栈差不多操作(入栈,出栈)

#defineDataTypeint

#defineMAXSIZE1024

typedefstruct

{

DataTypedata[MAXSIZE];

inttop;

}SeqStack;

SeqStack*Init_SeqStack()//栈初始化

{

SeqStack*p=(SeqStack*)malloc(sizeof(SeqStack));

memt(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

}

el

return0;

}

intPop_SeqStack(SeqStack*s,DataType*x)//出栈

{

if(s->top>0)

{

*x=s->data[s->top];

s->top--;

return1;

}

el

return0;

}

DataTypeTop_SeqStack(SeqStack*s)//取栈顶元素

{

if(s->top>0)

returns->data[s->top];

el

error("Stackimpty");

}

◆其他

编写一个自己的完全C语言版本的memt函数,同时评判那个实现的性能和可移植性。

void*memt(void*source,intch,unsignedn);)

{

char*p=(char*)source;

asrt(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

#include

#include

voidcreate_file(char*filename){

if(creat(filename,0755)<0){

printf("createfile%sfailure!n",filename);

exit(EXIT_FAILURE);

}el{

printf("createfile%ssuccess!n",filename);

}

}

intmain(intargc,char*argv[]){

inti;

if(argc<2){

perror("youhaven'tinputthefilename,pleatryagain!n");

exit(EXIT_FAILURE);

}

for(i=1;i

create_file(argv[i]);

}

exit(EXIT_SUCCESS);

}

执行命令:gccCreateFile–oCreateFile

./CreateFile

使用库函数,实现文件拷贝的功能

猎取本地时刻,以字符串方式显示

编写一应用程序,在程序中创建一子进程,分别在父进程和子进程中打印进程ID

使用vfork创建一子进程,分别在父进程和子进程中打印进程ID,观看父子进程的运行顺序

使用execl函数创建一个文件

编写一应用程序,在程序中创建一子进程,父进程需等待子进程运行终止后才能执行

在父进程中创建一个无名管道,并创建子进程来读该管道,父进程来写该管道

启动A进程,创建一有名管道,并向其写入一些数据;启动B进程,从A创建的有名管道中

读出数据

在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号

启动A进程,创建一共享内存,并向其写入一些数据;启动B进程,从A创建的共享内存中

读出数据

创建一消息队列,实现向队列中存放数据和读取数据

编写应用程序,创建一线程,并向该线程处理函数传递一结构

编写应用程序,创建一线程,父进程需要等待该线程终止后才能连续执行

编写应用程序,创建一线程,使用pthread_cleanup_push和pthread_cleanup_pop进行退出

爱护

编写使用TCP协议的服务器程序;编写使用TCP协议的客户端程序;客户端向服务器发送字

符串,服务器打印收到的字符串

编写使用UDP协议的服务器程序;编写使用UDP协议的客户端程序;客户端向服务器发送字

符串,服务器打印收到的字符串

第四时期Linux内核态及驱动开发

5天左右

熟悉Linux内核态和驱动开发的差不多概念,通过编写一些实验程序加深明白得。

学习内容:

进程地址空间

内核地址空间

Linux内核链表

Linux内核定时器

Linux系统调用

Proc文件系统

内核专门分析

字符设备驱动

驱动中的竞争与互斥

ioctl设备操纵

内核等待队列

堵塞形字符设备驱动

poll设备方法

实验:

编写内核模块,在模块中使用kmalloc分配内存并访问

编写内核模块,在模块中使用页方式分配内存并访问

编写内核模块,在模块中创建一链表,遍历该链表,删除链表中的结点

编写内核模块,在模块中启动一定时器,5秒钟超时,超时后任意打印一条信息

修改内核,在内核中增加一个实现乘法的系统调用,编写应用程序,使用该系统调用

编写内核模块,实现一可读可写的Proc文件

编写实现了读写,定位功能的字符设备驱动程序;编写应用程序,测试驱动

基于上述驱动程序,加入竞争操纵

基于上述驱动程序,加入ioctl的支持;设计应用程序,测试ioctl功能

基于上述驱动程序,进行读写改造,将读写实现成堵塞方式

基于上述驱动程序,添加poll设备方法;设计应用程序,测试驱动程序的poll操作

第五时期软件开发流程

3天左右

本课程时期熟悉软件开发通用流程,机能设计、概要设计、详细设计、单体测试、结合测试、

集成测试。熟悉类图,交互图,状态图。

本文发布于:2022-11-27 17:29:56,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/32340.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图