这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » uc,os,ii 一个uc/os-ii程序,运行结果与所要的预期不同,求教大家。

共2条 1/1 1 跳转至

uc,os,ii 一个uc/os-ii程序,运行结果与所要的预期不同,求教大家。

院士
2006-09-17 18:14:16     打赏
uc,os,ii 一个uc/os-ii程序,运行结果与所要的预期不同,求教大家。



关键词: 一个     os-ii     程序     运行     结果     要的     预期         

院士
2006-12-22 22:43:00     打赏
2楼
问 #include "config.h"
#include "stdlib.h"

#define  DIR1 1<<18
#define  DIR2 1<<19
#define  DIR3 1<<20
#define    Task0_Stk_Size    64            
#define Task_Stk_Size   64
OS_STK    Task0Stk [Task_Stk_Size];    
OS_STK    Task1Stk[Task_Stk_Size];        

void     Task0(void *pdata);            //Task0函数
void     Task1(void *pdata);            //Task1函数

        int main (void)
{
    OSInit ();                                                                                                        
(1)    OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10);    
        
    OSStart ();
    return 0;                                                            
}
/*********************************************************************************************************
**                            Task0 初始化PWM
********************************************************************************************************/

        void Task0(void *pdata)
{
    pdata = pdata;
    TargetInit ();
    
    PINSEL0  = 0x02 << 14|(0x02<<16);    
    PINSEL2  = PINSEL2&(~0x80);                                                 
    IO1DIR   = DIR1|DIR2|DIR3;
      
    
    PWMPR    = 0;                  
    PWMMCR   = 0x02;               
    PWMPCR   = 0x0400|0x01000;      
    PWMMR0   = Fpclk/10;        
    PWMMR2   = PWMMR0 / 2;          
    PWMMR4   = PWMMR0 / 2;        
    PWMTCR   = 0x02;             
    PWMTCR   = 0x01;            
    
    
(2)  OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 9);    
    
    IO1SET = DIR1|DIR2|DIR3;// 使开始时都置高电平
      while (1)
    {    
        IO1CLR   = DIR1|DIR2;          
        
        OSTimeDly(OS_TICKS_PER_SEC);
         
   
         IO1SET   = DIR1|DIR2;       
         OSTimeDly(OS_TICKS_PER_SEC);
         
    }
}
   
/*********************************************************************************************************
**                            Task1 ******************************** ************************************************************************/
   void Task1(void *pdata)
{
    pdata = pdata;
    
    
    while(1)
    {     
        IO1CLR   = DIR3;  
    
             
           
        OSTimeDly(OS_TICKS_PER_SEC);
        
        IO1SET   = DIR3;
                 
        
         OSTimeDly(OS_TICKS_PER_SEC);
        
    }
  
}
pwm的初始化,都正确的。我调试时p0.7口的蜂鸣器按所给的频率蜂鸣;
问题1)我是在main函数中通过OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10)创建Task0的,
而在Task0中,先初始化pwm之后再通过OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 9)创建Task1的,
我单步step in运行时, 只能走到
void OSStartHighRdy(void)
{
    _OSStartHighRdy();
}然后就不能单步了。困惑啊,是不是汇编写的就调试不到了。
而且,在uc/os-ii中,运行过程不像c语言那样,看不到运行过程是怎么样的啊。。
有什么书可以查得到吗?怎么看到任务task1的创建过程,我都没有看到
运行(2)  OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 9);这句代码。。迷惑的很。。
    



问题二:
主要是DIR1(即LED1,因为我是用这些口控制步进电机的正反转的。用lpc2131板上的LED来调试,以下类同。),DIR2(即LED2),DIR3(即LED3),
我用EasyARM LPC2131调试,此时由于第二行分给Task1优先级是九,比Task0 优先级10高,LED1,LED2先亮,然后,LED3亮,如果我把task1的优先级改为13,
LED3 就始终不亮了。。不是执行OSTimeDly(OS_TICKS_PER_SEC)是挂起当前任务吗,然后进行任务切换,,
怎么LED3始终亮不起来呢。。。。。。。





