您尚未登录。

楼主 # 2023-10-20 17:08:58

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,211
积分: 1147.5

求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

gd32f103,定时器10ms一中断,让一变量自增,其他函数里根据这个变量计数100次后置位1秒标值。main函数主循环里判断该标志位是否置位,是1的话,让led反转,并清该标志位。

mdk工程,之前是-o3优化等级,运行后正常。硬件仿真时,我改成了-o1优化,发现运行大概20秒后,led就不正常反转了。

-o3优化:led每秒反转,正常;
-o2优化,前20秒led能每秒反转,然后就变成很快的频率闪烁了;
-o1优化,前20秒led能每秒反转,然后就变成很快的频率闪烁了;
-o0优化,前20秒led能每秒反转,然后就变成很快常亮了;

程序比较大,有modbus数据区,占几k字节。编译后也比较占资源。

-o3:
Program Size: Code=31348 RO-data=1104 RW-data=504 ZI-data=24368 

-o2:
Program Size: Code=31408 RO-data=1104 RW-data=504 ZI-data=24368 

-o1:
Program Size: Code=33712 RO-data=1204 RW-data=504 ZI-data=24368 

-o0:
Program Size: Code=41236 RO-data=1204 RW-data=536 ZI-data=28656 

看了下-o3和-o2,应该是rom只差1k左右。

芯片是gd32f105vc,我查gd32f103vc是48k ram, 256k rom.

10ms定时器中断里自增的变量是volatile类型的,该变量整除100时置位的bool类型变量,也是声明成volatile类型的。

最近编辑记录 Gentlepig (2023-10-20 17:41:19)

离线

楼主 #1 2023-10-21 10:10:26

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,211
积分: 1147.5

Re: 求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

硬件仿真,对比-o1情况下定时器的寄存器情况,前20面正常时和后来狂闪时,发现定时器的重载定时器和控制器寄存器1没有变化。
-o0情况下,程序运行20秒后卡死,发现尽到了HardFault_Handler()。
根据https://blog.csdn.net/electrocrazy/article/details/78173558
定位到是spi_flash_write()函数。

挨个注释main主循环里的函数,发现注释掉保存数据到spiflash这个函数后,程序正常运行。那么,问题应该就是出在spi_ flash_ write这个函数了,但是我看网上大部分教程,原子、野火,大都是这么写的:

void SPI_FLASH_Write ( u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite )
{
    u32 secpos;
    u16 secoff;
    u16 secremain;
    u16 i;

    secpos = WriteAddr / 4096;
    secoff = WriteAddr % 4096;
    secremain = 4096 - secoff;

    if ( NumByteToWrite <= secremain )
        secremain = NumByteToWrite;

    while ( 1 )
    {
        SPI_FLASH_BufferRead ( spiFlashBuff, secpos * 4096, 4096 );
        for ( i = 0; i < secremain; i++ )
        {
            if ( spiFlashBuff[secoff+i] != 0xFF )
                break;
        }
        if ( i < secremain )
        {
            SPI_FLASH_SectorErase ( secpos * 4096 );
            for ( i = 0; i < secremain; i++ )
                spiFlashBuff[i+secoff] = pBuffer[i];
            SPI_FLASH_BufferWrite ( spiFlashBuff, secpos * 4096, 4096 );
        }
        else
            SPI_FLASH_BufferWrite ( pBuffer, WriteAddr, secremain );
        if ( NumByteToWrite == secremain )
            break;
        else
        {
            secpos++;
            secoff = 0;
            pBuffer += secremain;
            NumByteToWrite -= secremain;
            if ( NumByteToWrite > 4096 )
                secremain = 4096;
            else
                secremain = NumByteToWrite;
        }
    }
}

而且,为何优化等级不同,结果却不同?

离线

楼主 #2 2023-10-21 11:56:30

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,211
积分: 1147.5

Re: 求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

有群友说,spi flash擦写比较耗时,然后我定时器中断比较频繁,我是用的10ms定时器。spi_flash_write()执行时,频繁中断耗尽了堆空间。
不过我还是不太明白...

离线

#3 2023-10-21 14:50:27

Fomalhaut
会员
注册时间: 2021-10-28
已发帖子: 36
积分: 31

Re: 求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

优化等级会改变程序行为,除了性能以外,多半是是用了未定义行为。

离线

楼主 #4 2023-10-21 15:05:56

Gentlepig
会员
注册时间: 2018-10-24
已发帖子: 1,211
积分: 1147.5

Re: 求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

问题找到了,在一个函数中,给某个数组赋值时,访问越界,比如int arr[8],结果我给arr[9]赋值了,于是进入hardfault_handler了。
更详细一点就是,本来NUMBER定义的比较小,这次我改大了,没注意到有个数组赋值时用到了这个宏定义。

//#define NUMBER 16
#define NUMBER 32
uint8_t arr[32];
for(u8 i = 0; i < 16+i+NUMBER; i++)
{
    arr[i] = 1;
}

而这个函数里,还调用了spi_flash_write(),于是我就以为是spi_flash操作引起了错误。

这能解释-o0会进入hardfault_hander(),但是为什么-o3优化能正常运行?
-o1,o2 led狂闪?

最近编辑记录 Gentlepig (2023-10-21 16:01:47)

离线

#5 2023-10-21 18:06:44

sjshe3326
会员
注册时间: 2020-10-19
已发帖子: 123
积分: 67.5

Re: 求助,定时器中断,实现1s led反转,-o3优化正常,其他优化均不正常。程序占用ram rom过大的原因?

@Gentlepig
有可能 -O3 把你这段优化成了上电直接初始化内存值,不用循环访问。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn