lgh050706 发表于 2010-11-9 22:22:15

UcOS_II这种问题老是出现,就是程序执行一半就不知跑那儿去了!请高手指点!

我的程序比较简单,程序开始运行的时候先执行task2与task3,task2与世隔绝task3会发送一个信号量到task1中,当task1得到信号理的时候才能运行,而task1运行后会清除信号量集里的标志位,程序不继在周而复始,所以最后输出的结果为:“0xbb,0xcc,0xaa,0xbb,0xcc,0xaa,0xbb,0xcc,0xaa...........”
但是实际上程序只执行了一点.就不知跑到那里去啦,请大家指点,图片是程序执行的结果.

//--------------------------------------------------------------------------------
#include "config.h"
#include <stdio.h>                /* prototype declarations for I/O functions */
#include <LPC21XX.H>            /* LPC21xx definitions                      */
#include "Main_uart.h"
OS_STK TA_1;
OS_STK TA_2;
OS_STK TA_3;

OS_FLAG_GRP *ptemp;        //存放一个信号量

uint8 err;                        //存放错误信息
void task1(void *pdata);
void task2(void *pdata);
void task3(void *pdata);
#define led4 (1<<10)
int main (void)
{   
        UARTInit();        //串口初始化
        TargetInit(); //项目初始化
        IO0DIR=led4;                  
        IO0CLR=led4; //上电时LED闪动一下
        delay_ms(100);
        IO0SET=led4;   
          

        OSInit ();
    OSTaskCreate(task1,0,&TA_1,2);//创建三个任务
        OSTaskCreate(task2,0,&TA_2,3);
        OSTaskCreate(task3,0,&TA_3,4);
        ptemp=OSFlagCreate(0,&err);       //创建一个信号量集

        OSStart();       
}                     
void task1(void *pdata)
{       
    uint8 i;
        pdata=pdata;
        for(;;)
        {       
          OSFlagPend(ptemp,0x03,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,0,&err);        //请求一个信号量集 ,请求第一位和第二位
                send(0xaa);        //成功后发送0xaa;                                   
          OSTimeDly(50);                                                                                                                                   OSTimeDly(100);
        }
}
void task2(void *pdata)
{       
   pdata=pdata;
   for(;;)
   {       
          send(0xbb);        //发送0xbb
                OSFlagPost(ptemp,0x01,OS_FLAG_SET,&err); //发送第一位
                OSTimeDly(50);
   }
}
void task3(void *pdata)
{
   pdata=pdata;
   for(;;)
{       
          send(0xcc);
                OSFlagPost(ptemp,0x02,OS_FLAG_SET,&err);   //发送第二位
                OSTimeDly(50);
        }
}
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_596700IDE6MW.jpg
(原文件名:未命名.jpg)

lgh050706 发表于 2010-11-9 22:37:45

我把task1改为这样,程序执行就会正常了!
void task1(void *pdata)
{       
        pdata=pdata;
        for(;;)
        {       
          OSFlagAccept(ptemp,0x03,OS_FLAG_WAIT_SET_ALL+OS_FLAG_CONSUME,&err);        //请求一个信号量集 ,请求第一位和第二位
                if(err==OS_NO_ERR)
                {
                send(0xaa);        //成功后发送0xaa;
                }                                   
          OSTimeDly(50);                                                                                                                          
        }
}
结果是这样的!
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_596703X2GDIK.jpg
(原文件名:未命名.jpg)

lgh050706 发表于 2010-11-9 22:39:41

结果是这样的!
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_596703X2GDIK.jpg
(原文件名:未命名.jpg)

akin 发表于 2010-11-10 08:22:13

OS_STK TA_1;
OS_STK TA_2;
OS_STK TA_3;

你设置的堆栈太小,一般很简单的任务也要设置到64才行

lgh050706 发表于 2010-11-10 19:21:15

我想问一下!我怎样知道一个堆栈要设多大呢!请前辈指点!

greencamel 发表于 2010-11-10 20:07:06

有个笨办法,使用JTAGE之类的调试,在watch窗口添加你程序的堆栈数组,然后让程序运行一段时间后停止,你就能看到watch窗口的堆栈数组变红了一部分(被改过了),接下来就数一下数组里有多少是被修改过的就知道程序要用多大的堆栈了,特别声明,这只是适合一般情况,可能要考虑有中断嵌套的情况

lgh050706 发表于 2010-11-10 20:07:21

回复【3楼】akin
os_stk ta_1;
os_stk ta_2;
os_stk ta_3;
你设置的堆栈太小,一般很简单的任务也要设置到64才行
-----------------------------------------------------------------------