1: 2:看一下os_cfg.h里的OS_LOWEST_PRIO值 2: 调试再调试
(1)在task0里面设置断点调试

(2)再在task1里面设置断点

调试即可看出问题出在哪里,怎么调试,不用大家教了吧 3: 调试中发现一个更怪的问题啊。。。。昨天刚开始调试,发现一个很怪的问题,大家可以试试,,
我用的是zlg提供的移植到lpc2131代码,  我step in 运行OSInit ();进入了OS_InitRdyList();然后进入了OS_InitTCBList();我把这个函数copy出来,

static  void  OS_InitTCBList (void)
{
    INT8U    i;
    OS_TCB  *ptcb1;
    OS_TCB  *ptcb2;


    OSTCBList     = (OS_TCB *)0;                                 /* TCB Initialization                       */
    for (i = 0; i < (OS_LOWEST_PRIO + 1); i++) {                 /* Clear the priority table                 */
        OSTCBPrioTbl[i] = (OS_TCB *)0;
    }
    ptcb1 = &OSTCBTbl[0];
    ptcb2 = &OSTCBTbl[1];
    for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {  /* Init. list of free TCBs                  */
        ptcb1->OSTCBNext = ptcb2;
        ptcb1++;
        ptcb2++;
    }
    ptcb1->OSTCBNext = (OS_TCB *)0;                              /* Last OS_TCB                              */
    OSTCBFreeList    = &OSTCBTbl[0];
}   /**********************************************/
当step in 方式运行到最后一行的时候,再step in 一次,,整个程序就运行了。不会返回到OSInit()中的下一步。
但是在OSInit()中,你如果用step方式运行,运行OS_InitTCBList()之后,则不会使整个程序运行起来。。会继续下条指令。
怎么回事啊。。。我把周公深入浅出—LPC2131下册p250的例子重试 ,也有这样的结果。。。怎么回事,。。。想不通啊。。。。

4: re:没这回事。。。
我试过了。
肯定是你某些地方有问题所致。 5: re:seahai我试过了。。。。一直都是这样的。。

大家有板子再试试。。 6: re:自己顶下 7: Solution one:调试_OSStartHighRdy的方法_OSStartHighRdy有两种实现方式,直接调用assembler function或者借助SWI。在ADS中要Step into SWI Handler,需要在AXD中把OSStartHighRdy所在的文件点开,然后在里面设置Break point。 8: Solution Two:饥饿现象在Priority-driven,Full-preemptive 的OS,如果高优先级任务不主动交出OS的使用权的话,那么低优先级的任务永远的不到运行,这称为饥饿。

所以,UCOS要求用户任务在执行完任务代码后一定要调用系统服务,就是为了主动交出OS的使用权。UCOS中有一个任务是不会主动交出OS的使用权,那就是Idle Task。你的现象跟优先级大小有关,估计是发生了饥饿问题。

我的教训供你借鉴:仅调用系统函数而不检查其返回值是非常危险的,一般来说应该这样做比较好:

err = OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10);    

if(err != OS_NO_ERR)
{
    //Error handler
}
9: Solution Three:再试再step in 到OS_InitTCBList,
然后点击右键,选择Interleaving Disassembler,
这时进入汇编指令级Step 状态,由此可以发现到底是哪条指令出现问题;

另外,如果你在进入OS_InitTCBList时,中断已经打开,很可能中断发生致使程序执行顺序发生了改变,要在Debug时关注处理器的当前状态。

xianfei520 ,希望你解决问题后,能把最后的问题所在和原因在发上来,我也能一起学习:) 10: re:问题二答案利用设置断点的方式。我终于整懂了一些东西,把五一节学的东西写出来。。
与大家一起分享。好东西要与大家一起分享。这才是人生一大快事。有不对的
大虾门要指点一二啊。。


问题二答案:我find all 找到了周公定义的#define OS_LOWEST_PRIO 12,也就是说。我把task1的优先级改为13,当然都没有机会使它运行了。改为11也不行的。因为uc/os中 OS_LOWEST_PRIO-1也占用了。调试时像terrence说那样err = OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10);    

