为确保代码临界区的执行,在进入临界区之前要关中断,而临界区代码执行完以后要立即开中断(在任务切换时,地址、指令、数据等寄存器堆栈保护)。(2分)
12、 简要叙述嵌入式系统开发流程。 参考答案及要点: 建立开发环境; 配置开发主机;
建立引导装载程序BOOTLOADER; 下载已经移植好的操作系统; 建立根文件系统; 开发应用程序。
13、 试简述常用的三极管放大电路和技术特点。
答:共射电路:具有较大的电压放大倍数和电流放大倍数,输入电阻和输出电阻适中。 共集电路:输入电阻大,输出电阻小,电压放大倍数小于1。 共基电路:输入电阻小,频率特性好。
14、 嵌入式系统的软件层次结构包括哪些部分?简单说明各部分的功能与作用。 答:驱动层程序、操作系统、应用程序接口和应用程序。 驱动层程序:为上层软件提供设备的操作接口。 操作系统:进程管理、进程间通信、内存管理等。
应用程序接口:复杂函数和数据结构的集合,简化应用程序的开发。 应用程序:实现用户功能。
五、 阅读程序题
1、根据以下程序回答问题。 struct NODE {int k;
struct NODE *link; }; main()
{ struct NODE m[5],*p=m,*q=m+4; int i=0;
while(p!=q) {p->k=++i;p++; q->k=i++;q--; }
q->k=i;
for(i=0;i<5;i++)printf(\ printf(\ }
(1)i、p、struct NODE和m的分别占据多少字节的内存空间?(4分) (2)p和q指针初始指向的地址相差多少字节?(4分) (3)程序运行后的输出结果是什么?(4分)
参考答案及要点:
(1)i、p、struct NODE和m的分别占据4字节、4字节、8字节和40字节的内存空间。 (2)p和q指针初始指向的地址相差32字节 (3)程序运行后的输出结果13431。
2、在分辨率为320x240的LCD上,执行完下列程序后,画出在LCD上显示的图形并在划横线处添加注释。
void Main_Task(void *Id) { }
答:
int oldx,oldy; PDC pdc; ClearScreen(); pdc=CreateDC();
SetDrawOrg(pdc, LCDWIDTH/2,LCDHEIGHT/2, &oldx, & oldy); Circle(pdc,0, 0, 50); //_________________________ MoveTo(pdc, -50, -50);// _________________________ LineTo(pdc, 50, -50);// _________________________
ArcTo(pdc, 80, -20, TRUE, 30); //_________________________ LineTo(pdc, 80, 20);
ArcTo(pdc, 50, 50, TRUE, 30); LineTo(pdc, -50, 50);
ArcTo(pdc, -80, 20, TRUE, 30); LineTo(pdc, -80, -20);
ArcTo(pdc, -50, -50, TRUE, 30); OSTimeDly(3000);
320x240的LCD
(0.5分
以原点为圆心,50为半径画圆
画笔移动到坐标(-50,-50)处 (0.5分) 从坐标(-50, -50)到(50, -50)画直线 (0.5分)
从当前坐标开始以30为半径顺时针画圆弧到坐标(80, -20) (0.5分)
3、在划线处添加代码,完成下面的程序,实现在task1中计算1到10的平均值,完成后
向task2发送信号量。Task2无限期等待信号量,等到后在LCD上显示收到平均值。 ___ OS_EVENT *math_Sem;__;
Void Task1()
{ int i ,average=0,sum=0; __ math_Sem=OSSemCreate(0);__ for(i=1;i<=10;i++) {
sum=sum+i; }
average=sum/10; _ OSSemPost(math_Sem);__;
for(;;)
{ OSTimeDly(100);}
}
void task2() { __ U8 err; ___;
for(;;)
{ _ OSSemPend(math_Sem,0,&err);_ ;
LCD_printf(\!\\n\
}
}
____ OSTimeDly(100);__ ;
4、在划横线处添加代码,完成下面创建一个任务的过程,要求优先级为36,任务栈大小为256。
OS_STK task1_Stack [256]={0, }; void task1 (void *Id); #define task1_Prio 36 OSInit() ; //操作系统初始化
OSTaskCreate (task1,(void *)0,(OS_STK *)&task1_Stack[256-1],task1_Prio); OSStart() ;//操作系统任务调度开始
5、ARM指令集的每一条指令都是4字节的,下面是一段中断入口程序,在空白处填上该中断的类型和中断向量。
ENTRY B B B B B
Startup
; ; ; ; ;
复位中断,0x00 1分 未定义指令中断,0x04 软中断,0x08
1分
1分
UndefHandle SWIHandle
PAbtHandle DAbtHandle
预取中止,0x0C 1分
数据中止,0x00000010
NOP; B B
; 系统保存未用,0x00000014 ; ;
IRQ中断,0x18 快速中断,0x1C 1分 1分 IRQHandle FIQHandle
6、下面的程序描述了键盘消息的创建和使用过程,认真阅读并在划横线的地方添加适当的注释。
void Key_Scan_Task(void *Id)//按键扫描任务 {
U32 key; INT8U err; POSMSG pmsg; for (;;){
OSMboxPend(Key_MailBox, 0, &err); //__请求键盘邮箱 1分
key=Zlg7289_ReadKey();
pmsg=OSCreateMessage(NULL, OSM_KEY,KeyBoard_Map[key],0);
;//__请求到表示有键按下的邮箱 1分
}
void Main_Task(void *Id) //接收键盘消息的任务 {
POSMSG pMsg=0;//创建消息结构 for(;;) {//死循环
pMsg=WaitMessage(0); //___发送消息 1分
switch(pMsg->Message){ //___判断消息的类型 1分
}
if(pmsg)
SendMessage(pmsg); //_创建消息
1分
case OSM_KEY://键盘消息
LCD_printf(\向液晶屏输出
}
}
break; }
DeleteMessage(pMsg) ; //___删除消息 1分
7、三个任务代码如下,其中task1、task2、task3的优先级分别为:29、36,48。分析LCD上的显示结果。
Void task1() {
ClearScreen();
LCD_Printf(“task1 is running!\\n”); OSTimeDly(500); }
Void task2() {
ClearScreen();