GD32 库函数systick库BUG报告

[复制链接]
411|16
手机看帖
扫描二维码
随时随地手机跟帖
lifenghk|  楼主 | 2022-11-23 20:51 | 显示全部楼层 |阅读模式
测试芯片GD32F303CCT6
systick库中的delay_1ms(int ms) 函数存在重大BUG,进入就会死循环。打开库文件发现根本未进行正确实现。库文件代码如下:
/*!
    \brief      delay a time in milliseconds
    \param[in]  count: count in milliseconds
    \param[out] none
    \retval     none
*/
void delay_1ms(uint32_t count)
{
    delay = count;

    while(0U != delay){
    }
}

而这根本就未对delay做任何操作,不可能跳出循环。改用其他来源的delay函数才解决。
对比发现,F10x,E230,F30x等系列所提供的库函数均存在此BUG。systick库非常粗糙,未进行正确实现。

使用特权

评论回复
确实有时候会有这种问题,库文件得即使更新纠正问题

使用特权

评论回复
sonicll| | 2022-11-24 09:45 | 显示全部楼层
你这是只看了代码,从来没在板子上跑过例程吗?只要你跑过一个例子,就会发现systick中断服务函数里调用了delay_decrement(),delay值是在delay_decrement函数里做递减的。这么简单的问题,如果真是bug,早就有人反馈了

使用特权

评论回复
lvben5d| | 2022-11-24 13:08 | 显示全部楼层
这种全局变量  首字母不大写的写法,要打PP 。 Delay = count   起码看上去区别于局部变量顺一些, 要是 ex_Delay  保不齐更利于新人们看看

使用特权

评论回复
jackcat| | 2022-11-25 10:38 | 显示全部楼层
参考stm32的systick熟悉爱你delayms的功能吧。

使用特权

评论回复
kkzz| | 2022-11-25 10:49 | 显示全部楼层
这个还真没有遇到过。              

使用特权

评论回复
lifenghk|  楼主 | 2022-11-25 10:52 | 显示全部楼层
sonicll 发表于 2022-11-24 09:45
你这是只看了代码,从来没在板子上跑过例程吗?只要你跑过一个例子,就会发现systick中断服务函数里调用了d ...

就是因为在板子上跑程序,调用这个函数就会死机。

使用特权

评论回复
modesty3jonah| | 2022-11-25 11:10 | 显示全部楼层
这个是库里面自带的函数的吗              

使用特权

评论回复
maudlu| | 2022-11-25 12:09 | 显示全部楼层
为什么不使用定时器实现delay函数呢

使用特权

评论回复
m564522634| | 2022-11-25 18:03 | 显示全部楼层
delay  明显就不是一个局部变量了, 你怎么算出不做啥的

使用特权

评论回复
sagade| | 2022-11-26 09:56 | 显示全部楼层
特意去试了下,文件完全没有问题的,是你没有调用systick_config吧,还有SysTick_Handler里面有没有调用delay_decrement。

使用特权

评论回复
呐咯密密| | 2022-11-26 16:53 | 显示全部楼层
我在这个函数也卡死,自己写了一个

使用特权

评论回复
呐咯密密| | 2022-11-26 16:56 | 显示全部楼层
uint32_t  fac_us=0;        
#define assert_param(expr) ((void)0)
#define SysTick_CTRL_ENABLE_Pos1             0U                                            /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk1            (1UL << SysTick_CTRL_ENABLE_Pos1)  

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  
  if (SysTick_CLKSource == SYSTICK_CLKSOURCE_HCLK)
  {
    SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
  }
  else
  {
    SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8;
  }
}

/************************************************
函数名称 : delay_init
功    能 : 延时初始化
参    数 : 无
返 回 值 : 无
作    者 : Mico
*************************************************/
void delay_init(void)
{

        SysTick_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);        //选择外部时钟  HCLK/8
        fac_us=SystemCoreClock/8000000;                                //为系统时钟的1/8  

}       
/************************************************
函数名称 : delay_us
功    能 : 实现微秒级别延时
参    数 : nus
返 回 值 : 无
作    者 : Mico
*************************************************/

void delay_us(uint32_t nus)
{               
       
        uint32_t temp;                     
        SysTick->LOAD=nus*9;                                         //时间加载                           
        SysTick->VAL=0x00;                                                //清空计数器
        SysTick->CTRL|=0x01 ;        //开始倒数          
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk1;        //关闭计数器
        SysTick->VAL =0X00;                                               //清空计数器         
}


使用特权

评论回复
jacques0408| | 2022-11-26 17:05 | 显示全部楼层
我用的GD32C103,我这款是在gd32c10x_it.c文件的 void SysTick_Handler(void) 函数中调用delay_decrement(); 每次进入此中断就给delay变量减一。
T93WE])((ME%~M]9Q5TNU}N.png
6)HP2`DOF`J7[CTY}H_BVN7.png

使用特权

评论回复
sonicll| | 2022-11-28 09:28 | 显示全部楼层

这种用法需要注意systick的计数值是24bit的,所以延时时间不能设置的太长

使用特权

评论回复
呐咯密密| | 2022-11-28 09:55 | 显示全部楼层
sonicll 发表于 2022-11-28 09:28
这种用法需要注意systick的计数值是24bit的,所以延时时间不能设置的太长

是这样的,所以只是us的延时,可以在套一下变成ms

使用特权

评论回复
imdx| | 2022-11-28 10:35 | 显示全部楼层
这不是bug,是你没看懂代码。SysTick的ISR中会调用delay_decrement函数修改delay这个变量。
而且,这根本不是库,systick在Template目录下,只是一个简单的demo而已。

使用特权

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

本版积分规则