如何将STM32CubeMX + TouchGFX 工程中生成的图片,字库等超大数组保存到QSPI FLASH (W25Q256)

软件环境:STM32CubeMX5.3  、TouchGFX 4.10.0 Designer、uVision5.28.0.0

硬件环境:正点原子阿波罗STM32F767开发板、4.3寸LCD接口屏(480×272)、W25Q256

本博客源码链接(GitHub):https://github.com/ningjw/stm32f7_os/tree/01683d112abdf378b2db0a7df6fa847afd277478

本博客源码链接(CSDN):https://download.csdn.net/download/Ningjianwen/12000298

使用TouchGFX设计界面时,TouchGFX会将所有的图片资源转换成c数组形式,而图片资源占用的空间是特别大的,而STM32F767内部Flash有限,所以我们需要将图片资源放入QSPI FLASH中,接下来就教你解决这个问题。

1. 我们随便打开工程里的一个图片资源数组(Application/User/TouchGFX/generated 分类下),可以发现所有的图片资源都使用了LOCATION_EXTFLASH_ATTRIBUTE 进行修饰

2. 在Config.hpp文件中,可以发现LOCATION_EXTFLASH_ATTRIBUTE 的定义如下,增加该属性表示该数组会优先存放在名为“ExtFlashSection”的内存区域中:

#define LOCATION_EXTFLASH_ATTRIBUTE __attribute__ ((section ("ExtFlashSection"))) __attribute__ ((aligned(4)))

3. 默认是没有“ExtFlashSection”区域的,我们需要通过编写分散加载文件来配置“ExtFlashSection”段,首先通过下面的Edit按钮打开KEIL自己生成的sct文件,将该文件复制下来,并重命名为FLASH.sct

4. 在FLASH.sct文件中增加一个LR_EROM1加载域(命名可以随意),该加载域中定义了ExtFlashSection、FontFlashSection、TextFlashSection段,这样下载的时候图片资源就自动下载到该区域里面了,完整的代码如下:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00200000 0x00100000  {    ; load region size_region
  ER_IROM1 0x00200000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
	
  RW_IRAM1 0x20000000 0x00080000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

LR_EROM1 0x90000000 0x02000000  {    ; load region size_region
  ER_EROM1 0x90000000 0x02000000  {  ; load address = execution address
		*.o (ExtFlashSection)
		*.o (FontFlashSection)
		*.o (TextFlashSection)
	}
}

5.  通过以上配置后,在下载代码的时候,会出现“No Algorithm found for: 90000000H - 9000FFFFH”等等错误,这是因为你还没有为该段区域配置下载算法。

首先需要下载一个STM32F767_W25Q256.FLM文件(链接:https://download.csdn.net/download/ningjianwen/11643298),将该文件放入C:\Keil_v5\ARM\Flash目录,然后就可以在以下界面添加该算法了,这里有以下几点需要注意:

(另外附上生成算法的工程链接:https://download.csdn.net/download/Ningjianwen/12000367,用MDK打开该工程后,直接编译就可以生成FLM算法文件)

  • 需要修改RAM for Algorithm的Size大小,因为我们的STM32F767_W25Q256.FLM文件比较大,需要更大的空间加载算法
  • Verify不要勾选,勾选后在下载程序后会出现“”等错误,导致不能在线仿真(不影响程序运行)。为什么会有这个错误,我还没弄明白。

6.  我们还需要在程序中将QSPI 配置为memory-mapped mode,这样我们才可以像访问内存一样访问QSPI FLASH空间。

关于QSPI的驱动可以参考博客:https://blog.csdn.net/Ningjianwen/article/details/96477565

我们需要做的是在编写好初始化W25Q256程序后,调用一个进入内存映射模式的函数,该函数如下:

/**
* @brief Configure the QSPI in memory-mapped mode
* @param None 
* @retval QSPI memory status
*/
void W25QXX_MemoryMappedMode(void)
{
  QSPI_CommandTypeDef s_command;
  QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;

  /* Configure the command for the read instruction */
  s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES;
  s_command.Instruction = W25X_FastReadData;
  s_command.AddressMode = QSPI_ADDRESS_4_LINES;
  s_command.AddressSize = QSPI_ADDRESS_32_BITS;
  s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  s_command.DataMode = QSPI_DATA_4_LINES;
  s_command.DummyCycles = 8;
  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
  s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

  /* Configure the memory mapped mode */
  s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
  s_mem_mapped_cfg.TimeOutPeriod = 0; //1;

  if (HAL_QSPI_MemoryMapped(&hqspi, &s_command, &s_mem_mapped_cfg) != HAL_OK)
  {
    Error_Handler();
  }
}

 

  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 35
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值