硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4014|回复: 18
收起左侧

[μCOS-III] 任务内调用子函数导致ucos停止运行的问题。

[复制链接]

31

主题

53

回帖

146

积分

初级会员

积分
146
发表于 2016-4-27 12:42:09 | 显示全部楼层 |阅读模式
问题一:
111.png


当在ucos任务1中调用上面的子函数时,会出现如下现象:我在任务2里向任务1post信号量时,post信号量会始终阻塞。
其他任务(如LED闪烁)也停止运行。

1.把上面红线的代码去掉,ucos恢复正常。
2.把上面子函数的代码直接复制到任务1代码中,ucos恢复正常。

是因为浮点数运算产生的问题吗?为什么放到子函数中就有问题,直接调用就没有问题呢?
解决方法是什么?


问题二:
UCOSIII的OS_TS_GET()得到的时间戳的时基是多少?
在哪里配置的?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-4-28 01:47:06 | 显示全部楼层
不好意思啊,楼主,今天回复的有些晚了,这几天群里面售后问题有些多,只能论坛的稍晚点回复了。
----------------------------------
1. 你现在用的是F407还是F103,如果是F407的话,可能是浮点寄存器的入栈出栈没有处理好,即移植部分有些问题。
    还有一个可能是你的任务栈空间小了,浮点寄存器共有34个呢,在任务切换的时候,这个就得需要34*4 = 136字节。

2. 参考我们的uCOS-III例子,初始化CPU_Init函数即可。进一步跟踪就是
    #define  OS_TS_GET()               (CPU_TS)CPU_TS_TmrRd()
   CPU_TS_TmrRd是读取的时钟周期计数器,即每个时钟周期的计数,32位仅存器。
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-3 13:26:52 | 显示全部楼层

回 eric2013 的帖子

eric2013:
不好意思啊,楼主,今天回复的有些晚了,这几天群里面售后问题有些多,只能论坛的稍晚点回复了。
----------------------------------
1. 你现在用的是F407还是F103,如果是F407的话,可能是浮点寄存器的入栈出栈没有处理好,即移植部分有些问题。
    还有一个可能是你的任务栈空间小了,浮点寄存器共有34个呢,在任务切换的时候,这个就得需要34*4 = 136字节。

.......
谢谢,五一假期没上网。
我用的stm32f429,
OSIII用的是ucos官方网站下载的Micrium_STM32F429II-SK_OS3.zip,

我在main函数中,OSInit();之后创建的第一个任务就执行了CPU_Init();,然后才创建其他任务,
代码参考的是Jean J.Labrosse的著作《嵌入式实时操作系统uc/OS-III》

111.png

栈空间我设置过1024、2048,还是这个现象,难道是栈空间还是不够大吗?
任务源码如下:(从代码看不像是栈空间不足的问题)
222.png


3.png
把栈大小设置为1024时,mp->dot = ...直接放在任务中执行,程序正常,放在子函数中就会引起阻塞,
如果说栈空间不足,那么改为2048,多出了1k字节,一定可以容纳浮点数寄存器,但是2048同样会有问题。

另外请教一个问题:
我想监视ucos运行时各个堆栈和cpu的使用情况,请问使用什么软件,该如果操作?有相关的教程吗?
我看到《嵌入式实时操作系统uc/OS-III》这本书有介绍,原理都看的很懂,但如何做没有思路。请指点。
probe说是付费的,没用过,能指导一下思路么?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-4 00:38:55 | 显示全部楼层
调用这个函数:

