搜索
bottom↓
回复: 9

栈溢出问题!

[复制链接]

出0入0汤圆

发表于 2011-4-18 11:19:21 | 显示全部楼层 |阅读模式
初学,RT—Thread
LED例程,STM32F107,金牛学习板

原程序,

void rt_hw_led_on(rt_uint32_t n)
{
        switch (n)
        {
        case 0:
                GPIO_SetBits(led1_gpio, led1_pin);
                break;
        case 1:
                GPIO_SetBits(led2_gpio, led2_pin);
                break;
        default:
                break;
        }
}

void rt_hw_led_off(rt_uint32_t n)
{
        switch (n)
        {
        case 0:
                GPIO_ResetBits(led1_gpio, led1_pin);
                break;
        case 1:
                GPIO_ResetBits(led2_gpio, led2_pin);
                break;
        default:
                break;
        }
}






void led_toggle(rt_uint32_t n)
{
        switch (n)
        {
        case 0:
                GPIO_WriteBit(led1_gpio, led1_pin, (BitAction)((GPIO_ReadOutputDataBit(led1_gpio,led1_pin))^1) );
               
                break;
        case 1:
                GPIO_WriteBit(led2_gpio, led2_pin, (BitAction)((GPIO_ReadOutputDataBit(led2_gpio,led2_pin))^1) );
                break;
        default:
                break;
        }

}
void rt_led_disp_thread_entry(void* parameter)
{
        rt_uint32_t i=0;
        while(1)
        {
                i=0x50000;

                do{
                i--;
                }while(i>0);

                led_toggle(0);
                i=0x50000;

                do{
                i--;
                }while(i>0);
                led_toggle(1);
               
        }
}

void rt_led_disp_init(void)
{
        rt_thread_t init_led_thread;
        init_led_thread = rt_thread_create("led_disp", rt_led_disp_thread_entry, RT_NULL,
        128, 28, 10);
        if (init_led_thread != RT_NULL)
        rt_thread_startup(init_led_thread);

}




static rt_uint8_t led_inited = 0;
void led(rt_uint32_t led, rt_uint32_t value)
{
        /* init led configuration if it's not inited. */
        if (!led_inited)
        {
                rt_hw_led_init();
                led_inited = 1;
        }

        if ( led == 0 )
        {
                /* set led status */
                switch (value)
                {
                case 0:
                        rt_hw_led_off(0);
                        break;
                case 1:
                        rt_hw_led_on(0);
                        break;
                default:
                        break;
                }
        }

        if ( led == 1 )
        {
                /* set led status */
                switch (value)
                {
                case 0:
                        rt_hw_led_off(1);
                        break;
                case 1:
                        rt_hw_led_on(1);
                        break;
                default:
                        break;
                }
        }
}




#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(led, set led[0 - 1] on[1] or off[0])
FINSH_FUNCTION_EXPORT(led_toggle, toggle the leds)

#endif


我修改后,去掉了led_toggle()函数, 怎么栈还溢出了那, 因该占用更少才对啊,不解?

void rt_hw_led1_on(void)
{
GPIO_SetBits(led1_gpio, led1_pin);
}

void rt_hw_led1_off(void)
{
  GPIO_ResetBits(led1_gpio, led1_pin);
}


void rt_led_disp_thread_entry(void* parameter)
{
        //rt_uint32_t i=0;
        while(1)
        {
                rt_hw_led1_off();
                rt_thread_delay(100);

                rt_hw_led1_on();
                rt_thread_delay(100);
               
        }
}

void rt_led_disp_init(void)
{
        rt_thread_t init_led_thread;
        init_led_thread = rt_thread_create("led_disp", rt_led_disp_thread_entry, RT_NULL,
        128, 28, 10);

        if (init_led_thread != RT_NULL)
           rt_thread_startup(init_led_thread);

}




static rt_uint8_t led_inited = 0;