if(err != OS_NO_ERR)
{
    //Error handler
}
会发现err的值不是OS_NO_ERR.这是个好方法。。多谢terrence。。

下面把ocos的运行顺序写出来。给大家参考。。
利用设置断点的方式。
可以知道本程序
开始运行OSInit();                                                                  利用下面的函数创建                                     
OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10);    
      然后开始运行  OSStart ();
然后进入了task0函数中,直到走到
OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 9);
如果大家单步运行进去后,会因为这时候OSRunning=ture;
9又比10大,所以会进行任务切换的。然后进入了task1中运行,,
直到在任务task1中,
IO1CLR   = DIR3;  
OSTimeDly(OS_TICKS_PER_SEC);   单步进去发现,此函数把任务task1 挂起
进行任务切换,,
然后就进入了task0中。。
以后就好分析了。。


11: 关于中断的机理。。五一一直在搞中断,苦读几天有些眉目,跟大家共享,共同探讨。共同进步。。。
讲讲时间中断吧。。这个在ucos是核心的。。。少了它那整个系统就是没有头了。
在lpc2131中,周公使用了time0作中断用,首先必须建立起时间中断,原因大家去看贝贝的书,周公在TargetInit ();中有
void TargetInit(void)
{
    OS_ENTER_CRITICAL();
    srand((uint32) TargetInit);
    VICInit();
    Timer0Init();
    OS_EXIT_CRITICAL();
}
我把VICInit() copy出来。
void VICInit(void)
{
    extern void IRQ_Handler(void);
    extern void Timer0_Handler(void);

    VICIntEnClr = 0xffffffff;
    VICDefVectAddr = (uint32)IRQ_Handler;

    VICVectAddr0 = (uint32)Timer0_Handler;//这句是关键啊。。记住Timer0_Handler等下用它的。
    VICVectCntl0 = (0x20 | 0x04);
    VICIntEnable = 1 << 4;
}
函数Timer0Init()是初始化,这个我不多说了。
好了。有了这些东东后,
看看工作过程:
首先根据中断机理,当发生中断的时候,
执行LDR     PC, [PC, #-0xff0](对菜鸟来说,不知道这是硬件强制执行,我
当时也蒙了。后来才知道)
然后执行到Timer0_Handler  HANDLER Timer0_Exception(在IRQ.S中) 一定要知道,HANDLER
是个宏名,在IRQ.inc中,有宏的定义,如下。
$IRQ_Label HANDLER $IRQ_Exception_Function

        EXPORT  $IRQ_Label                      ; 输出的标号
        IMPORT  $IRQ_Exception_Function         ; 引用的外部标号

$IRQ_Label
        SUB     LR, LR, #4                      ; 计算返回地址
        STMFD   SP!, {R0-R3, R12, LR}           ; 保存任务环境
        MRS     R3, SPSR                        ; 保存状态
        STMFD   SP, {R3, SP, LR}^               ; 保存用户状态的R3,SP,LR,注意不能回写
                                                ; 如果回写的是用户的SP,所以后面要调整SP
        LDR     R2,  =OSIntNesting              ; OSIntNesting++
        LDRB    R1, [R2]
        ADD     R1, R1, #1
        STRB    R1, [R2]

        SUB     SP, SP, #4*3
        
        MSR     CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式
        CMP     R1, #1
        LDREQ   SP, =StackUsr
        
     (1)   BL      $IRQ_Exception_Function         ; 调用c语言的中断处理程序

        MSR     CPSR_c, #(NoInt | SYS32Mode)    ; 切换到系统模式
        LDR     R2, =OsEnterSum                 ; OsEnterSum,使OSIntExit退出时中断关闭
        MOV     R1, #1
        STR     R1, [R2]

        BL      OSIntExit

        LDR     R2, =OsEnterSum                 ; 因为中断服务程序要退出,所以OsEnterSum=0
        MOV     R1, #0
        STR     R1, [R2]

        MSR     CPSR_c, #(NoInt | IRQ32Mode)    ; 切换回irq模式
        LDMFD   SP, {R3, SP, LR}^               ; 恢复用户状态的R3,SP,LR,注意不能回写
                                                ; 如果回写的是用户的SP,所以后面要调整SP
        LDR     R0, =OSTCBHighRdy
        LDR     R0, [R0]
        LDR     R1, =OSTCBCur
        LDR     R1, [R1]
        CMP     R0, R1

        ADD     SP, SP, #4*3                    ;
        MSR     SPSR_cxsf, R3
        LDMEQFD SP!, {R0-R3, R12, PC}^          ; 不进行任务切换
        LDR     PC, =OSIntCtxSw                 ; 进行任务切换
    MEND