大哥!我试过了,我把推栈设到100都不行,请问前辈能不能帮我看一下是不什么原因吗!这个问题搞我搞死啦!

greencamel 发表于 2010-11-10 20:18:18

你没有JLink什么的调试器??平时程序出问题了你是怎么分析调试的????
等出问题了直接暂停看程序死哪了,然后一步一步反向分析

lgh050706 发表于 2010-11-10 20:33:34

我看到啦!他是停到以下的这一步!请看以下黄色箭头里,我是用H-JTAG来仿真的。但这停到这一步不知为什么!
http://cache.amobbs.com/bbs_upload782111/files_34/ourdev_596899RJ36WE.jpg
(原文件名:未命名.jpg)


以下是整一个头件,我发上来大哥你帮我看一下好吗!

;/****************************************Copyright (c)**************************************************
;**                               广州周立功单片机发展有限公司
;**                                     研    究    所
;**                                        产品一部
;**
;**                                 http://www.zlgmcu.com
;**
;**--------------文件信息--------------------------------------------------------------------------------
;**文   件   名: Startup.s
;**创   建   人: 陈明计
;**最后修改日期: 2004年3月3日
;**描      述: lpc21xx的启动代码,包含异常向量入口、初始化堆栈的代码等
;**            每个工程应当有独立的这个文件的拷贝,并进行相应的修改   
;**--------------历史版本信息----------------------------------------------------------------------------
;** 创建人: 陈明计
;** 版本: v1.0
;** 日 期: 2004年2月2日
;** 描 述: 原始版本
;**
;**------------------------------------------------------------------------------------------------------
;** 修改人:
;** 版本:
;** 日 期:
;** 描 述:
;**
;**--------------当前版本修订------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;** 描 述:
;**
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/

;定义堆栈的大小
FIQ_STACK_LEGTH         EQU         0
IRQ_STACK_LEGTH         EQU         9*8             ;每层嵌套需要9个字堆栈,允许8层嵌套
ABT_STACK_LEGTH         EQU         0
UND_STACK_LEGTH         EQU         0

NoInt       EQU 0x80

USR32Mode   EQU 0x10
SVC32Mode   EQU 0x13
SYS32Mode   EQU 0x1f
IRQ32Mode   EQU 0x12
FIQ32Mode   EQU 0x11

PINSEL2   EQU 0xE002C014


;引入的外部标号在这声明
    IMPORTFIQ_Exception                   ;快速中断异常处理程序
    IMPORT__main                        ;C语言主程序入口
    IMPORTTargetResetInit               ;目标板基本初始化

    IMPORTSoftwareInterrupt

;给外部使用的标号在这声明
    EXPORTReset
    EXPORT__rt_div0
    EXPORT__user_initial_stackheap
        EXPORT bottom_of_heap
        EXPORT        StackUsr
   
        CODE32

    PRESERVE8       ;这个东东一定要加,,,,不加好像不行。。。。       在KEIL v2.5时没有发现这个东东

    AREA    vectors,CODE,READONLY

    ARM
;中断向量表
Reset
      LDR   PC, ResetAddr
      LDR   PC, UndefinedAddr
      LDR   PC, SWI_Addr
      LDR   PC, PrefetchAddr
      LDR   PC, DataAbortAddr
      DCD   0xb9205f80
      LDR   PC,
      LDR   PC, FIQ_Addr

ResetAddr         DCD   ResetInit
UndefinedAddr       DCD   Undefined
SWI_Addr            DCD   SoftwareInterrupt
PrefetchAddr      DCD   PrefetchAbort
DataAbortAddr       DCD   DataAbort
Nouse               DCD   0
IRQ_Addr            DCD   0
FIQ_Addr            DCD   FIQ_Handler

;未定义指令
Undefined
      B       Undefined

;取指令中止
PrefetchAbort
      B       PrefetchAbort

;取数据中止
DataAbort
      B       DataAbort//------------------------------------------------------------------------------程序就是停到这一步,不知道为什么?

;快速中断
FIQ_Handler
      STMFD   SP!, {R0-R3, LR}
      BL      FIQ_Exception
      LDMFD   SP!, {R0-R3, LR}
      SUBS    PC,LR,#4


;//传说中的加密
;标号一定要对齐,否则出错了,想到X也找不出来
; 程序加密
        IF :DEF: EN_CRP
      IF. >= 0x1fc
      INFO    1,"\nThe data at 0x000001fc must be 0x87654321.\nPlease delete some source before this line."
      ENDIF
CrpData
    WHILE . < 0x1fc
    NOP
    WEND
CrpData1
    DCD   0x87654321          ;/*When the Data is 为0x87654321,user code be protected. 当此数为0x87654321时,用户程序被保护 */
    ENDIF