/*
*********************************************************************************************************
*    函 数 名: DispTaskInfo
*    功能说明: 将uCOS-III任务信息通过串口打印出来
*    形    参:无
*    返 回 值: 无
*********************************************************************************************************
*/
static void DispTaskInfo(void)
{
    OS_TCB      *p_tcb;            /* 定义一个任务控制块指针, TCB = TASK CONTROL BLOCK */
    float CPU = 0.0f;
    CPU_SR_ALLOC();

    CPU_CRITICAL_ENTER();
    p_tcb = OSTaskDbgListPtr;
    CPU_CRITICAL_EXIT();
   
   
    /* 打印标题 */
    printf("===============================================================\\r\\n");
    printf(" 优先级 使用栈 剩余栈 百分比 利用率   任务名\\r\\n");
    printf("  Prio   Used  Free   Per    CPU     Taskname\\r\\n");

    /* 遍历任务控制块列表(TCB list),打印所有的任务的优先级和名称 */
    while (p_tcb != (OS_TCB *)0)
    {
        CPU = (float)p_tcb->CPUUsage / 100;
        printf("   %2d  %5d  %5d   %02d%%   %5.2f%%   %s\\r\\n",
        p_tcb-&gtrio,
        p_tcb->StkUsed,
        p_tcb->StkFree,
        (p_tcb->StkUsed * 100) / (p_tcb->StkUsed + p_tcb->StkFree),
        CPU,
        p_tcb->NamePtr);        
         
        CPU_CRITICAL_ENTER();
        p_tcb = p_tcb->DbgNextPtr;
        CPU_CRITICAL_EXIT();
    }
   
}
就可以显示任务栈的使用情况了。
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-4 07:28:07 | 显示全部楼层

回 eric2013 的帖子

eric2013:调用这个函数:

