打印
[51单片机]

请ayb_ice帮我看一下!!急!!

[复制链接]
1712|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huhaomcu|  楼主 | 2013-11-7 10:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ICE, AC, se, tc, TI
本帖最后由 huhaomcu 于 2013-11-7 10:10 编辑

在使用RTX51-Tiny中明明我信号都已经发出去了,接收此信号的任务却不执行!!
C:\Users\TC\Desktop\1.png
C:\Users\TC\Desktop\2.png
感觉可能是我应用程序的问题,RTX51-Tiny我写过几个DEMO都没遇到过种情况!!!!

相关帖子

沙发
ayb_ice| | 2013-11-7 10:43 | 只看该作者
这个系统是不能抢占的,任务必须主动释放CPU,
如果已经使能了轮转,还不运行的话,则一定是程序问题
任务是否已经建立?

使用特权

评论回复
板凳
huhaomcu|  楼主 | 2013-11-7 11:16 | 只看该作者
ayb_ice 发表于 2013-11-7 10:43
这个系统是不能抢占的,任务必须主动释放CPU,
如果已经使能了轮转,还不运行的话,则一定是程序问题
任务 ...

问题好像出在下面的这段程序中:
void uart_rec_task(void) _task_ 1
{
uint8_t status1,status2;
while(1)        {                                                                               
status1 = os_wait1(K_SIG);
switch(status1)
{
case SIG_EVENT:
{
status2 = os_wait2(K_TMO,100);
switch(status2)
{
case TMO_EVENT:
{
os_send_signal(2);
break;
}
default: break;
}
break;
}
default: break;
}
os_switch_task();
}
}
用这段代码就有问题,如果改成下面的样子就可以:
void uart_rec_task(void) _task_ 1
{
uint8_t i,j;
uint8_t status;
while(1)
{                os_wait1(K_SIG);                                                               
status = os_wait(K_SIG|K_IVL,100,0);                                                               
switch(status)
{
case SIG_EVENT:                                                                               
{                                os_reset_interval(100);                                                                       
break;
}
caseTMO_EVENT:                                                                               
{                                os_send_signal(2);                                                                       
break;
}
default: break;
}
os_switch_task();
}
}
看了半天也没看出问题也在那里,轮转已经关了,任务也已建立!两者唯一的不同就是上面的这段代码!!!

使用特权

评论回复
地板
ayb_ice| | 2013-11-7 11:39 | 只看该作者
本帖最后由 ayb_ice 于 2013-11-7 11:41 编辑

程序写法是没有问题的
但感觉逻辑混乱,
语法也混乱,

出问题,当然要调试了,光看代码是很难看出问题的,关键是状态转移要清楚

另外你这两个程序完成的功能是有明显区别的

使用特权

评论回复
5
ayb_ice| | 2013-11-7 11:46 | 只看该作者
一般情况下,两个任务不要互相等待对方的信号(或事件等),否则容易死锁,如果不可避免,必须要超时控制,而且必须仔细规则

超时后的处理。

乒乓式的等待除外,此时一般只需要先触发一下即可

使用特权

评论回复
6
huhaomcu|  楼主 | 2013-11-7 11:58 | 只看该作者
ayb_ice 发表于 2013-11-7 11:46
一般情况下,两个任务不要互相等待对方的信号(或事件等),否则容易死锁,如果不可避免,必须要超时控制, ...

谢谢ayb_ice的回答!我自己在找找问题出在那吧!两段代码逻辑上是有点问题,我的目的就是要用这个任务来判断一帧数据帧是否接收完成(用超时处理,也就是接收到单字节数据后开始计时,比如计时值设为100ms,如100ms到后没有数据过来,说明此帧数据接收完成了,则此任务发信号给串口发送任务),这种方式我之前都是这样用的,基本上没什么问题,就是在使用RTX51-Tiny后实现起来就有点问题了!!
再次感谢ayb_ice的及时回答!!!!!!

使用特权

