我按照步骤把 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),发生任务切换时发生的错误,所以觉得这个问题归根结底是移植代码出现问题,特别是堆栈处理。
写移植代码经常会看到这样的情况:刚开始程序好像运行得很正常,但不久就跑飞了,也就是上面说的死机