执行到(1)中,然后跳到Timer0_Exception函数中,
  void Timer0_Exception(void)
{
    T0IR = 0x01;
    VICVectAddr = 0;            
    OSTimeTick();
}
大家不会不知道OSTimeTick()作用吧。那就自己看书好了。。







12: re:对于swi函数的应用,我写得不好,大家要多多指点,,
个人理解为:首先是 LDR  PC, SWI_Addr,然后走到
SoftwareInterrupt
        LDR     SP, StackSvc            ;
        STMFD   SP!, {R0-R3, R12, LR}
        MOV     R1, SP                  ;

        MRS     R3, SPSR
        TST     R3, #T_bit              ;
        LDRNEH  R0, [LR,#-2]            ;
        BICNE   R0, R0, #0xff00
        LDREQ   R0, [LR,#-4]            ;
        BICEQ   R0, R0, #0xFF000000
                                        ;
        CMP     R0, #1
        LDRLO   PC, =OSIntCtxSw
        LDREQ   PC, =__OSStartHighRdy   ;

        BL      SWI_Exception
        
        LDMFD   SP!, {R0-R3, R12, PC}^
        
StackSvc           DCD     (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

然后根据r0的值,判别怎么走,有点像c中switch case 语句。

中间的堆栈数据保护,大家自己仔细分析了。然后是中断返回。其中还包含一些
任务调度方面的。。我下次写全些。。



13: re:terrence

调试_OSStartHighRdy的方法

_OSStartHighRdy有两种实现方式,直接调用assembler function或者借助SWI。在ADS中要Step into SWI Handler,需要在AXD中把OSStartHighRdy所在的文件点开,然后在里面设置Break point。

一种方式我会,把OSStartHighRdy所在的文件点开,然后在里面设置Break point。

“直接调用assembler function或者借助SWI ” 是什么意思。没有懂。。。



14: re:terrence

关于这个怪问题。我回复terrence兄弟

“step in 到OS_InitTCBList,
然后点击右键,选择Interleaving Disassembler,
这时进入汇编指令级Step 状态;

另外,如果你在进入OS_InitTCBList时,中断已经打开,很可能中断发生致使程序执行顺序发生了改变,要在Debug时关注处理器的当前状态。”
///////////////////////////////////////////////
我step in 在Interleaving Disassembler step in OS_InitTCBList,发现
中断都是禁止的。所以没有你说的那方面的可能。

我用周功自写得启动代码,提供的ucos的代码。有位seahai兄他的就没有
出现这种问题。那我就郁闷了。。



15: 好人做到底,转贴 waitwait 的东东,一起给大家前一段时间对何时任务调度一直搞不清楚,苦读几天有些眉目,跟大家共享,共同探讨。
所谓任务调度说的明白些就是将控制权交给内核,那么在程序上其实就是实现了程序上的一个跳转(汇编),C语言的话就是调用了一个函数sched().在这个函数里执行的功能就是从就绪表中找到就绪的最高级的任务,并将该任务的TCB复给OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];然后调用OS_TASK_SW();这个函数是用汇编写的(其中涉及到一个宏定义),这个函数就的入口就是OSIntCtxSw,功能就是保存当前任务的信息,将其压入堆栈,将OSTCBHighRdy 所对应的任务的指针付给PC,将数据从堆栈中弹出。开始执行新的任务。

那么什么时候调用sched()呢?有几种情况,第一种应当就是通常所说的中断级任务调度。大家都知道有一个时钟节拍的概念。它的一个重要作用就是当任务通过ostimedly()挂起时,在中断中提供准确的tick数。那么中断中到底执行了什么呢?当时钟节拍发生中断时函数的入口是IRQ向量中断,地址是timer0。
如下:
;定时器0中断
Timer0_Handler  HANDLER Timer0
这里用到了一个宏定义

    MACRO
$IRQ_Label HANDLER $IRQ_Exception

初次看时并没有看懂其中的意思,后经过反复思考,结合自己认为正确的想法,终于有所突破。
在这个宏中调用了留给用户自己编写的用C语言写的中断处理函数。
        void Timer0(void)
{
    T0IR = 0x01;
    T0MR0 += (Fpclk / OS_TICKS_PER_SEC);
    VICVectAddr = 0;            // 通知中断控制器中断结束
    OSTimeTick();
}
这个函数中调用了    OSTimeTick();这个函数,那么这个函数又完成了什么呢?
他负责检查是否在挂起的任务中有完成tick数的如果有将其加到任务就绪表中,返回宏中,在宏的末尾调用了任务处理函数OSIntCtxSw。进行了任务切换。
这种就应到是中断级任务调度。
另外的就是任务及调度,任务的就绪目前认为只有两种情况,一是tick数到期,另外一种就是信号量,消息,邮箱等非中断产生的信号是任务就绪。第一种上面已经讨论过。剩下的就是第二种,所以以信号量为例,如果一个任务要等待某个信号量那么他会调用ossempend()函数,任务要等待,以我们的想法,她没事做了,要等,那么就别占着茅坑不拉屎,交权吧!没措事实就是这样,这个函数中再次调用了sched()这个函数,寻找高优先级任务,进行任务切换。
那么有了ossempend()这个函数我们就会想到ossempost()这个函数,它是发送信号量的,当一个任务发送了信号量,那么内核就应该看看是不是有任务在等待信号量,oseventtaskrdy(),如果有任务在等待,怎么办,应该让这个任务执行,内核让一个任务执行的方法就是任务调度,本质就是程序跳转,再次调用sched()这个函数,这样是不是就通了。当然这块还涉及到事件控制块的机制,要细究的朋友,可以弄一下,弄点心得出来,大家一起进步。
总结一下,操作系统是人写出来的,别忘了它是一个程序。在想一个操作系统是如何工作时,我们首先要想如果我设计应该怎么设计,当然不考虑细节,先考虑整体,然后再按着自己的思路看源码,这是我的体会!还请大家指教!

称为抢占式的操作系统,也是有一个极小的时间片在里边的,就是时钟节拍。当然与时间片轮转式的操作系统大不一样。之所以能够进行抢占,就是在每种使任务就绪的情况发生的地方都进行了任务调度,寻找出高优先级的任务,进行执行。

共同努力! 16: 顶一下!学RTOS学的超快!
不得不顶,呵呵 17: terrenceterrence过奖了。多谢你老兄帮忙,兄弟我万分感谢啊。。
今后还希望多多指教。 18: 好人不少呢。谢谢。。。 19: 麻烦周公给解答啊。。。。。关于上面讲到的一个 “调试中发现一个更怪的问题啊。。。。”


麻烦周公给解答啊。。。。。

我把程序重新整理了下。注释显示不对的。对高手来说,这些注释也没有用。


#include "config.h"
#include "stdlib.h"
/*********************************************************************************************************
**                                    &frac12;&Oacute;&iquest;&Uacute;&para;¨&Ograve;&aring;&sup2;&iquest;·&Ouml;&iexcl;&cent;&Iuml;à&sup1;&Oslash;&micro;&Auml;&Ecirc;&yacute;&frac34;&Yacute;&para;¨&Ograve;&aring;&sup2;&iquest;·&Ouml;&pound;&raquo;
********************************************************************************************************/


#define    Task0_Stk_Size    64            //Define the Task0 stack length &para;¨&Ograve;&aring;&Oacute;&Atilde;&raquo;§&Egrave;&Icirc;&Icirc;&ntilde;0&micro;&Auml;&para;&Ntilde;&Otilde;&raquo;&sup3;¤&para;&Egrave;
#define Task_Stk_Size   64
OS_STK    Task0Stk [Task_Stk_Size];        //Define the Task0 stack &para;¨&Ograve;&aring;&Oacute;&Atilde;&raquo;§&Egrave;&Icirc;&Icirc;&ntilde;0&micro;&Auml;&para;&Ntilde;&Otilde;&raquo;
OS_STK    Task1Stk[Task_Stk_Size];        //Define the Task&pound;± stack &para;¨&Ograve;&aring;&Oacute;&Atilde;&raquo;§&Egrave;&Icirc;&Icirc;&ntilde;0&micro;&Auml;&para;&Ntilde;&Otilde;&raquo;


void     Task0(void *pdata);            //Task0 &Egrave;&Icirc;&Icirc;&ntilde;0
void     Task1(void *pdata);            //Task1 &Egrave;&Icirc;&Icirc;&ntilde;1
/********************************************************************************************************
** &ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig;: Delay
** &sup1;&brvbar;&Auml;&Uuml;&Atilde;è&Ecirc;&ouml;: &Egrave;í&frac14;&thorn;&Ntilde;&Oacute;&Ecirc;±&ordm;&macr;&Ecirc;&yacute;
*******************************************************************************************************
*/
void Delay(uint32 dly)
{
    uint32 i;
    
    for(; dly > 0; dly--)
        for(i = 0; i < 50000; i++);
}
/*
*********************************************************************************************************
** &ordm;&macr;&Ecirc;&yacute;&Atilde;&ucirc;&sup3;&AElig; &pound;&ordm;main()
** &ordm;&macr;&Ecirc;&yacute;&sup1;&brvbar;&Auml;&Uuml; &pound;&ordm;
** &micro;÷&Ecirc;&Ocirc;&Euml;&micro;&Atilde;÷ &pound;&ordm;
*********************************************************************************************************
*/

        int main (void)
{
    OSInit ();                                                                                                        
    OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0_Stk_Size - 1], 10);    
        
    OSStart ();
    return 0;                                                            
}
/*********************************************************************************************************
**                            Task0 &Egrave;&Icirc;&Icirc;&ntilde;0,&sup3;&otilde;&Ecirc;&frac14;&raquo;&macr;&Auml;&iquest;±ê°&aring;&pound;&not;&sup3;&otilde;&Ecirc;&frac14;&raquo;&macr;PWM
********************************************************************************************************/

        void Task0    (void *pdata)
{    

    
    uint32 i;
    pdata = pdata;
    
       
       
       i = 10;
    TargetInit ();
    
    PINSEL0  = 0x02 << 14|(0x02<<16);    // P0.7&Ntilde;&iexcl;&Ocirc;&ntilde;PWM2&sup1;&brvbar;&Auml;&Uuml;,P0.8&Ntilde;&iexcl;&Ocirc;&ntilde;PWM4&sup1;&brvbar;&Auml;&Uuml;&pound;&raquo;
    PINSEL2  = PINSEL2&(~0x80);           //±&Oslash;&ETH;&euml;&Ecirc;&sup1;&Oacute;&Atilde;&Otilde;&acirc;&Ouml;&Ouml;·&frac12;&Ecirc;&frac12;&pound;&not;&sup2;&raquo;&Auml;&Uuml;&Ecirc;&sup1;&Oacute;&Atilde; PINSEL2  = 0x00·&frac12;&Ecirc;&frac12;&pound;&raquo;
                                      //&Eacute;è&Ouml;&Atilde;p1:25--p1:16&Icirc;&ordf;GPIO&sup1;&brvbar;&Auml;&Uuml;&pound;&raquo;
    IO1DIR   = DIR1|DIR2|DIR3;
      
   
    
    
    OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 5);    
    
     /* PWM&sup3;&otilde;&Ecirc;&frac14;&raquo;&macr; */
  ((1))  PWMPR    = 0;                     // &sup2;&raquo;·&Ouml;&AElig;&micro;&pound;&not;&frac14;&AElig;&Ecirc;&yacute;&AElig;&micro;&Acirc;&Ecirc;&Icirc;&ordf;Fpclk&pound;&raquo;
    PWMMCR   = 0x02;                // &Eacute;è&Ouml;&Atilde;PWMMR0&AElig;&yen;&Aring;&auml;&Ecirc;±&cedil;&acute;&Icirc;&raquo;PWMTC &Ccedil;&Ograve;&sup2;&raquo;&sup2;ú&Eacute;ú&Ouml;&ETH;&para;&Iuml;&pound;&raquo;
    PWMPCR   = 0x0400|0x01000;      // &Ocirc;&Ecirc;&ETH;íPWM2&ordm;&Iacute;PWM4&Ecirc;&auml;&sup3;&ouml;&pound;&not;&micro;&yen;±&szlig;PWM
    PWMMR0   = Fpclk/10;        //&cedil;&oslash;&sup3;&ouml;&micro;&Auml;&Acirc;&ouml;&sup3;&aring;&AElig;&micro;&Acirc;&Ecirc;
    PWMMR2   = PWMMR0 / 2;          // 50%&Otilde;&frac14;&iquest;&Otilde;±&Egrave;&pound;&raquo;
    PWMMR4   = PWMMR0 / 2;        // 50%&Otilde;&frac14;&iquest;&Otilde;±&Egrave;&pound;&raquo;
       PWMTCR   = 0x02;             // &cedil;&acute;&Icirc;&raquo;PWMTC&pound;&raquo;
    PWMTCR   = 0x01;            // &AElig;&ocirc;&para;&macr;PWM&Ecirc;&auml;&sup3;&ouml;&pound;&raquo;
    
    
    
   
      
      
      
      while (1)
    {    
        IO1CLR   = DIR1;          //&cedil;&ordm;&Iuml;ò&ETH;&yacute;×&ordf;&pound;&raquo;
    //    Delay(100);  
        OSTimeDly(OS_TICKS_PER_SEC);
         
           IO1SET   = DIR1;        //&Otilde;&yacute;&Iuml;ò&ETH;&yacute;×&ordf;&pound;&raquo;
         
        OSTimeDly(OS_TICKS_PER_SEC);
         
    //    Delay(100);
        
    }
}
   
