4225|0

21

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

求助 UCOS移植到ARM9上的中断处理问题 [复制链接]

 
我最近在学习将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;// eint02低电平
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触发,LED9LED10!!!\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=1TASK1才会运行,所以会先运行TASK2,我在TASK2中的Key_Scan_Test( )里面的中断服务程序void __irq KeyISR(void)中设了只要触发按键中断全局变量i才会等于1,也就是说,只有触发按键中断后让i=1TASK1才会有可能运行。
可是当我实际运行的时候,我触发按键中断,却看到超级终端上一直在打印消息 i=1,任务不能切换。
会不会是我的方法有问题,如果是,应该怎么样处理呢?? 我刚学习不久,希望大神支招................
我还有如下问题:
1、就是将UCOS移植到ARM9上,不管移植到哪个平台上,怎样才能算移植完成,是不是移植后能跑多个任务就算完成了(不加想我这样管理外部硬件资源),还是说需要通过假如外部硬件资源来检测......
2UCOS移植到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 编辑 ]
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表