山东建筑大学计算机学院嵌入式复习资料

更新时间:2024-01-01 21:19:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

大题

1、控制LED亮灭 void Port_Init() {

rPDATC = 0xFC00; //1111 1100 0000 0000B

rPCONC = 0x0FF5FF55; // 0101:PC9/8: Output(01) rPUPC = 0x30FF; //PC9/8上拉:00

rPDATF = 0xE7; //0000 0000 1110 0111B rPCONF= 0x24914A; //PF4/3 Output(01) rPUPF= 0x6; //PF4/3上拉 }

void LED_Display(int nLedStatus) {

if((nLedStatus & 0x01) == 0x01) rPDATC &= 0xFEFF; //PC8=0, LED1亮 else rPDATC |= (1 << 8); //0x0100, PC8=1, LED1灭 if((nLedStatus & 0x02) == 0x02) rPDATC &= 0xFDFF;

else

rPDATC |= (1 << 9); if((nLedStatus & 0x04) == 0x04) rPDATF &= 0xEF; else rPDATF |= (1<<4); if((nLedStatus & 0x08) == 0x08) rPDATF &= 0xF7; else

rPDATF |= (1<<3); }

void Main() {

Port_Init(); while(1) { LED_Display(0x0F);//全亮 Delay(1000);//延迟1000毫秒(节拍) LED_Display(0x00);//全灭 Delay(1000);//延迟1000毫秒(节拍) } }

2、某嵌入式系统采用S3C44B0X为微控制器,主时钟为66MHZ,采用定时器0产生定时中断,定时间隔为0.5秒,在定时中断服务子程序中通过端口PC2和PC4控制两个LED的闪烁,所有中断均为IRQ中断,采用矢量中断模式,试编写相应的主程序(含初始化部分)和定时器0中断服务子程序(所编写的程序访问寄存器时,只能影响相应寄存器中相应的比特位,无关位均为0)。 void Init_Timer(void) {

rTCFG0 = 0x00000041; (0x41)//预分频65 rTCFG1 = 0x00000004; (0x04)//mux0 = 1/32 rTCNTB0 = 15625; //0.5秒 rTCON = 0x02; rTCON = 0x09; }

void Init_Int(void) {

rINTMOD = 0x0; //设置中断为IRQ中断 rINTCON = 0x1; //设置中断为矢量中断模式 pISR_Timer0 = (S32)Timer0_ISR; //设置Timer0的ISR入口地址 rINTMSK &= (~(0x1<<26 | 0x1<<13)); //使能Timer0中断 }

void Init_Prot(void) {

rPCONC = 0x0110; rPDATC = 0x0014; rPUPC = 0x0000; }

bool bLEDON = 0; void Timer0_ISR() {

rI_ISPC |= 0x1<<13; if(bLEDON == 0)

{ rPDATC &= (~(0x1<<2 | 0x1<<4)); bLEDON = 1; } else { rPDATC |= (0x1<<2 | 0x1<<4);

bLEDON = 0; } }

void main(void) {

Init_Timer();

Init_Int(); Init_Prot(); while(1){} }

3、已知某嵌入式系统中,任务A的优先级为(11)D。

(1)若当前的OSRdyGrp=(07)H,OSRdyTbl[0]=(1F)H,OSRdyTbl[1]=(B5)H,OSRdyTbl[2]=(08)H,OSRdyTbl[3]=(00)H,试分析任务A就绪后的OSRdyGrp和OSRdyTbl[0]~OSRdyTbl[3]的值。 (2)如果当前的OSRdyGrp=(0E)H,OSRdyTbl[0]=(00)H,OSRdyTbl[1]=(18)H,OSRdyTbl[2]=(C2)H,OSRdyTbl[3]=(AB)H,试分析任务A进入挂起态后的OSRdyGrp和OSRdyTbl[0]~OSRdyTbl[3]的值。 解:y=11/8=1, x=11%8=3

(1)

OSRdyGrp=(07)H:0000 0111 (课得出最高优先等级在Y = 0的组内) OSRdyTbl[1]=(B5)H ->(BD)H

OSRdyTbl[0]、 OSRdyTbl[2]、 OSRdyTbl[3]不变 (2)

OSRdyGrp=(0E)H:0000 1110 (得出Y = 1)

OSRdyTbl[1]=(18)H->10H:0001 1000 任务11挂起,那么就变为0,12就绪 OSRdyTbl[0]、 OSRdyTbl[2]、 OSRdyTbl[3]不变

4、已知某嵌入式系统经过一段时间的运行后,OSRdyGrp=(22)H,OSRdyTbl[1]=(64)H,OSRdyTbl[5]=(F0)H,试分析这时的最高就绪态任务的优先级为何值。

解:因为OSRdyGrp=(22)H = 00100010B,故y=1

又因为OSRdyTbl[1]=(64)H = 01100100B,所以x=2 故prio=y*8+x=10

5、试用uC/OS-II编写一个实时控制系统的程序,要求创建4个任务,其中两个任务利用信号量实现对某一共享资源的互斥,另外两个任务之间利用消息邮箱传递消息。

OS_STK Task1Stk[TASK_STK_SIZE]; OS_STK Task2Stk[TASK_STK_SIZE]; OS_STK Task6Stk[TASK_STK_SIZE]; OS_STK Task7Stk[TASK_STK_SIZE]; OS_EVENT *SemECB; //定义信号量 OS_EVENT *MboxECB; //定义邮箱 void Task1 (void *pdata) {

INT8U err; for (;;) {

OSSemPend(SemECB, 10, &err); //等待一个信号 printf(\OSSemPost(SemECB); //发送一个信号量 } }

void Task2 (void *pdata) {

for (;;) {

OSSemPend(SemECB, 10, &err);

//等待一个信息

printf(\ OSSemPost(SemECB); //发送一个信息 } }

void Task6 (void *pdata) {

INT8U err; void * msg; for (;;) {

printf(\ msg =OSMboxPend(MboxECB, 10, &err);

//等待一个邮箱中的信息

printf(\‘s%’!\\n, msg \ OSTimeDly(166); //延时函数 } }

void Task7 (void *pdata) {

for (;;) {

printf(\

OSMboxPost(MboxECB, (void*)”How are you?”); //发送一个信息到邮箱中

OSTimeDly(166); } }

void main (void) {

OSInit();

SemECB = OSSemCreate(1); //建立一个信号量 MboxECB = OSMboxCreate((void *)0); //建立一个邮箱 /* 创建任务 */

OSTaskCreate(Task1, (void *)'1', &Task1Stk[TASK_STK_SIZE - 1], 1); OSTaskCreate(Task2, (void *)'2', &Task2Stk[TASK_STK_SIZE - 1], 2); OSTaskCreate(Task6, (void *)'6', &Task6Stk[TASK_STK_SIZE - 1], 6); OSTaskCreate(Task7, (void *)'7', &Task7Stk[TASK_STK_SIZE - 1], 7); OSStart(); }

任务堆栈初始化:

OS_STK *OSTaskStkInit (void (*task), void *pdata, OS_STK *ptos, INT16U opt) {

OS_STK *stk;

stk = ptos; /* 载入堆栈指针 */ *(stk) = (OS_STK)task; /* Entry Point */ *(--stk) = (INT32U)0; /* lr */ *(--stk) = (INT32U)0; /* r12 */ *(--stk) = (INT32U)0; /* r11 */ *(--stk) = (INT32U)0; /* r10 */ *(--stk) = (INT32U)0; /* r9 */ *(--stk) = (INT32U)0; /* r8 */ …… /* r7-r1 */

*(--stk) = (INT32U)pdata; /* r0 : argument */ *(--stk) = (INT32U)(SVC32MODE|0x0); /* CPSR */ *(--stk) = (INT32U)(SVC32MODE|0x0); /* SPSR */ return (stk); }

任务切换函数OSCtxSw和OSIntCtxSw OSCtxSw:

stmfd sp!,{lr} //lr入栈

stmfd sp!,{r0-r12,lr} //将r0~r7,lr入栈,sp指向r0

mrs r4,cpsr //将cpsr(状态寄存器)的值拷贝到通用寄存器r4中 stmfd sp!,{r4} //sp指针指向r4,(r4的地址给sp)

mrs r4,spsr //将spsr的内容拷贝到通用寄存器r4中 stmfd sp!,{r4}

/* 获得当前任务TCB的地址 */

ldr r4,=OSTCBCur //获取OSTCBCur的地址,存放到r4中 ldr r5,[r4] //读取r4中的内容(地址)给r5

str sp,[r5] //将被特权模式的栈顶指针保存到中断任务的OSTCBStrkptr中 OSIntCtxSw:

bl OSTaskSwHook //调用任务开关

/* 将最高就绪态任务给OSTCBCur */

ldr r6,=OSTCBHighRdy //获得最高优先级任务TCB的地址 ldr r6,[r6] //读取r6中的内容

ldr sp,[r6] //得到新任务的堆栈指针,将r6中数据读入到sp str r6,[r4] //将r4中的内容给r6

/* 将最高就绪态任务给OSTCBCur */ ldr r4,=OSPrioCur

ldr r5,=OSPrioHighRdy ldrb r6,[r5] strb r6,[r4]

ldmfd sp!,{r4} //取出新的任务spsr (从堆栈中恢复) msr SPSR_cxsf,r4

ldmfd sp!,{r4} //取出新的任务spsr msr CPSR_cxsf,r4

ldmfd sp!,{r0-r12,lr,pc} //恢复r0~r12,lr,pc

任务切换函数OSCtxSw和OSIntCtxSw OSCtxSw:

stmfd sp!,{lr} //lr入栈

stmfd sp!,{r0-r12,lr} //将r0~r7,lr入栈,sp指向r0

mrs r4,cpsr //将cpsr(状态寄存器)的值拷贝到通用寄存器r4中 stmfd sp!,{r4} //sp指针指向r4,(r4的地址给sp)

mrs r4,spsr //将spsr的内容拷贝到通用寄存器r4中 stmfd sp!,{r4}

/* 获得当前任务TCB的地址 */

ldr r4,=OSTCBCur //获取OSTCBCur的地址,存放到r4中 ldr r5,[r4] //读取r4中的内容(地址)给r5

str sp,[r5] //将被特权模式的栈顶指针保存到中断任务的OSTCBStrkptr中 OSIntCtxSw:

bl OSTaskSwHook //调用任务开关

/* 将最高就绪态任务给OSTCBCur */

ldr r6,=OSTCBHighRdy //获得最高优先级任务TCB的地址 ldr r6,[r6] //读取r6中的内容

ldr sp,[r6] //得到新任务的堆栈指针,将r6中数据读入到sp str r6,[r4] //将r4中的内容给r6

/* 将最高就绪态任务给OSTCBCur */ ldr r4,=OSPrioCur

ldr r5,=OSPrioHighRdy ldrb r6,[r5] strb r6,[r4]

ldmfd sp!,{r4} //取出新的任务spsr (从堆栈中恢复) msr SPSR_cxsf,r4

ldmfd sp!,{r4} //取出新的任务spsr msr CPSR_cxsf,r4

ldmfd sp!,{r0-r12,lr,pc} //恢复r0~r12,lr,pc

本文来源:https://www.bwwdw.com/article/thdx.html

Top