评论回复
7
伟布斯| | 2013-11-7 13:05 | 只看该作者
我帮你顶贴吧

使用特权

评论回复
8
huhaomcu|  楼主 | 2013-11-7 16:26 | 只看该作者
ayb_ice 发表于 2013-11-7 10:43
这个系统是不能抢占的,任务必须主动释放CPU,
如果已经使能了轮转,还不运行的话,则一定是程序问题
任务 ...

ayb_ice我看了一天也没找到问题的原因,实在是没办法了,我想把代码给你看一下(代码量很少),我觉得就是用RTX51中出的问题,想请你帮我看下,问题出在那里了!!!!代码见下楼。

使用特权

评论回复
9
huhaomcu|  楼主 | 2013-11-7 16:29 | 只看该作者
代码见附件

新建文件夹.rar

1.67 KB

源代码

使用特权

评论回复
10
ayb_ice| | 2013-11-7 17:28 | 只看该作者
基本程序应该是没有问题的
但很多细节我不知道,什么时候什么条件产生,没有办法分析,
不过感觉比较简单的东西,逻辑搞复杂了

使用特权

评论回复
11
huhaomcu|  楼主 | 2013-11-7 20:27 | 只看该作者
ayb_ice 发表于 2013-11-7 17:28
基本程序应该是没有问题的
但很多细节我不知道,什么时候什么条件产生,没有办法分析,
不过感觉比较简单的 ...

ayb_ice本身实现我这个单一的功能确实不用这么复杂的逻辑!因为我这部分是准备放到另一个程序中的,所以架构就被别人搞成这样了(我也不想的)!
还有问题已经被自己歪打正着找到了,原因见下帖(因为好像回复不能发图片)

使用特权

评论回复
12
huhaomcu|  楼主 | 2013-11-7 20:33 | 只看该作者
不知怎么搞的还是不能发图片!!原因是在KEIL中Options-Target-Memory Model中默认的是Small模式,我把它改成Large模式后就可以很正常完美的运行了,自己也不知是什么原因,对编译器不熟啊,还望你指点!!!!!!
不知是不是我定义了这样数据结构的原因
xdata struct TRINGBUFFER recBuff,sendBuff;
uint8_t xdata recDataBuf[MAXBUFFERSIZE];
uint8_t xdata sendDataBuf[MAXBUFFERSIZE];
MAXBUFFERSIZE=1024,上面是两个‘环’形数据结构,但是我看了的编译后的大小是data=28.0 xdata=2083,code=2944也并没有超过C8051内存的大小啊,不是很明白!!!!!!!!!

使用特权

评论回复
13
huhaomcu|  楼主 | 2013-11-7 20:52 | 只看该作者
ayb_ice 发表于 2013-11-7 17:28
基本程序应该是没有问题的
但很多细节我不知道,什么时候什么条件产生,没有办法分析,
不过感觉比较简单的 ...

ayb_ice问题已找到,因为程序中对环的操作使用了可重入函数(MB,环操作是别人写的,全是声明为可重入函数)如下
extern uint16_t RingBuf_FreeSize(struct TRINGBUFFER *ringbuf) reentrant;
extern uint16_t RingBuf_GetData(struct TRINGBUFFER *ringbuf, uint8_t *databuf, uint16_t len) reentrant;
extern uint16_t RingBuf_SaveData(struct TRINGBUFFER *ringbuf, uint8_t *databuf, uint16_t len) reentrant;
extern uint16_t RingBuf_DelData(struct TRINGBUFFER *ringbuf, uint16_t len) reentrant;
我将reentrant关键字去掉后,然后将Memory Model改为Small依旧可正常运行!!!真烦,原来是这个问题造成的!!!!!!!
谢谢ayb_ice你的帮助~~!!!

使用特权

评论回复
14
ayb_ice| | 2013-11-9 08:58 | 只看该作者
重入函数会使用模拟堆栈,模拟堆栈与编译模式有关,起动文件需要正确配置才行

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

189

主题

508

帖子

3

粉丝