/*********************************************************************************************************
**                            Task1 &Egrave;&Icirc;&Icirc;&ntilde;1,&Ocirc;&Euml;&ETH;&ETH;&pound;&oslash;,&pound;ù&Ouml;á
******************************** ************************************************************************/
   void Task1(void *pdata)
{    
    uint32 i;
    pdata = pdata;
    
  ((2))     IO1SET = DIR1|DIR2|DIR3;
       
       i = 5;
    while(1)
    {     
        IO1CLR   = DIR3;
    
             
         //Delay(100);  
        OSTimeDly(OS_TICKS_PER_SEC);
        
        IO1SET   = DIR3;
                 
        //Delay(100);
         OSTimeDly(OS_TICKS_PER_SEC);
        //OSTimeDly(10);
    }
  
}

/*************************************************/
先使程序运行到OSTaskCreate (Task1,(void *)0, &Task1Stk[Task_Stk_Size-1], 5);句,
分别在((1)),((2))中设置断点,然后全速运行,程序首先在((2)),但是如果不是这种方式,step in 去运行,程序就会先运行在((1)),我都迷惑了。跟踪时候,我知道可以进入任务OS_Sched,但是优先级还是十,没有改变,,
我真的很纳闷啊。。。。。。怎么会有这样的事情。。我都没有开发的
信心了。。感觉随时都有定时炸弹似的。。。

估计这两样事情出现的原因是一样的。。周公解答。。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]