硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1410|回复: 7
收起左侧

[技术讨论] STM32L412CBU6制作外部QSPI下载算法可以全片擦除,但是下载代码就会报错

[复制链接]

4

主题

10

回帖

22

积分

新手上路

积分
22
发表于 2023-2-7 14:12:38 | 显示全部楼层 |阅读模式
如题,STM32L412CBU6自带QSPI接口,并且支持XIP,但是目前我制作的下载算法可以实现全片擦除(图1)但是却不能下载代码,一点load按钮就报错(图二),郁闷死了,已经调试了2天了,真的不知道哪里出问题了,QSPI驱动读、写、擦除函数都已经测试过可以正常工作,数据也都正确,但是用它制作Keil5的下载算法就是不行,flash型号是S25FL064K,8M容量的。关键是网上关于STM32L4单片机的资料又比较少,非常郁闷。。。(工程在下面,求指教

图一

图一

图二

图二

STM32L412CBU6_W25Q64_FLM.rar

870.85 KB, 下载次数: 10

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2023-2-7 15:03:04 | 显示全部楼层
1、重定向改下
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*        函 数 名: HAL_InitTick
*        功能说明: 重定向,不使用
*        形    参: ----
*        返 回 值: 无
*********************************************************************************************************
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
        return HAL_OK;
}

uint32_t HAL_GetTick (void) 
{
        static uint32_t ticks = 0U;
        uint32_t i;
        
        for (i = (SystemCoreClock >> 14U); i > 0U; i--) 
        {
                __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
                __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
        }
        
        return ++ticks;
}

void HAL_Delay(uint32_t Delay)
{
        uint32_t tickstart = HAL_GetTick();
        uint32_t wait = Delay;
        
        if (wait < HAL_MAX_DELAY)
        {
                wait += (uint32_t)(HAL_TICK_FREQ_DEFAULT);
        }
        
        while((HAL_GetTick() - tickstart) < wait)
        {
                __NOP();
        }
}


2、然后就是QSPI的支持内存映射模式不,支持的话,参考我这个H7的略微修改下试试

https://www.armbbs.cn/forum.php?mod=viewthread&tid=86980&extra=page%3D1
image.png









回复

使用道具 举报

4

主题

10

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2023-2-8 17:23:31 | 显示全部楼层
感谢硬汉回复。目前排查出的问题就是下载算法不会运行到ProgramPage函数里去,我在ProgramPage函数里放了一个点亮LED的语句(如图1),发现板子上的LED没亮,但是我把这个语句加到其他例如Init、UnInit、EraseChip、EraseSector函数中的return 0语句前面,LED都会亮,说明都执行正常,(return 0表示执行OK),但是就算放在ProgramPage函数最开始的位置都不亮,说明下载算法压根就没有运行到ProgramPage函数里去,接着就报“Programming Failed!”错误,然后对照MDK下载代码流程图,应该是(图2)红圈里的环节出问题,感觉是用户代码未能正确加载在到RAM里去,最终导致ProgramPage函数没有执行就退出报错了,但是目前我尚未找到解决方法。。。
我给出的解释就是STM32L412CBU6的RAM只有40KB,其中32KB是连续的,MDK将下载算法装入RAM后就没有足够的RAM缓冲区来装载用户的代码了,所以没有执行ProgramPage函数就直接退出报错了。最燃这种解释没有根据,但是实在不知道该怎么去解决了,用了硬汉给的方法也不行。
图一.jpg
图二.JPG
回复

使用道具 举报

4

主题

