论坛» 嵌入式开发» MCU

[求助]关于2407上ucos调试的问题

菜鸟
2007-04-26 20:39 1楼

最近准备做一个基于ucosTMS320LF2407的系统,开始很幸运在网上找到一个移植好的代码,刚开始编译有一些问题,根据错误提示,修改了一些头文件的设置,就Build Complete

接着,我添加了两个任务,运行可以进入优先级高的任务,但不能进行任务切换,单步调试发现是OS_TASK_SW()的问题,程序里定义的是调用31号软中断,但我的开发板片内FLASH也就是003F的那段没有烧写上软中断的定义,偷懒直接就在Os_CPU.H里定义OS_TASK_SW( )直接调用_OSCtxSw,没有用软中断,(我觉得用这个软中断可能是为了方便移植吧,不知道这样可以不?反正任务可以切换了)。

我先写了两个简单任务,一个是阵列按键扫描,一个是IO口控制LED发光,运行发现按间后对应LED点亮,再按就没有反映了,原来程序任务切换三次后(高到低,低再到高,然后就到空闲)就一直在空闲任务里运行,百度上搜了下,真惭愧,把系统很重要的时钟节拍的忘了。

我用的2407没有实时时钟,就用定时器T1的周期中断,设了100ms,把定时器中断加在优先级最高的一个任务,运行了下,程序可以从空闲任务里出来了,但我也发现我的系统崩溃了(),由于是第一次,也没有经验,现在都一个星期了,也找不到原因。

我分析可能是时钟节拍中断的问题,但看程序也看不出毛病了,真郁闷!一个小小的ucos,怎么就搞不定-------那个高手来给我点建议!

请不惜赐教,非常感激!

菜鸟
2007-04-26 20:41 2楼


#include "includes.h"
#include "global.c"
void SystemInit();
void Timer1Init();
void OS_Tick() ;
extern unsigned int key();
extern unsigned int num=0;

OS_STK Task0[OS_TASK_IDLE_STK_SIZE];
OS_STK Task1[OS_TASK_IDLE_STK_SIZE];
OS_STK Task2[OS_TASK_IDLE_STK_SIZE];

static void Task0(void *);
static void Task1(void *);
static void Task2(void *);
/*******************************************************************************
*
* Routine : main
*
*******************************************************************************/
void main(void)
{
int i;
SystemInit(); //系统初始化
OSInit();
OSTaskCreate(Task0,(void *)&i,(void *)&Task0[0], 5);
OSTaskCreate(Task1,(void *)&i,(void *)&Task1[0], 10);
OSTaskCreate(Task2,(void *)&i,(void *)&Task2[0], 1);
OSStart();
}

void Task0(void *i)
{
i=i;

while (1)
{

num=key(); //读键值

if(num!=0)
OSTimeDly(20); //若有键按下时,延时20个始终节拍
}
}
/*******************************************************************************/

void Task1(void *j)
{
int i=i;

MCRA=MCRA & 0x80FF; //IOPB0-6设为IO口模式
PBDATDIR=0xBFC2; //所有LED=0,并置IOPB6为输入口

while (1)
{
if(num==60)
{ PBDATDIR=PBDATDIR & 0xFFC7; //将其他的led灭掉
if((PBDATDIR & 0x0004)==0x0004)
PBDATDIR=PBDATDIR & 0xFFFB; //IOPB2=0;LED1灭
else
PBDATDIR=PBDATDIR |0x0404; //IOPB2=1;LED1亮
}
if(num==58)
{ PBDATDIR=PBDATDIR & 0xFFCB;
if((PBDATDIR & 0x0008)==0x0008)
PBDATDIR=PBDATDIR & 0xFFF7; //IOPB3=0;LED2灭
else
PBDATDIR=PBDATDIR |0x0808; //IOPB3=1;LED2亮
}
if(num==54)
{ PBDATDIR=PBDATDIR & 0xFFD3;
if((PBDATDIR & 0x0010)==0x0010)
PBDATDIR=PBDATDIR & 0xFFEF; //IOPB4=0;LED3灭
else
PBDATDIR=PBDATDIR |0x1010; //IOPB4=1;LED3亮
}
if(num==92)
{ PBDATDIR=PBDATDIR & 0xFFE3;
if((PBDATDIR & 0x0020)==0x0020)
PBDATDIR=PBDATDIR & 0xFFDF; //IOPB5=0;LED4灭
else
PBDATDIR=PBDATDIR |0x2020; //IOPB5=1;LED4亮

}

OSTimeDly(20);

}
}

/*******************************************************************************/

void Task2(void *i)
{
i=i;

Timer1Init();
asm(" CLRC INTM ");


while (1)
{

OSTimeDlyHMSM(1,0,0,0);

}
}
/*******************************************************************************/
void SystemInit()
{

asm(" SETC INTM "); /* 关闭总中断 */
asm(" CLRC SXM "); /* 禁止符号位扩展 */
asm(" CLRC CNF "); /* B0块映射为 on-chip DARAM*/
asm(" CLRC OVM "); /* 累加器结果正常溢出*/
SCSR1=0x83FE; /* 系统时钟CLKOUT=20*2=40M */
/* 打开ADC,EVA,EVB,CAN和SCI的时钟,系统时钟CLKOUT=10M */
WDCR=0x006F; /* 禁止看门狗,看门狗时钟64分频 */
// KickDog(); /* 初始化看门狗 */
IFR=0xFFFF; /* 清除中断标志 */
IMR=0x0002; /* 中断*/

}

void Timer1Init()
{

EVAIMRA=0x0080; // 定时器1周期中断使能
EVAIFRA=0xFFFF; // 清除中断标志
GPTCONA=0x0000;
T1PR=25000; // 定时器1初值,定时0.4us*25000=10ms
T1CNT=0;
T1CON=0x144E; //增模式, TPS系数40M/16=2.5M,T1使能

}


这是我在ucos下写的三个任务,按照我的想法,程序是这样运行:首先,建立3个任务,开始运行多任务OSStart(),在优先级最高的Task2启动时钟节拍,然后挂起1小时,接下来运行Task0读出按键的键值,当读出键值后任务挂起20个时钟节拍,接下来运行Task1,点亮相应的LED,挂起20个时钟节拍,程序进入空闲任务。等Task0延时时间完了后,又开始运行Task0,然后Task1,不断反复,直到1个小时后,运行Task2,再反复...
示意图表示下: main()--OSStart()--task2--task0--task1--OSTaskIdle()--task0--task1--OSTaskIdle()
但我通过设置断点发现实际程序运行顺序是:
main()--OSStart()--task2--task0--task1--OSTaskIdle()--main()--OSStart()--task2--task0--task1--OSTaskIdle()
感觉是不是设置断点影响了时钟节拍,导致运行顺序发生变化???????????????
全速运行,观察运行效果,按一个键,对应LED亮,再按再亮,没有什么问题了。

大家所说自己意见?

[align=right][color=#000066][此贴子已经被作者于2007-4-29 9:39:20编辑过][/color][/align]
共2条 1/1 1 跳转至

回复

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