CH32X035 MRS v1.92 卡在while循环里出不来

MCU:? CH32X035C8

MRS 版本: v1.92



void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));


void SysTick_Handler(void)

{

? ? runMilis++;


? ? SysTick->SR = 0;

}


//-------------------------------------------------------------------------------------//

// Get System tick counter

//-------------------------------------------------------------------------------------//

uint32_t get_time_tick(void)

{

? ? return runMilis;

}


//--------------------------------------------------------------------------//

// Delay function

//--------------------------------------------------------------------------//

void DelayMS( uint32_t nMS )

{

? ? volatile uint32_t now = get_time_tick();


? ? while( (get_time_tick() - now) < nMS );

}


仿真时 nMS = 500,? 变量 now = 1,? runMilis = 5389, 按理已经应该return了,但实际上程序还卡在while里出不来。


请问原厂的FAE,这个函数有什么问题吗?为何一直卡住?是不是编译器有啥BUG?

同样的程序,在keil MDK里运行正常,但到了MRS里就会一直卡住

79f6ede03c9fe9e270227a43c6a0b7e.png


没有看见你的runMilis变量的声明。这个变量应该是也需要定义为volatile的。反而是now变量可以不必使用volatile。

从左侧透露出的反汇编可以推测,lw a5,12这句应当是在读取内存中now变量的值,反而没有看到应该存在的读取内存中runMilis变量的指令,下面的sub指令直接令寄存器a4的值减去a5的值。假如你将runMilis变量定义为volatile的,则应当同时出现两句lw指令,分别从内存加载runMilis和now变量。

综上,将runMilis变量用volatile修饰应该可以解决。


感谢楼上网友的回答!


事实上我的runMilis变量也是加了volatile修饰的。感觉MRS的编译器非常奇怪,即使按照ANSI C的写法,仍会有一些奇奇怪怪的的问题。

1724342794485.png


根据实际debug发现,函数内的now变量如果不加volatile修饰,则会被编译器optimization out


debug时看到变量被优化不影响该变量在函数内的读取,因为此时变量只是固定存于寄存器中,理论上并不影响程序运行,只是调试时麻烦。

我也常遇到gcc有时自作聪明把全局变量变成寄存器访问(即没有每次访问去都去内存读现在的值),这一点还是等待官方工作人员来帮忙吧。


您好,附件例程是我根据你的配置测试,测试并没有遇到卡死的问题,你可以测试一下。或可将你可复现问题的工程发我邮箱(lzs@wch.cn)具体看一下。

icon_rar.gifCH32X035 SysTick.zipimage.png



只有登录才能回复,可以选择微信账号登录