10

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2023-2-8 17:44:12 | 显示全部楼层
eric2013 发表于 2023-2-7 15:03
1、重定向改下
[mw_shl_code=c,true]/*
************************************************************* ...

感谢硬汉回复,目前排查出的问题就下载算法压根就没有执行到ProgramPage函数里面去(图一),因为我在ProgramPage函数最开始的地方加了一个点亮LED的语句,但是板子上的LED没有亮,而在其他函数例如Init、Uninit()、EraseSector()、EraseChip()等函数里就能点亮LED,并且是在return 0语句前加入的该语句,说这些函数都正确执行了,唯独这个ProgramPage函数没有被执行到。
我猜测的原因就是:STM32L412CBU6的RAM只有40KB,连续的只有32KB,对比MDK下载代码的流程图来看,应该是图二红圈里的环节出问题了,MDK将下载算法加载到RAM里后就没有足够的RAM空间来作为烧录用户代码的缓冲区了,所以MDK直接就没有执行ProgramPage函数就退出报错了,虽然我的猜想缺乏库科学依据。。。目前下载算法仍然未能成功

图1

图1

图2

图2
回复

使用道具 举报

5

主题

18

回帖

33

积分

新手上路

积分
33
发表于 2023-2-8 22:07:29 | 显示全部楼层
无聊的码农 发表于 2023-2-8 17:44
感谢硬汉回复,目前排查出的问题就下载算法压根就没有执行到ProgramPage函数里面去(图一),因为我在Pro ...

要不你看看MAP文件,验证一下你的想法
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2023-2-9 00:25:21 | 显示全部楼层
无聊的码农 发表于 2023-2-8 17:44
感谢硬汉回复,目前排查出的问题就下载算法压根就没有执行到ProgramPage函数里面去(图一),因为我在Pro ...

足够用

    Total RO  Size (Code + RO Data)                21632 (  21.13kB)
    Total RW  Size (RW Data + ZI Data)              4192 (   4.09kB)
    Total ROM Size (Code + RO Data + RW Data)      21652 (  21.14kB)
回复

使用道具 举报

4

主题

10

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2023-2-9 16:39:26 | 显示全部楼层
eric2013 发表于 2023-2-9 00:25
足够用

    Total RO  Size (Code + RO Data)                21632 (  21.13kB)

也不知道问题该怎么解决,可以确定的是ProgramPage函数就是没有执行到,但是原因未知,已经花费了太多时间了,得继续把其他功能实现了,这个下载算法先放着,以后再去鼓捣
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2023-2-10 09:05:22 | 显示全部楼层
无聊的码农 发表于 2023-2-9 16:39
也不知道问题该怎么解决,可以确定的是ProgramPage函数就是没有执行到,但是原因未知,已经花费了太多时 ...

抽空参考我的实现例子,你这个做的略复杂,另外你的页编程大小怎么配置了个8K

这个是我的
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*	模块名称 : FlashDev
*	文件名称 : FlashDev.c
*	版    本 : V1.0
*	说    明 : Flash配置
*
*	修改记录 :
*		版本号  日期         作者       说明
*		V1.0    2020-11-06  Eric2013   正式发布
*
*	Copyright (C), 2020-2030, 安富莱电子 [url]www.armfly.com[/url]
*
*********************************************************************************************************
*/
#include "FlashOS.H"       


#ifdef FLASH_MEM
struct FlashDevice const FlashDevice  =  {
    FLASH_DRV_VERS,                   /* 驱动版本,勿修改,这个是MDK定的 */
    "ARMFLY_STM32H7x_QSPI_W25Q256",   /* 算法名,添加算法到MDK安装目录会显示此名字 */
    EXTSPI,                           /* 设备类型 */
    0x90000000,                       /* Flash起始地址 */
    32 * 1024 * 1024,                 /* Flash大小,32MB */
    4 * 1024,                         /* 编程页大小 */
    0,                                /* 保留,必须为0 */
    0xFF,                             /* 擦除后的数值 */
    1000,                             /* 页编程等待时间 */
    6000,                             /* 扇区擦除等待时间 */
    64 * 1024, 0x000000,              /* 扇区大小,扇区地址 */
    SECTOR_END    
};
#endif 

/***************************** 安富莱电子 [url]www.armfly.com[/url] (END OF FILE) *********************************/


[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: ProgramPage
*	功能说明: 页编程
*	形    参: adr 页起始地址
*             sz  页大小
*             buf 要写入的数据地址
*	返 回 值: 无
*********************************************************************************************************
*/
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) 
{
    int size;
    int result = 0;

    /* 地址要在操作的芯片范围内 */    
    if (adr < QSPI_FLASH_MEM_ADDR || adr >= QSPI_FLASH_MEM_ADDR + QSPI_FLASH_SIZES)
    {
        return 1;
    }
   
    /* W25Q256初始化 */
    result = bsp_InitQSPI_W25Q256();
    if (result != 0)
    {
        return 1;
    }
        
    adr -= QSPI_FLASH_MEM_ADDR;
    size =  sz;
    
    /* 页编程 */
    while(size > 0)
    {
        if (QSPI_WriteBuffer(buf, adr, 256) == 1)
        {
            QSPI_MemoryMapped(); 
            
            return 1;   
        }
        size -= 256;
        adr += 256;
        buf += 256;
    }
    
    /* 内存映射 */    
    result = QSPI_MemoryMapped(); 
    if (result != 0)
    {
        return 1;
    }
    
    return (0);                      
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 08:18 , Processed in 0.182259 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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