yulutong 发表于 2010-2-3 10:49:05

UCOS只能执行一次任务,请教可用什么调试方法来找问题?

void TestTask1(void *pdata)
{
       Timer1_init();
        pdata = pdata;
        while(1)
        {
                LED2_ON();
                OSTimeDly(2);
                }       
        }
void Task2(void *pdata)
{
        pdata = pdata;
        while(1)
        {
                LED2_OFF();
                OSTimeDly(100);               
                }       
        }       
创建了2个任务。
OSInit();
OSTaskCreate(TestTask1,(void *)0,&TestTaskStk,1);//99是指向栈顶,堆栈是往下长的
OSTaskCreate(Task2,(void *)0,&Task2buf,2);
OSStart();

在timer5ms中断服务程序中调用OSTimeTick();AXD下仿真断点,能执行到这个时钟节拍函数。

现在出现的问题是执行完任务1->任务2->空闲任务,永远也跳不出来了。
小弟百思不得其解,对ucos-ii不是很熟悉,现在想大家请教我这样的问题可以通过什么调试方法来找到问题。
谢谢。

ffxz 发表于 2010-2-3 11:03:36

不懂ucos,乱说下,

OSTaskCreate(TestTask1,(void *)0,&TestTaskStk,1);//99是指向栈顶,堆栈是往下长的
OSTaskCreate(Task2,(void *)0,&Task2buf,2);

在创建一个任务时,程序中需要显式的指定到栈顶吗?

如果调试,你可以这样,在ucos的时钟中断中设个断点,当然为了快速的复现你这个现象,你可以把OSTimeDly改小些

yulutong 发表于 2010-2-3 11:21:51

谢谢帮顶。
我定义的堆栈生长方向是向下的,所以给任务一个连续空间的RAM最高端。
OSTimeDly改到1也没有用,程序执行完任务1,2后永远执行空闲任务了。

xuxi2009 发表于 2010-2-3 11:47:38

让OSTimeTick每次执行输出系统时间计数器,就是叫什么Cnt的那个,看看计数器跑得对不对,如果计数器跑的对,没有理由不调度任务

yangsen 发表于 2010-2-3 11:52:38

检查一下是不是中断被禁止掉了,一种情况是没有在调度开始后开中断应该在任务开始后打开中断;还有一种情况是在调度上下文切换返回时候把中断关掉了

yulutong 发表于 2010-2-3 12:33:04

全局变量OSTime++正常。
4楼 你说的中断是我的定时器中断么?没有被禁止掉,因为我在定时器中断服务程序里打断点,单步,全速(有LED指示灯)都可以进的。

ffxz 发表于 2010-2-3 12:55:08

回复【2楼】yulutong土土狗
谢谢帮顶。
我定义的堆栈生长方向是向下的,所以给任务一个连续空间的RAM最高端。
OSTimeDly改到1也没有用,程序执行完任务1,2后永远执行空闲任务了。
-----------------------------------------------------------------------

不知道ucos是如何处理的。RTT中是不需要关心栈是往上长还是往下长,因为这部分平台移植已经做掉了,总是默认传进栈的初始位置,由平台移植代码再转向指向正确的位置。

如果栈没问题,那么你可以查看时钟中断的处理,既然计数器一直在累加,那么最近的一个软定时器达到时刻是什么时候,比较下就能得出结论。

ba_wang_mao 发表于 2010-2-3 13:09:58

可能的问题:
   1.移植函数中的:时间节拍中断服务程序_OSTickISR::有问题
   2.移植函数中的中断级任务切换_OSIntCtxSw::有问题.

yulutong 发表于 2010-2-3 13:57:50

7楼】 ba_wang_mao
1 我没有写OSTickISR函数,因为我在定时器调用OSTimeTick();我想效果一样的吧。
2 我现在我也怀疑没有移植好,os_cpu.a中的几个函数我在仔细看看。

yulutong 发表于 2010-2-3 13:58:01