;/*********************************************************************************************************
;** 函数名称: InitStack
;** 功能描述: 初始化堆栈
;** 输 入:   无
;** 输 出 :无
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修 改:
;** 日 期:
;**-------------------------------------------------------------------------------------------------------
;********************************************************************************************************/



InitStack   
      MOV   R0, LR

;设置中断模式堆栈
      MSR   CPSR_c, #0xd2
      LDR   SP, StackIrq
;设置快速中断模式堆栈
      MSR   CPSR_c, #0xd1
      LDR   SP, StackFiq
;设置中止模式堆栈
      MSR   CPSR_c, #0xd7
      LDR   SP, StackAbt
;设置未定义模式堆栈
      MSR   CPSR_c, #0xdb
      LDR   SP, StackUnd
;设置系统模式堆栈
      MSR   CPSR_c, #0xdf
      LDR   SP, =StackUsr

      MOV   LR, R0
      MOV   PC, LR
               
;/*********************************************************************************************************
;** 函数名称: ResetInit
;** 功能描述: 复位入口
;**
;** 输 入: 无
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人: 陈明计
;** 日 期: 2004年3月3日
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
ResetInit      
      BL      InitStack               ;初始化堆栈
      BL      TargetResetInit         ;目标板基本初始化
                                       
      B       __main          ;跳转到c语言入口


;/*********************************************************************************************************
;** 函数名称: __user_initial_stackheap
;** 功能描述: 库函数初始化堆和栈,不能删除
;**
;** 输 入: 参考库函数手册
;**
;** 输 出: 参考库函数手册
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__user_initial_stackheap   
    LDR   R0,=bottom_of_heap
    MOV   PC,LR


;/*********************************************************************************************************
;** 函数名称: __rt_div0
;** 功能描述: 整数除法除数为0错误处理函数,替代原始的__rt_div0减少目标代码大小
;**
;** 输 入: 参考库函数手册
;**
;** 输 出: 无
;**         
;** 全局变量: 无
;** 调用模块: 无
;**
;** 作 者: 陈明计
;** 日 期: 2004年2月2日
;**-------------------------------------------------------------------------------------------------------
;** 修改人:
;** 日 期:
;**------------------------------------------------------------------------------------------------------
;********************************************************************************************************/
__rt_div0

      B       __rt_div0

StackIrq         DCD   IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq         DCD   FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt         DCD   AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd         DCD   UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

;/* 分配堆栈空间 */
      AREA    MyStacks, DATA, NOINIT, ALIGN=2
IrqStackSpace         SPACE   IRQ_STACK_LEGTH * 4;中断模式堆栈空间
FiqStackSpace         SPACE   FIQ_STACK_LEGTH * 4;快速中断模式堆栈空间
AbtStackSpace         SPACE   ABT_STACK_LEGTH * 4;中止义模式堆栈空间
UndtStackSpace          SPACE   UND_STACK_LEGTH * 4;未定义模式堆栈


;
;从以前的heap.s 和 stacks中移过来,,少了两个文件

      AREA    Heap, DATA, NOINIT
bottom_of_heap    SPACE   1

      AREA    Stacks, DATA, NOINIT
StackUsr                  SPACE   1

    END
;/*********************************************************************************************************
;**                            End Of File
;********************************************************************************************************/

lgh050706 发表于 2010-11-10 20:40:54

我把速一个功程到上传上来,让大家帮我看一下!
点击此处下载 ourdev_596906VBBLHH.rar(文件大小:484K) (原文件名:14-实时操作系统 uCOS_II - KEIL.rar)

lgh050706 发表于 2010-11-10 22:25:47

回复【7楼】greencamel
你没有jlink什么的调试器??平时程序出问题了你是怎么分析调试的????
等出问题了直接暂停看程序死哪了,然后一步一步反向分析
-----------------------------------------------------------------------

它现在停在启动文件那里啦!真的搞不懂为什么会这样!请大家帮一个忙吧!

dysxq 发表于 2010-11-29 01:19:24

你在DataAbort下断点,断下来之后,看LR的值,就知道从哪儿跳过来的了,还可以看前一模式的LR值,更可以知道是哪个函数调用出问题了,你这个DataAbort,可能是访问了非法的地址,也可能是读数据时,没有对齐引起的

peavey 发表于 2011-1-17 12:51:58

“你在DataAbort下断点,断下来之后,看LR的值,就知道从哪儿跳过来的了,还可以看前一模式的LR值。”,有用,记号
页: [1]
查看完整版本: UcOS_II这种问题老是出现,就是程序执行一半就不知跑那儿去了!请高手指点!