/*
*********************************************************************************************************
*    函 数 名: DispTaskInfo
....... (2016-05-04 00:38) 
这个函数在哪里调用?单独创建一个任务吗?
这个函数时是自己写的?还是ucos提供的?
是不是在ucosII那本书里有这个代码?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-4 09:32:55 | 显示全部楼层

回 ggafish 的帖子

ggafish:这个函数在哪里调用?单独创建一个任务吗?
这个函数时是自己写的?还是ucos提供的?
是不是在ucosII那本书里有这个代码? (2016-05-04 07:28) 
我们自己写的。
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-6 18:42:42 | 显示全部楼层

回 eric2013 的帖子

eric2013:

我们自己写的。
我又遇到了这个问题,快来救救我吧:任务中进行浮点数的计算会导致ucos跑飞。

栈空间足够大:
111.png

工程配置启用浮点寄存器
444.png



运行到下面语句,ucos程序就会跑飞,不管用不用子函数fillbuffer封装,也许是因为sin函数本身就是个子函数。
把这个函数放到fillbuffer子函数中也是一样。
注释这条语句,ucos可以正常向下执行:翻转LED。
222.png

上次只是为了设置一个变量,我后来用查表法,规避了进行浮点计算这个问题。
但是现在需要利用sin函数填充一个buffer,这个问题回避不了了。
应该从哪里着手解决?
在工程配置中关闭浮点数计算吗?
救救我吧,是不是我的ucos没有配置好,我对ucos的移植不太懂,仅仅是能用。

项目压缩包
版本,mdk5.14
工程文件在project目录下。
MorseDemoF4.zip (2.12 MB, 下载次数: 61)
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-7 01:03:26 | 显示全部楼层
你的FPU移植有个问题,在启动代码里面加上这个,关闭FPU的lazy stack特性:
1.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-7 01:05:36 | 显示全部楼层
另外还有很重要的一点,如果用户通过MDK或者IAR编译器开启FPU,那么使用了浮点运算的任务在创建的时候
务必要使能参数OS_OPT_TASK_SAVE_FP,切记! 没有用到浮点运算的任务不需要此参数,设置了此参数才可
以对浮点寄存器进行入栈和出栈操作。         
3.png
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-7 14:14:45 | 显示全部楼层

回 eric2013 的帖子

eric2013:另外还有很重要的一点,如果用户通过MDK或者IAR编译器开启FPU,那么使用了浮点运算的任务在创建的时候
务必要使能参数OS_OPT_TASK_SAVE_FP,切记! 没有用到浮点运算的任务不需要此参数,设置了此参数才可
以对浮点寄存器进行入栈和出栈操作。     &nbs .. (2016-05-07 01:05)
这个,有点厉害啊。
虽然还没有照做,但是感觉问题就是你说的这个。

这些知识是从哪里学来的?

下面这个微博里面也谈到了一下这个问题,说是因为官方的移植代码,FPU入栈和出栈的顺序错误,版主什么观点?我是不是应该同时采纳你的和这篇微博的意见?
http://blog.sina.com.cn/s/blog_98ee3a930102v9p7.html
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-7 14:32:10 | 显示全部楼层

回 ggafish 的帖子

ggafish:这个,有点厉害啊。
虽然还没有照做,但是感觉问题就是你说的这个。

这些知识是从哪里学来的?
....... (2016-05-07 14:14) 
我就是专门搞嵌入式操作系统的,见笑了[s:142]
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-7 17:27:42 | 显示全部楼层
你的微博里面说的官方移植代码的浮点寄存器出栈入栈代码有问题,跟你这里说的有什么相同和不同的地方?
我应该照哪个方案做。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-8 00:11:41 | 显示全部楼层

回 ggafish 的帖子

ggafish:你的微博里面说的官方移植代码的浮点寄存器出栈入栈代码有问题,跟你这里说的有什么相同和不同的地方?
我应该照哪个方案做。
 (2016-05-07 17:27) 
博客里面的是我自己实现的,这个帖子里面的是uCOS官方的方案,你就用官方的方案就行。
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-8 12:31:46 | 显示全部楼层

回 eric2013 的帖子

eric2013:

博客里面的是我自己实现的,这个帖子里面的是uCOS官方的方案,你就用官方的方案就行。

明白。我再调试一下。
再问一个问题:我在仿真里面的MSP指针和map文件中的指针地址为什么会相差8个字节。
不应该是相同的吗?
222.png

1111.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-8 12:47:22 | 显示全部楼层
从你的这个反汇编来看是,R0寄存器要入栈,这个寄存器保存了system函数的返回值地址,而你的程序中要用R0寄存器。
------------------------------
R0寄存器占用4个字节,另外就是进入任何子函数,编译器会对其做8字节对齐调整,这个是AAPCS规约要求的。

所以就是你上面所说的那个地址了。
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-8 21:25:03 | 显示全部楼层

回 eric2013 的帖子

eric2013:
从你的这个反汇编来看是,R0寄存器要入栈,这个寄存器保存了system函数的返回值地址,而你的程序中要用R0寄存器。
------------------------------
R0寄存器占用4个字节,另外就是进入任何子函数,编译器会对其做8字节对齐调整,这个是AAPCS规约要求的。

所以就是你上面所说的那个地址了。
.......

1.没看明白,想继续问也不知道问什么,暂时这样吧,看来差距不是一点半点。
2.按照你说的方法,修改了startup.s汇编代码,问题从运行现象上看是解决了,可以正常往后执行,不会跑飞了。
另外,我还发现,只修改startup.s,但创建任务时不指定OS_OPT_TASK_SAVE_FP选项,OS也可以正常进行浮点计算,只是不知道这样做有什么隐患。
3.不知道能否出一些底层的文字或者视频教程呢,比如这两种解决方案,一种是你说的修改startup.s,第二种是微博里面说的自己改写的入栈出栈代码,
这两种方法如何做到异曲同工的作用的?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-9 10:13:41 | 显示全部楼层

回 ggafish 的帖子

ggafish:1.没看明白,想继续问也不知道问什么,暂时这样吧,看来差距不是一点半点。
2.按照你说的方法,修改了startup.s汇编代码,问题从运行现象上看是解决了,可以正常往后执行,不会跑飞了。
另外,我还发现,只修改startup.s,但创建任务时不指定OS_OPT_TASK_SAVE_FP选项,OS也可以 .. (2016-05-08 21:25) 
2. 一定要加上。
3. 暂时不会做视频教程了,太耗费精力了。[s:142]
回复

使用道具 举报

31

主题

53

回帖

146

积分

初级会员

积分
146
 楼主| 发表于 2016-5-30 19:03:18 | 显示全部楼层
出差了1个月,回来会继续这个项目的开发,我先前按照你的代码统计栈空间和cpu利用率,没有成功,
看来问题找到了,是浮点数这里的问题。
现在这个问题解决了,可以重新把栈空间统计的代码完善了。
遇到问题还要请教。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2016-5-31 10:05:49 | 显示全部楼层

回 ggafish 的帖子

ggafish:出差了1个月,回来会继续这个项目的开发,我先前按照你的代码统计栈空间和cpu利用率,没有成功,
看来问题找到了,是浮点数这里的问题。
现在这个问题解决了,可以重新把栈空间统计的代码完善了。
遇到问题还要请教。 (2016-05-30 19:03) 
[s:142]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 05:31 , Processed in 0.235731 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表