7楼】 ba_wang_mao
1 我没有写OSTickISR函数,因为我在定时器调用OSTimeTick();我想效果一样的吧。
2 我现在我也怀疑没有移植好,os_cpu.a中的几个函数我在仔细看看。

0x00 发表于 2010-2-3 14:30:29

方便的话,把你的整个工程传上来,大家帮你看看

yulutong 发表于 2010-2-3 15:37:33

为什么我的程序无法运行到这个函数 OSIntCtxSw?

major888 发表于 2010-2-3 16:08:24

是不是应该先建一个启动任务(比如TASK_START),然后在启动任务中建立多任务,就是你的TASK1 TASK2.

major888 发表于 2010-2-3 16:09:56

你的这样建立的TASK2,TASK2,实际上是建立了两次启动任务,而启动任务是只执行一次的,这就是你的症结所在了

fnems 发表于 2010-2-3 18:08:51

为什么在task里面执行 Timer1_init() 呢?中断服务应该是属于系统级的吧

yulutong 发表于 2010-2-4 07:35:43

我是根据书上推荐,在优先级最高的任务中初始化定时器。12楼好像没有这种说话阿,不需要建task_start的吧。

mshicom 发表于 2010-2-4 10:14:49

我以前遇到过,最后好像是在中断里面加上OSIntEnter()和OSIntExit

kanprin 发表于 2010-2-4 10:20:59

把你的中断程序发上来看看(timer1),还有中断移植部分。
如此简单的工程最好还是整个工程打包上来。
另外还要说明一下编译环境。

yulutong 发表于 2010-2-4 13:24:07

问题找到了,
IRQ中断发生后需要调用UCOS_IRQHandler(),我这步骤没有做。不过还是不懂为什么要调用,我看别人的程序没有这个函数阿。

ba_wang_mao 发表于 2010-2-8 10:50:59

给你一个实际调试通过的实例:
   编译器=ICC7.22

http://cache.amobbs.com/bbs_upload782111/files_26/ourdev_533031.JPG
(原文件名:未命名1.JPG)

ba_wang_mao 发表于 2010-2-8 10:52:18

注意:设置路径:

http://cache.amobbs.com/bbs_upload782111/files_26/ourdev_533032.JPG
(原文件名:未命名2.JPG)

ba_wang_mao 发表于 2010-2-8 10:54:23

以下是源代码:
点击此处下载 ourdev_533033.rar(文件大小:722K) (原文件名:UCOS_ICC.rar)

yulutong 发表于 2010-2-10 10:44:16

谢谢楼上,我现在已经搞定了。
系统执行完任务后,就跳入空闲任务,而空闲任务中是没有OSTimeDly(2); 函数的。 这就意味着永远跳不出来,所以还要在定时器中断向量中跳到 完成执行 UCOS_IRQHandler()(有些程序上写的是OSTickISR,都是一样的)。

alp2502 发表于 2010-2-22 15:08:32

yulutong 土土:我也发现了同样的问题,我是从别人的ucos-ii v2.83移植到v2.88,在2.83下,点灯正常,2.88下,只亮一下。我发了份邮件过去,麻烦帮我看看

cptjy 发表于 2010-3-16 22:22:13

楼主能否发一个可以用的工程?我下了论坛里的,可仿真不可以。

twd3621576 发表于 2010-4-14 14:22:13

MARK 下

xuetingxun2010 发表于 2010-4-17 13:43:34

呵呵,正在学习

ghl220 发表于 2010-6-2 14:55:15

想请问下楼主,你的调试方法是什么,什么发现这个问题的,能不能详细说下,本人现在也遇到一个问题,就是单个任务时工作正常,加一个任务后,没有进行切换功能。

如果谁知道什么进行串口打印信息调试的方法,麻烦也说下,因为我看过说调操作系统常用这种方法,但我不知道什么弄?
页: [1]
查看完整版本: UCOS只能执行一次任务,请教可用什么调试方法来找问题?