本帖最后由 混森蓝兽 于 2021-12-7 12:16 编辑
在解码和显示jpeg图片时,需要用到两个很大的数组:- uint16_t s_FBs[2][272][480];
- uint8_t g_JPEGReadBuf[480*272*2];
复制代码
芯片自带的SRAM容量不够大,只能使用片外的SDRAM。SDRAM的初始化代码在官方例程里面已经有了,所以这个不是啥大问题。问题在分散加载这里,由于以前没怎么接触过,所以这次被折腾了好几天,才捋顺这个问题。
分散加载的工作主要由有部分: - 一是在.icf文件中增加SDRAM的地址空间,添加自定义的section
- 二是在C代码中定义所需的数组然后指定到自定义section中
icf文件部分内容如下 定义SDRAM的地址段 0xA0000000 - 0xA0100000(板载的是16MB的,所以设置到0xA1000000也没问题)。自定义section名为“JPEG_BUF”,位于SDRAM地址段内。- define symbol m_interrupts_start = 0x00000000;
- define symbol m_interrupts_end = 0x000003FF;
- define symbol m_text_start = 0x00000400;
- define symbol m_text_end = 0x0007FFFF;
- define symbol m_data_start = 0x20000000;
- define symbol m_data_end = 0x20027FFF;
- define symbol m_usb_sram_start = 0x40100000;
- define symbol m_usb_sram_end = 0x40101FFF;
- define symbol m_sdram_start = 0xA0000000;
- define symbol m_sdram_end = 0xA0100000;
- define memory mem with size = 4G;
- define region SDRAM_region = mem:[from m_sdram_start to m_sdram_end];
- do not initialize { section JPEG_BUF };
- place in SDRAM_region { section JPEG_BUF };
复制代码
C代码部分如下: 两个大数组8字节对其,绑定在SDRAM的"JPEG_BUF"段
- #pragma data_alignment = 8
- #pragma location="JPEG_BUF"
- uint16_t uint16_t s_FBs[2][272][480];
- #pragma data_alignment = 8
- #pragma location="JPEG_BUF"
- uint8_t g_JPEGReadBuf[480*272*2];
复制代码
以上代码是能正常运行的。 其中这一行很关键,折腾了我好久,没有这一行,上电直接死机。- do not initialize { section JPEG_BUF };
复制代码
一切都要从启动代码说起:- Reset_Handler
- LDR r0, =SystemInit
- BLX r0
- LDR r0, =__iar_program_start
- BX r0
复制代码
CPU执行完SystemInit函数之后,会跳转到__iar_program_start,这是IAR编译器提供的初始化代码的入口。在这里会完成所有具有初始值的全局/静态变量的赋值,以及零初始化全局/静态变量的清零操作,将保存在ROM区由链接器生成的变量初始值复制到变量的地址。
问题就在于,SDRAM是在main中才进行初始化的,所以在__iar_program_start里面,CPU是无法访问SDRAM的,这就是CPU hardfault的原因。
所以我们必须将JPEG_BUF 段设置为不初始化的段,这样__iar_program_start就不会对SDRAM进行操作了。
本工程基于IAR8.2, 把jpeg.jpeg文件拷贝到SD卡即可:
|