注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
wstrom的个人空间 https://home.eeworld.com.cn/space-uid-51500.html [收藏] [复制] [分享] [RSS]
日志

有问必答--关于UCOS

已有 1232 次阅读2011-3-20 06:54

在这里创建这个帖子的目的是提高大家学习UCOS的积极性。如果大家在学习过程中遇到任何问题都可以在这里提问。坛子里的这方面高手希望大家经常来这里看一下,帮助大家解决问题。
发表评论 评论 (8 个评论)
回复 hades2011 2011-7-15 15:20
楼主 我最近在学习UCOS ii  能否和您交流下 我的QQ是 1974478360
回复 wstrom 2011-7-18 08:52
hades2011: 楼主 我最近在学习UCOS ii  能否和您交流下 我的QQ是 1974478360
可以啊
我的QQ:148124539
回复 mo0000021 2011-10-31 17:33
楼主,我学ucos-ii的时候,你的帮助很大呀。
问个问题:以前遇到的,系统中加了个任务,是电量检测的。工作的时候,切不到这个任务。然后提高优先级可以运行但最后一个优先级任务就不行了。最后的解决办法:最后一个优先级该是9 把他该为10就好了。也就是说。优先级9没用到。
不知道是什么问题。讨论下。
回复 wstrom 2011-11-8 21:58
我觉得你说的还是不够详细,这样。你可以加我的QQ,咱们再讨论
回复 hzh09031208 2012-3-27 21:29
可以加我的QQ379877911么?
回复 zsjalive 2012-8-13 21:22
我最近在学习将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 21:23
可以加我的QQ吗    我想向你请教    我加你的QQ   却加不了   有验证
回复 wstrom 2012-8-14 09:23
验证问题
王玮

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章