打印

gd32f150 bootloader

[复制链接]
10987|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 〽️〽️〽️ 于 2021-3-3 14:25 编辑

boot放在0x08000000
app放在  0x08004000

1.用的外部晶振
2.用了UART0 DMA空闲中断完成升级, 也就是bootloader用到了中断

现在升级都正常,升级的文件也对的
但是升级后app运行异常,表现是速度变慢了

#define APP_ADDRESS             (uint32_t)0x08004000

bootloader 里:
void vJumpToApplication(void)
{
    uint32_t  JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
    pFunction Jump_To_Application;

     if (((*(__IO uint32_t*)APP_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
     {
        __disable_irq();  //由于boot 用了中断,不加这句话的话,跳转了直接不运行app
         __set_MSP(*(__IO uint32_t*) APP_ADDRESS);         
        JumpAddress = *(__IO uint32_t*) (APP_ADDRESS + 4);           
        Jump_To_Application = (pFunction) JumpAddress;
        Jump_To_Application();  
     }      


app 里
int main(void)
{
          SCB->VTOR = 0x08004000;   //APP下载的地址
          sys_init();
          __enable_irq(); //boot关了,要打开    
         while(1)
        {
             ...
        }        
}

使用特权

评论回复
沙发
单片小菜| | 2021-3-3 14:57 | 只看该作者
禁止中断和使能中断,之后就可以跳转了吗?

使用特权

评论回复
板凳
〽️〽️〽️|  楼主 | 2021-3-3 15:23 | 只看该作者
本帖最后由 〽️〽️〽️ 于 2021-3-3 15:25 编辑
单片小菜 发表于 2021-3-3 14:57
禁止中断和使能中断,之后就可以跳转了吗?

可以跳转,也能运行,但是运行的不对,整体变慢了,我跟踪了晶振部分又发现是初始化了外部晶振 没用内部,说明不是因为晶振切换到了内部而变慢了

错误的表现是,一个定时器发送的间隔,原来10ms的 现在变成了大约1s的样子。

其他串口什么通信都是对的,但是串口关了了这个定时器,所以也就跟着串口异常了

boot里也试过关闭 或者 deint那些打开的外设 都没用

使用特权

评论回复
地板
dujunqiu| | 2021-3-3 15:27 | 只看该作者
1.1 修改库时钟,启动时间宏定义在xxx32f10x.h头文件中;
将宏定义#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)
修改为 #define HSE_STARTUP_TIMEOUT ((uint16_t)0xFFFF)


这里改了吗

使用特权

评论回复
5
sonicll| | 2021-3-3 15:36 | 只看该作者
如果APP的串口能正常通信,你可以试试把系统时钟配置相关的几个寄存器,还有TIMER的寄存器值打印出来,看看是哪个寄存器配置的问题

使用特权

评论回复
6
〽️〽️〽️|  楼主 | 2021-3-3 15:54 | 只看该作者
dujunqiu 发表于 2021-3-3 15:27
1.1 修改库时钟,启动时间宏定义在xxx32f10x.h头文件中;
将宏定义#define HSE_STARTUP_TIMEOUT ((uint16_t ...

谢谢!

用的GD库    2017-06-19, V3.1.0
HSE_STARTUP_TIMEOUT   默认看是0x0800,我改了0xFFFF也是不行


使用特权

评论回复
7
里面有晴雨| | 2021-3-3 19:41 | 只看该作者
我一直卡在了跳转的地方,现在好了,解决了。

使用特权

评论回复
8
〽️〽️〽️|  楼主 | 2021-3-3 22:34 | 只看该作者
GD32F150G8 用的GD3.1.0库

精简到最小代码 ,去掉了boot的全部中断全部外设功能,
现在定位到了,如下

bootloader跳转到 app,  app可以运行,带代码有些功能异常


app直接0x08000000下载运行一切正常。



boot代码如下   非常简单   iMDK  rom是0x08000000


#define APP_ADDRESS    (uint32_t)0x08004000   

void vJumpToApplication(void);
typedef void (*pFunction)(void);  


/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
   vJumpToApplication();
}

/*!
    \brief      vJumpToApplication
    \param[in]  none
    \param[out] none
    \retval     none
*/
void vJumpToApplication(void)
{
    uint32_t  JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
    pFunction Jump_To_Application;

    if (((*(__IO uint32_t*)APP_ADDRESS) & 0x2FFE0000 ) == 0x20000000)  
    {
        JumpAddress = *(__IO uint32_t*) (APP_ADDRESS + 4);            
        Jump_To_Application = (pFunction) JumpAddress;
        __set_MSP(*(__IO uint32_t*) APP_ADDRESS);
        Jump_To_Application();                                
    }
    else
    {
        while(1);
    }
}


app代码就改动2处
1. 就mdk 设置irom  0x08004000
2. app的main开头加了句SCB->VTOR = 0x08004000;

这样情况都不行,前面几位提到的晶振延时,中断关闭打开 都排除了

使用特权

评论回复
9
〽️〽️〽️|  楼主 | 2021-3-3 23:08 | 只看该作者
本帖最后由 〽️〽️〽️ 于 2021-3-3 23:27 编辑

继续找定位:发现如下
1. 如果直接将app下载到0x08000000地址运行,一切正常
2. 如果通过bootloader跳转到0x08004000地址运行app,
    那么会导致app中有2个全是float浮点变量的 ln以e为底 运算的函数 时间变得翻n倍,
    正常只要几ms, 现在要几十ms,   导致最终代码逻辑异常,这样和我前面说的串口
    收发通信正常也符合的,只是串口收发也被这个卡住变慢些而已。


这何解?,仅仅是boot跳转 会导致  float变量的 ln e计算 一个私有函数(补充下,参与的float 也都是正常的值) 变化这么多时间?
其他定时器, systick都是正常的。

使用特权

评论回复
10
suncl110| | 2021-3-4 08:21 | 只看该作者
app配置时钟后,等待成功并稳定运行后,再切换。试试

使用特权

评论回复
11
sonicll| | 2021-3-4 09:13 | 只看该作者
你的APP代码有多大?超过16K了吗?F1x0系列,只有前32K flash是取指零等待,32K后面的部分,取指速度会变慢,所以你的app起始地址在0x08004000,大小不能超过16K

使用特权

评论回复
12
〽️〽️〽️|  楼主 | 2021-3-4 09:40 | 只看该作者
本帖最后由 〽️〽️〽️ 于 2021-3-4 09:50 编辑
sonicll 发表于 2021-3-4 09:13
你的APP代码有多大?超过16K了吗?F1x0系列,只有前32K flash是取指零等待,32K后面的部分,取指速度会变慢 ...

您好,非常感谢。应该是您说的问题关键点上了,这个我确实未知GD32F150 指令等待的问题

我的代码 boot 16k,  app 超过31k的。  GD150总flash是64k。

原来app直接下载到0x08000000,刚好不超32K

现在16+31k, 那如果ln e的float函数刚好分配在后面 就取指速度变慢,完全符合你的指导说法。


请问有什么办法可以让我2几个计算 float  lne的复杂函数放在前面几k    如10k的地方呢(这样16+10就不会超过32),保证后面app bin再大即使40k 代码 。 这2函数也不会让编译器分配到32k外 ?
是不是这样就解决了?

使用特权

评论回复
13
sonicll| | 2021-3-4 09:52 | 只看该作者
〽️〽️〽️ 发表于 2021-3-4 09:40
您好,非常感谢。应该是您说的问题关键点上了,这个我确实未知GD32F150 指令等待的问题

我的代码 boot 16 ...

可以用绝对地址定位,例如:

void my_function(void) __attribute__((section(".ARM.__at_0x08005000")));

void my_function(void)
{
    /*代码*/
}

使用特权

评论回复
14
〽️〽️〽️|  楼主 | 2021-3-4 11:17 | 只看该作者
void my_function(void) __attribute__((section(".ARM.__at_0x08005000")));

看到代码分配不超过 32k了, 但还是不行,

使用特权

评论回复
15
〽️〽️〽️|  楼主 | 2021-3-4 16:17 | 只看该作者
试了一天,发现还是有问题的,主要就是超过32k的,有些在32k外函数都很慢。 又不能全部放32k内,导致异常,看来32k外只能做些普通const用,不能放代码呀。

具体有指标吗?  换GD32F350G8?       64k也这样吗?,还是64k全零等待呢 、其他厂商的MCU也都有这个32k前 0等待,后面的满吗?

使用特权

评论回复
16
〽️〽️〽️|  楼主 | 2021-3-4 21:36 | 只看该作者
本帖最后由 〽️〽️〽️ 于 2021-3-4 21:37 编辑
sonicll 发表于 2021-3-4 09:52
可以用绝对地址定位,例如:

void my_function(void) __attribute__((section(".ARM.__at_0x08005000"))) ...

白天的这个问题,晚上又被我自己都否了,如下

我去掉boot, 故意只用app  烧到0x08000000,然后关键的2个前面发现延时的函数
我又故意放到32K后面

结果, 一切都正常

说明boot跳到app后  还是其他问题导致慢,应该不是这个32k 前面零等待的取指 前后的问题了。

另外前面也有兄弟说 晶振稳定问题, boot到app后,我的systick 时间,正常的,串口也是正常的
那应该不存在时钟问题?

QQ图片20210304213543.png (15 KB )

QQ图片20210304213543.png

QQ图片20210304213033.png (5.12 KB )

QQ图片20210304213033.png

QQ图片20210304213014.png (2.31 KB )

QQ图片20210304213014.png

使用特权

评论回复
17
imdx| | 2021-3-4 22:21 | 只看该作者
gd32f150c8t6你当它只有32kB 闪存就行了

使用特权

评论回复
评论
〽️〽️〽️ 2021-3-4 23:09 回复TA
先前2个函数慢的,我故意放它们到32k外面, 发现不从boot跳到app话,它们两个也正常的 那说明还有其他函数放外面是可能引起不正常的,但这也说不太通。 因为那2个函数慢的,是阻塞方式的 大数据计算,最多被中断打断。非RTOS也不会切掉任务 既然放32k外也OK, 那我觉得可以排除32k 前后的问题了 
18
〽️〽️〽️|  楼主 | 2021-3-4 23:05 | 只看该作者
百度到的,别的处理器有这个问题cache问题


GD32F150 和 GD 3.1.0的库  会有这种cache概念吗? 看描述的问题也是和我非常像


QQ图片20210304230255.png (446.19 KB )

QQ图片20210304230255.png

使用特权

评论回复
19
sonicll| | 2021-3-5 09:23 | 只看该作者
你的两个计算ln的函数,有调用其他子函数吗?如果有子函数的话,子函数地址在前32K吗?我说的子函数,包括C库里的sin,log等数学计算的函数

使用特权

评论回复
20
〽️〽️〽️|  楼主 | 2021-3-5 09:58 | 只看该作者
sonicll 发表于 2021-3-5 09:23
你的两个计算ln的函数,有调用其他子函数吗?如果有子函数的话,子函数地址在前32K吗?我说的子函数,包括C ...

谢谢!
通宵了一晚,还是没进展

这个子函数 除了 f_temp=log(adc_average)-log(first[0]);  也就是调用#include <math.h>里的log计算

其他无任何调用函数了

使用特权

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

本版积分规则

51

主题

377

帖子

2

粉丝