200906
来源:互联网 发布:数空车床编程视频教程 编辑:程序博客网 时间:2024/06/13 06:25
一、填空题(共30空,每空1.5分)共45分
注:已知定义如下:
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
1、在全局变量、任务变量、局部变量、静态全局变量中,任何情况下都可以用于可重入函数的变量有 __ _____、 __
2、试题说明:阅读下面C语言代码,请在空格内填上相应的内容;
#include <malloc.h>
auto char gvChar;
volatile short gvShort;
unsigned int gvInt = 0x12345678;
const long gvLong = 0x87654321;
unsigned char * pChar = “Hello C”;
void main(void)
{
unsigned char array[10], *p;
p = malloc(10*sizeof(char));
... ... ...
}
试题要求:参考上述代码,如下变量分别存放在什么空间(如堆,栈,bss段,data段、代码段):
gvChar __ _______ gvShort _ __ _____
gvInt _ ______ _ gvLong _ ________
array ___ __ _ p _ ________
pChar _ _______ pChar所指向的字符串存放在 _ _______
3、某存储器芯片的位宽为16比特,共有16根地址线(不考虑地址复用的情况),该存储器的容量为 字节。
在内存中给某模块分配的临终遗言空间为0x90000~0x97FFF(内存按字节编址),则该模块的临终遗言空间大小为 _ _ 字节。
4、某16位的硬件寄存器A的地址可以用REG_A_ADDR表示,该寄存器可读可写,请用一个C语句在不影响其他比特的情况下将A寄存器的bit2和bit1(已知bit0为LSB)置1:
_________ ____________
再用一个C语句完成将A寄存器的bit2和bit1清零的操作(同样要求不影响其他比特):_________ ____________
另有一个16位的硬件寄存器B的地址用REG_B_ADR表示,该寄存器是一个告警状态寄存器,每个比特都表示一个特定的硬件异常状态,1表示有相应告警,0表示没有告警,因此读该寄存器的值就可以得到硬件异常的告警状态。此寄存器的每比特写1可以清除相应位的告警状态(写1清0),写0无效。请用一个C语句在不影响其他比特的情况下将B寄存器的bit1告警位清零:
__________ ____________
5、试题说明:有如下结构定义:
struct tagAbc
{
char cStr1;
short sStr2;
char cStr3;
long lStr4;
}*pstrAbc;
pAbc = 0x300000;
试题要求:请计算并填空(注:typedef unsigned long ULONG)
pstrAbc + 0x100 = _____
(ULONG) pstrAbc + 0x100 = _____
(ULONG *) pstrAbc + 0x100 = ____
(char *) pstrAbc + 0x100 = _____
6、有如下程序段:
#define MAX(a,b) ((a)>(b)?(a):(b))
...
X = 5;
Y = 8;
Z = MAX(x++,y++);
请填写该程序运行后X、Y、Z的值:
X = __ ___
Y = __ ___
Z = __ __
7、以太网通信中,如果通信双方中一端的工作模式(全双工/半双工)固定,另一端设置为自适应模式,那么不管固定一端是全双工还是半双工,自适应那端自适应出来的工作模式为
8、在32位嵌入式操作系统中,定义UINT32* g_pulStatus = 0x5a6b7c8d,请问:
在大模式(big-endian)时: *(UINT8*)g_pulStatus =
*(UINT16 *)g_pulStatus =
在小模式(little-endian)时: *(UINT8 *)g_pulStatus =
*(UINT16 *)g_pulStatus =
9、为了保证cache一致性,在必要的时候可以采用人工cache操作来保证数据的及时刷新。如在CPU“读”方向上,可以先使用 (请填写API函数名,简要描述也可以)然后再读来保证cache和内存的数据一致性,在CPU“写”方向上,可以先写数据然后使用 (请填写API函数名,简要描述也可以)保证cache和内存的数据一致性。
10、有如下定义:
union unFlag
{
struct
{
unsigned char ucMode ;
};
unsigned short usVal;
}unMyFlag;
那么unMyFlag占用了 __ ___位(bit)的内存大小
二、改错题(共5题,每错1~2分)共34分
1、试题说明:硬件驱动编程中,通常要等待硬件寄存器的状态翻转表明某项硬件功能已完成,才能进行后续的操作,请找出该段程序的错误之处。
#define BSP_READ_REG(addr) (*((UINT16 *)((UINT32)(addr))))
。。。。
while ((0 != ((BSP_ READ _REG(BSP_STATE_REG_ADRS)) & 0x01)))
{
/*延迟1 Us*/
。。。 。。。
}
。。。。
试题要求:请找出该段程序的1~2处错误或隐患(不考虑代码风格问题),不要求修正。
2、试题说明:如下程序段,函数NETDRV_PacketRecv主要完成数据包的接收处理,每次可以接收处理一个标准的MAC包。
试题要求:请找出该段程序的2~4处错误或隐患(不考虑代码风格问题),不要求修正。
01 UINT32 NETDRV_PacketRecv(UINT8 *pucBuf,UINT32 ulLen)
02 {
03 UINT32 ulReturn = NETDRV_ERROR; /*注:NETDRV_ERROR是已定义的正确宏 */
04
05 if (pucBuf = NULL)
06 {
07 return NETDRV_ERROR;
08 }
09
10 /* 对接收的数据包进行校验,此函数已经在前面进行了声明 */
11 ulReturn = NETDRV_VerifyPacket(UINT8 *pucBuf,UINT32 ulLen);
12
13 /* 接收包校验错误时丢弃包 */
14 if (NETDRV_ERROR == ulReturn)
15 {
16 printf("Verify packet error\n");
17
18 /* 丢包处理 */
19 ... ...
20
21 free(pucBuf);
22 }
23
24 /* 如果使能了接收包环回转发功能,则进行环回转发处理
25 注:此处宏和全局变量gulLoopFwdEnableFlag已经正确定义和初始化 */
26 if (NETDRV_LOOPFWD_ENABLE == gulLoopFwdEnableFlag)
27 {
28 ulReturn = NETDRV_LoopFwdPacket(UINT8 *pucBuf,UINT32 ulLen);
29 return (ulReturn);
30 }
31 else
32 {
33 /* 进行接收包处理,此函数已经在前面进行了声明 */
34 ulReturn = NETDRV_ProcessPacket(UINT8 *pucBuf,UINT32 ulLen);
35 return (ulReturn);
36 }
37 }
38
39 /* 此函数完成环回转发功能,即把收到的包调换源/目的地址后发送回去,
40 或者按照设置的目的地址进行转发 */
41 UINT32 NETDRV_LoopFwdPacket(UINT8 *pucBuf,UINT32 ulLen)
42 {
43 /* 如果是环回处理,则调换MAC地址并发送回去 */
44 if (... ...)
45 {
46 ... ...
47 }
48 else /*转发处理,填写目的MAC为已设置的转发MAC地址并发送*/
49 {
50 ... ...
51 }
52
53 /* 处理完后释放内存 */
54 if (... ...)
55 {
56 free(pucBuf);
57 }
58
59 return NETDRV_OK;
60 }
61
62 UINT32 NETDRV_VerifyPacket(UINT8 *pucBuf,UINT32 ulLen)
63 {
64 /* 如下代码完成接收包的校验判断功能 */
65 ... ...
66
67 return NETDRV_OK;
68 }
69
70 UINT32 NETDRV_ProcessPacket(UINT8 *pucBuf,UINT32 ulLen)
71 {
72 /* 如下代码完成接收包的解析,并根据不同的解析类型把
73 数据包拷贝一份送给上层应用软件 */
74 ... ...
75
76 return NETDRV_OK;
77 }
3、试题说明:如下程序段,挂接一个定时器中断,驱动sample任务运行,代码中用到的函数原型参考如下:
taskSpawn ( name, priority, options, stacksize, main, arg1, ... arg10 );
STATUS intConnect
(
VOIDFUNCPTR *vector, /* to attach */
VOIDFUNCPTR routine, /* to be called */
int parameter /* for the routine */
)
SEM_ID semMCreate
(
int options /* mutex semaphore options */
)
试题要求:请找出该段程序的2~3处错误或隐患(不考虑代码风格问题),不要求修正。
01 /*This example shows the use of semaphores for task synchronization*/
02 #include <vxWorks.h>
03 #include <semLib.h>
04 #include <arch/arch/ivarch.h>
05
06 SEM_ID syncSem; /* ID of sync semaphore */
07 init (int someIntNum)
08 {
09 /* connect interrupt service routine */
10 intConnect(INUM_TO_IVEC(someIntNum), eventInterruptSvcRout, 0);
11
12 /* create semaphore */
13 syncSem = semMCreate (SEM_Q_FIFO, SEM_EMPTY);
14
15 /* spawn task used for synchronization. */
16 taskSpawn ("sample", 100, VX_USER_MODE, 200, task1,
17 0,0,0,0,0,0,0,0,0,0);
18 }
19
20 task1 (void)
21 {
22 unsigned long testStat[400];
23 do
24 {
25 semTake (syncSem, WAIT_FOREVER); /*wait for event to occur*/
26 printf ("task 1 got the semaphore\n");
27
28 /* process event */
29 ... ...
30 }while(1)
31 }
32
33 eventInterruptSvcRout (void)
34 {
35 printf ("Give the semaphore\n");
36 semGive (syncSem); /* let task 1 process event */
37 }
4、试题说明:请分析如下代码,找出其中的错误之处。
01 unsigned char size = 100;
02 while (size-- >= 0)
03 {
04 int * p ;
05 unsigned char * q = NULL;
06
07 q = malloc(sizeof(char));
08 *p = 100 ;
09 *q = size;
10 if(*p != *q)
11 {
12 continue;
13 }
14 else
15 {
16 printf("\nwhen size is :%d,*p ==*q\n",size);
17 }
18 }
试题要求:请找出该段程序的3~5处错误或隐患(不考虑代码风格问题),不要求修正。
5、试题说明:在某单板上起一个任务不断地检测寄存器REG_ADDR中REG_BUSY_BITMASK位是否处于忙状态,根据忙闲状态进行做不同的处理,同时更新全局变量g_ulRegBusy,其它任务也会读写该全局变量,进行相应处理。函数原型参考:taskSpawn ( name, priority, options, stacksize, main, arg1, ... arg10 );
试题要求:请找出该段程序的6~9处错误或隐患(不考虑代码风格问题),不要求修正。
01 typedef unsigned char UINT8;
02 typedef unsigned short UINT16;
03 typedef unsigned int UINT32;
04 #define REG_ADDR 0xff001000
05 #define REG_BUSY_BITMASK 0x00001000
06 #define FALSE 0
07 #define TRUE 1
08 UINT32 g_ulRegBusy = TRUE;
09
10 void test()
11 {
12 UINT32 *ptr ;
13 UINT8 aucTemp[1000];
14 UINT8 ucCounter;
15 UINT16 usCounter = 0;
16
17 ptr = (UINT32 *)REG_ADDR;
18 while ( 1 )
19 {
20 /*硬件首先做一段延时处理*/
21 ucCounter = 200;
22 while ((ucCounter--) >= 0 )
23 {
24 /*空处理*/;
25 }
26
27 while (0 !=((*ptr)®_BUSY_BITMASK) )
28 {
29 g_ulRegBusy = TRUE;
30 }
31
32 /* 取出寄存器空间的值并存入数组中 */
33 aucTemp[++usCounter] = (*ptr)& 0xff;
34
35 if (usCounter > 1000 )
36 {
37 /*把aucTemp数组中的数据发送出去*/
38 ... ... ...
39
40 usCounter = 0;
41 }
42
43 g_ulRegBusy = FALSE;
44 }
45 }
46
47 void testInit()
48 {
49 taskSpawn("tTest", 20, 0, 1000, (FUNCPTR)test,0,0,0,0,0,0,0,0,0,0);
50 }
三、优化题(共1 题,每题6分)共6分
1、试题要求:如下代码的运行效率较低(不考虑编译器的自动优化),需要进行优化。请分析一下代码效率低的可能原因,并给出优化后的代码或者修改思路。
funx()
{
...
/* 注:ALM_LCBITEM_STRU是已经定义好的告警结构 */
for (ulLoop = 0; ulLoop < (sizeof(pstrAlarms->pLCBItem)/ sizeof(ALM_LCBITEM_STRU)); ulLoop ++)
{
/*注:pstrAlarms为全局结构指针*/
pstrAlarms -> pLCBItem[ulLoop].ulPreviousIndex = ulLoop - 1;
pstrAlarms -> pLCBItem[ulLoop].ulNextIndex = ulLoop + 1;
pstrAlarms -> pLCBItem[ulLoop].bIdleFlag = VOS_TRUE;
}
...
}
四、编程题(共1 题,每题15分)共15分
1、试题说明:栈(Stack)结构是计算机语言实现中的一种重要数据结构。对于任意栈,进行插入和删除操作的一端称为栈顶(Stack Top),而另一端称为栈底(Stack Bottom)。栈的基本操作包括:创建栈(NewStack)、 判断栈是否为空(IsStackEmpty)、判断栈是否已满(IsStackFull)、获取栈顶数据(GetStackTop)、压栈/入栈(PushStack)、弹栈/出栈(PopStack)。
当设计栈的存储结构时,可以采取多种方式。此处采用链式存储结构实现一个整数栈操作,栈结构定义如下:
typedef struct List
{
int data; // 栈数据
struct List* next; // 上次入栈的数据地址
}List;
typedef struct Stack
{
List* pTop; // 当前栈顶指针
}Stack;
现给出一个函数示例供参考:
(1)创建栈: 函数定义为 Stack* NewStack(void)
Stack* NewStack()
{
return (Stack*)calloc(1,sizeof(Stack));
}
试题要求:请编写栈的基本操作函数,具体函数定义如下:
判断栈是否为空:函数定义为 int IsStackEmpty(Stack* pstrStack)
函数功能描述:判断pstrStack指向的堆栈是否为空
已知如下宏定义:
#define FALSE 0
#define TRUE 1
压栈/入栈: 函数定义为 void PushStack(Stack* pstrStack, int iTheData)
函数功能描述:将数据iTheData压入pstrStack指向的堆栈
- 200906
- 200906~200908
- Mandriva 200904--200906
- 200906 每日一句(By 宇宙老人)
- 200706-200903-200906-200911-201006-201008-201103....
- Best Practice to Set OpenSolaris 200906 as xvm domain 0
- 200906期 -在敏捷中我不愿被称为架构师
- 高手Java核心技术学习笔记 http://developer.51cto.com/art/200906/129191.htm
- Zero Clipboard - 跨浏览器兼容的“复制到剪贴板”功能
- 201003
- 如何打造像样的应用日志——10条秘诀
- 200910
- Shell 获取当前执行脚本的路径
- 200906
- 黑马程序员 面对对象(二)
- zip打包,unzip解包
- 从此记录我的ACM生涯
- iOS里的MVC
- 简明 Vim 练级攻略
- 数据库 变量查询 字符串转换
- Android 关机流程分析-----(2)JNI和kernel层
- 输入输出外挂