void led(rt_uint32_t led, rt_uint32_t value)
{
        /* init led configuration if it's not inited. */
        if (!led_inited)
        {
                rt_hw_led_init();
                led_inited = 1;
        }

        if ( led == 0 )
        {
                /* set led status */
                switch (value)
                {
                case 0:
                        rt_hw_led1_off();
                        break;
                case 1:
                        rt_hw_led1_on();
                        break;
                default:
                        break;
                }
        }

        if ( led == 1 )
        {
                /* set led status */
                switch (value)
                {
                case 0:
                        rt_hw_led1_off();
                        break;
                case 1:
                        rt_hw_led1_on();
                        break;
                default:
                        break;
                }
        }
}




#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(led, set led[0 - 1] on[1] or off[0])
//FINSH_FUNCTION_EXPORT(led_toggle, toggle the leds)

#endif


led_disp 栈溢出!.jpg (原文件名:led_disp 栈溢出!.jpg)

出0入0汤圆

发表于 2011-4-18 11:56:44 | 显示全部楼层
1,128太小,先设为1K,再在finsh里list_thread看最大用了多少,再留点余量来确定用多大。
2.都用上OS了,还用do_while来死等延时?

出0入0汤圆

发表于 2011-4-18 12:08:16 | 显示全部楼层
代码好多好乱啊

这个似乎仅是警告,把栈加大些吧,如果说是128字节,那只能说你太吝啬啦:-)

出0入0汤圆

发表于 2011-4-18 12:23:59 | 显示全部楼层
要用到底要配多大?
看stack_init() 再看编泽出来的报告文件里面统计的线程所在函数做最大栈深度。
如果糸统构架里中断共用线程栈,则还要算上这个,
如果有递归调用则还要预测最大可能的深度。如果不能保证,尽量别用。

所以最方便还是先设足够大,再让糸统把全部功能跑一遍看用了多少,再尽可能多留点余量。

出0入0汤圆

 楼主| 发表于 2011-4-18 18:09:12 | 显示全部楼层
主要是在我没改之前,它是没有这个提示, 而我去掉个函数他反而不足了, 这点我不明白是为什么?

原代码用的是,do..while


我改成,操作系统延时了, 不会是这个的原因吧! 试试!

出0入0汤圆

 楼主| 发表于 2011-4-18 18:18:24 | 显示全部楼层
试了一下, 就是我加了,rt_thread_delay(100); 的原因, 换成do while延时就好啊,

看来,rt_thread_delay(100); 占的栈不小啊,

出0入0汤圆

发表于 2011-4-18 18:25:08 | 显示全部楼层
do...while仅占用一个寄存器,不占用栈,运气最坏也仅压一个字。
而rt_thread_delay()要多少自己看去.

128字节,光R0-Rn就得nx4字节,打花谁呢! stack_check里就要32字节余量。
finsh都用了,还舍不得这点。

出0入131汤圆

发表于 2011-4-18 19:28:35 | 显示全部楼层
其实最怕的就是 函数里调用函数再调用函数,每次调用都会压栈,这样压栈压栈再压栈会导致栈溢出。
还有中断嵌套有时也会导致栈溢出。
还有个原因 就是局部变量用多了。
我上个星期就因为栈溢出原因查我的程序查了4天没查出来,鸟编译器溢出的话没有任何警告。

出0入0汤圆

发表于 2011-4-18 23:15:49 | 显示全部楼层
回复【7楼】asj1989  
我上个星期就因为栈溢出原因查我的程序查了4天没查出来,鸟编译器溢出的话没有任何警告。
-----------------------------------------------------------------------

彰显栈溢出检查的好处:-)

出0入0汤圆

 楼主| 发表于 2011-4-19 08:13:46 | 显示全部楼层
是啊,溢出是最头疼的事了,

而且溢出常常发生在特定条件下!

溢出检查太有用了!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 04:37

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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