当前位置: 代码迷 >> 驱动开发 >> 困扰半个月的有关问题:ucOS中,第2次调用OSTimeDly()死机
  详细解决方案

困扰半个月的有关问题:ucOS中,第2次调用OSTimeDly()死机

热度:640   发布时间:2016-04-28 11:00:35.0
困扰半个月的问题:ucOS中,第2次调用OSTimeDly()死机
我按照步骤把 ucos 移植到 ZLG 的 easyARM 开发板上,前面工作进行的挺顺利,但最近被这个问题给卡住了,半个月了,还没有搞定。
请求高手解疑释惑啊:

在一些初始化工作之后,创建了两个任务:

void main(void)

{

  OSInit();
  (void)OSTaskCreate(task_idle, (void *)0, &TaskIdleStk[TASK_STK_SIZE - 1], OS_LOWEST_PRIO - 4);
  (void)OSTaskCreate(task_handset, (void *)0, &TaskHandsetStk[TASK_STK_SIZE - 1], 5);
  OSStart();
}

两个 task 代码如下:

void task_idle(void * pdata)
{
  for (;;)
  {
  LED_flash(1);
  delay_NS(LED_FLASH_KEEP_TIME);
  }
}

void task_handset(void * pdata)
{
  timer_init();

  for (;;)
  {
  LED_flash(2);
  OSTimeDly(OS_TICKS_PER_SEC);
  }
}

其中 task_handset 的优先级比 task_idle 的优先级高,所以我在 task_handset 中启动时钟中断定时器。
时钟中断处理函数是按照 easyARM 开发版的标准模板写的,其中通过如下函数调用 ucos 的 tick 函数:

void IRQ_Timer0(void)
{
  T0IR = 0x01; // Clear IR flag.
  VICVectAddr = 0x00; // Notify VIC work has done.

  LED_flash(7);

  OSTimeTick();
}

由于笔记本上没有并口,不能用 ZLG 带的 easyJTAG,只能用 LED 指示;
运行现象如下:

1. LED 2 亮一下,说明 task_hanset 启动了,同时 delay;

2. LED1 闪烁,同时 LED 7 闪烁,说明 task_idle 运行正常,时钟中断函数运行正常;

3. 过一会 LED 2 亮一下,之后就死机了。

应该是 task_handset delay 时间到,由于其优先级高,所以抢占执行,LED 2 亮一下是正常的,但是之后第二次调用 OSTimeDly 就死机了,不知道为什么。


跪求高手指点迷津????

------解决方案--------------------
我觉得是不是中断不来了?
因为OSTimeDly是按照多少个tick后允许任务切换。
并且你的TimeTisk是挂在IRQ0上的。
所以是不是中断不来。造成任务没有切换?
------解决方案--------------------
fighting
------解决方案--------------------
中断中 LED_flash(7)实现是什么?其占用多少时间?

timer_init()如何实现的?目前定时器是自动重装载的么?
也就是说进入IRQ_Timer0后退出时有没有再次启动定时器?

在OSTimeTick中会将OSTimeDly的任务的延时减1
通过减少至0来决定是否进行任务切换
同时会判断当前是否有其更高优先级任务进入就绪状态,若有则进行任务切换

delay_NS(LED_FLASH_KEEP_TIME)是否调用了OSTimeDly?

从现象看好像是没有进行任务
但感觉有点矛盾,若定时器没有正常工作那么 task_handset是怎么进入就绪状态的呢?
“3. 过一会 LED 2 亮一下”是怎么产生的呢?
只有task_handset的延时减为0其才能进入就绪态啊

------解决方案--------------------
是不是定时器0占用了系统时钟?
------解决方案--------------------
初学者呢 最近也有挺多麻烦的问题,想高人指点指点。不闲我麻烦就加QQ:946402368
------解决方案--------------------
你在void IRQ_Timer0(void) 里面重新启动了中断么?

------解决方案--------------------
因为 LED 2 能亮第二次,所以说明时间中断应该是没有问题
应该是LED2第二次亮后,接着调OSTimeDly(OS_TICKS_PER_SEC),发生任务切换时发生的错误,所以觉得这个问题归根结底是移植代码出现问题,特别是堆栈处理。
写移植代码经常会看到这样的情况:刚开始程序好像运行得很正常,但不久就跑飞了,也就是上面说的死机