我最近在学习将UC0S移植到S3C2410上,是ARM9,在网上下的别人的移植的代码,自己稍加修改,可以跑多个任务,我想,既然是操作系统移植到ARM板上,就可以管理外部硬件资源了,之前我在裸板上有个按键控制LED亮灭的程序,我想添加个任务,用UCOS来管理这个外部中断事件,我开始的想法是,新建立一个任务,在任务里将按键控制灯的程序放在这个任务里面就可以管理了,我建立2个任务,程序代码大概如下: void APP_vMain (void) { OSInit(); OSTaskCreate(TaskStart1, (void *)0, (void *)&TaskStartStk1[TASK_STK_SIZE - 1], 3); OSTaskCreate(TaskStart2, (void *)0, (void *)&TaskStartStk2[TASK_STK_SIZE - 1], 6); FRMWRK_vStartTicker(OS_TICKS_PER_SEC); /* os_cfg.h */ //OS_TICKS_PER_SEC=100 用看门狗定时器创建时钟 OSStart(); /* Start multitasking */ } extern U8 i=0; void TaskStart1 (void *data) { data = data; // Prevent compiler warning while(1) { if(i==1){ printf("Run Task1\n"); i=0; } OSTimeDly(50); } } void TaskStart2 (void *data) { data = data; // Prevent compiler warning while(1) { if(i==0) { Key_Scan_Test( ); //按键中断的程序 } // OSTimeDly(50); } } void Key_Scan_Test( void ) { KeyScanInit() ; rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((0<<22)|(0<<6)) ; //GPG11,3 set input rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((0<<4)|(0<<0)) } void KeyScanInit(void) { rGPGCON = rGPGCON & (~((3<<12)|(3<<4))) | ((1<<12)|(1<<4)) ; //GPG6,2 set output rGPGDAT = rGPGDAT & (~((1<<6)|(1<<2))); //GPG6,2 output 0 rGPECON = rGPECON & (~((3<<26)|(3<<22))) | ((1<<26)|(1<<22)); //GPE13,11 set output rGPEDAT = rGPEDAT & (~((1<<13)|(1<<11))); //GPE13,11 output 0 rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((2<<22)|(2<<6)) ; //GPG11,3 set EINT rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((2<<4)|(2<<0)) ; //GPF2,0 set EINT rEXTINT0 &= ~(7|(7<<8)); rEXTINT0 |= (2|(2<<8)); //set eint0,2 falling edge int //rEXTINT0=0x22222020;// eint0,2低电平 rEXTINT1 &= ~(7<<12); rEXTINT1 |= (2<<12); //set eint11 falling edge int rEXTINT2=0x22224020;// eint19高电平触发 rEINTPEND |= (1<<11)|(1<<19); //clear eint 11,19 rEINTMASK &= ~((1<<11)|(1<<19)); //enable eint11,19 ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23); pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)KeyISR; EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT8_23); } static void __irq KeyISR(void) //中断服务程序 { U8 key ; rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((0<<22)|(0<<6)) ; //GPG11,3 set input rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((0<<4)|(0<<0)) ; //GPF2,0 set input rGPFCON = rGPFCON|0x5500; //设置GPF[7:4]为输出 if(rINTPND==BIT_EINT8_23) { ClearPending(BIT_EINT8_23); if(rEINTPEND&(1<<11)) { rGPFDAT =0x3F; //LED亮 Delay( 5000 ) ; Beep( 2000, 5000 ) ; //第一个参数是频率(freq),第二个参数是时间(ms) puts("Interrupt eint11 occur..."); puts("\nEINT11触发,LED9,LED10亮!!!\n"); rEINTPEND |= 1<< 11; } if(rEINTPEND&(1<<19)) { puts("Interrupt eint19 occur..."); rGPFDAT =0x7F; //LED亮 Delay( 5000 ) ; putch('\n'); rEINTPEND |= 1<< 19; } } else if(rINTPND==BIT_EINT0) { puts("Interrupt eint0 occur..."); rGPFDAT =0xEF; Beep( 2000+pwm_dac, 2000 ) ; ClearPending(BIT_EINT0); } else if(rINTPND==BIT_EINT2) { puts("Interrupt eint2 occur..."); rGPFDAT =0xDF; Delay( 5000 ) ; Beep( 2000, 3000 ) ; //第一个参数是频率(freq),第二个参数是时间(ms) puts("\nEINT2 触发, LED11亮!!!\n"); ClearPending(BIT_EINT2); } i=1; printf("i=%d\n",i); //重新初始化IO口 rGPGCON = rGPGCON & (~((3<<12)|(3<<4))) | ((1<<12)|(1<<4)) ; //GPG6,2 set output rGPGDAT = rGPGDAT & (~((1<<6)|(1<<2))); //GPG6,2 output 0 rGPECON = rGPECON & (~((3<<26)|(3<<22))) | ((1<<26)|(1<<22)); //GPE13,11 set output rGPEDAT = rGPEDAT & (~((1<<13)|(1<<11))); //GPE13,11 output 0 rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((2<<22)|(2<<6)) ; //GPG11,3 set EINT rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((2<<4)|(2<<0)) ; //GPF2,0 set EINT } TASK1的优先级高于TASK2,但是,我设了个全局变量 i,初始化为0,i=1时TASK1才会运行,所以会先运行TASK2,我在TASK2中的Key_Scan_Test( )里面的中断服务程序void __irq KeyISR(void)中设了只要触发按键中断全局变量i才会等于1,也就是说,只有触发按键中断后让i=1后TASK1才会有可能运行。 可是当我实际运行的时候,我触发按键中断,却看到超级终端上一直在打印消息 i=1,任务不能切换。 会不会是我的方法有问题,如果是,应该怎么样处理呢?? 我刚学习不久,希望大神支招................ 我还有如下问题: 1、就是将UCOS移植到ARM9上,不管移植到哪个平台上,怎样才能算移植完成,是不是移植后能跑多个任务就算完成了(不加想我这样管理外部硬件资源),还是说需要通过假如外部硬件资源来检测...... 2、UCOS移植到ARM9上,无外乎修改三个文件。我的OS_CPU.S文件中有些不理解,望指教: ;********************************************************************************************************* ; IRQ HANDLER ; ; This handles all the IRQs ; Note: FIQ Handler should be written similar to this ; ;********************************************************************************************************* IMPORT C_IRQHandler IMPORT OSIntEnter IMPORT OSIntExit IMPORT OSIntCtxSwFlag IMPORT OSTCBCur IMPORT OSTaskSwHook IMPORT OSTCBHighRdy IMPORT OSPrioCur IMPORT OSPrioHighRdy NOINT EQU 0xc0 EXPORT UCOS_IRQHandler UCOS_IRQHandler stmfd sp!,{r0-r3,r12,lr} bl OSIntEnter bl C_IRQHandler bl OSIntExit ldr r0,=OSIntCtxSwFlag ldr r1,[r0] cmp r1,#1 beq _IntCtxSw ldmfd sp!,{r0-r3,r12,lr} subs pc,lr,#4 _IntCtxSw mov r1,#0 str r1,[r0] ;OSIntCtxSwFlag = 0;清零 ldmfd sp!,{r0-r3,r12,lr} stmfd sp!,{r0-r3} mov r1,sp add sp,sp,#16 sub r2,lr,#4 mrs r3,spsr orr r0,r3,#NOINT msr spsr_c,r0 ldr r0,=.+8 movs pc,r0 stmfd sp!,{r2} ; push old task's pc stmfd sp!,{r4-r12,lr} ; push old task's lr,r12-r4 mov r4,r1 ; Special optimised code below mov r5,r3 ldmfd r4!,{r0-r3} stmfd sp!,{r0-r3} ; push old task's r3-r0 stmfd sp!,{r5} ; push old task's psr mrs r4,spsr stmfd sp!,{r4} ; push old task's spsr ; OSPrioCur = OSPrioHighRdy ldr r4,=OSPrioCur ldr r5,=OSPrioHighRdy ldrb r5,[r5] strb r5,[r4] ; Get current task TCB address ldr r4,=OSTCBCur ldr r5,[r4] str sp,[r5] ; store sp in preempted tasks's TCB bl OSTaskSwHook ; call Task Switch Hook ; Get highest priority task TCB address ldr r6,=OSTCBHighRdy ldr r6,[r6] ldr sp,[r6] ; get new task's stack pointer ; OSTCBCur = OSTCBHighRdy str r6,[r4] ; set new current task TCB address ldmfd sp!,{r4} ; pop new task's spsr msr SPSR_cxsf,r4 ldmfd sp!,{r4} ; pop new task's psr msr CPSR_cxsf,r4 ldmfd sp!,{r0-r12,lr,pc} ; pop new task's r0-r12,lr & pc ;********************************************************************************************************* 我只能说我能理解个大概,里边的 ldr r0,=.+8 movs pc,r0这两句我不知道是什么意思.....
[ 本帖最后由 zsjalive 于 2012-8-13 16:57 编辑 ]
|