上节,讲述了如何移植SPI FLASH驱动,从中可以看出,移植SPI FLASH是相对比较容易的。移植容易并不等于没有任何问题,相反,还遇到了棘手问题,本节讲述如何解决这个棘手的问题。

说到技术问题,说点题外话。在我创建的eCos技术群(群号:144940146,欢迎加入)上,有些人一遇到问题就马上寻求帮助,并且很强烈地希望你给他分析给他解决。我想说的是,搞技术,肯定会遇到这样那样的问题,但遇到问题时,自己先要思考和分析,并尝试进行问题定位,然后寻求帮助。别人帮你分析并提供相应问题分析方法和建议时,自己也要积极思考并反馈实验现象,这样才能有利于问题的解决。所以说,寻求帮助实际上也是一门很大的学问。

只要掌握了方法,任何问题不是不可以解决,方法无非就是:根据问题现象进行分析,然后定位,最后解决问题。

回归正题,希望大家阅读的时候,不是看解决了什么问题,而是看怎么分析问题、怎么解决问题的。

问题现象

当在图形配置工具中,设置CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE配置项(即SPI驱动Bounce buffer size配置项)为256时,不能正常地把elf映像文件转换为bin格式映像文件,转换生成的bin格式映像文件大小只有4KB,但可正常转换输出srec格式映像文件;如果设置为0,则可以正常转换输出bin格式映像文件。

image

问题分析

根据问题现象,这应该是由CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE配置项引起的。打开STM32 SPI驱动源文件spi_stm32.c,直接用这个配置项进行搜索,看是否有相关的代码与之关联。找到代码如下:

#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0) 
static cyg_uint8 bus1_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE] 
  __attribute__((aligned (2), section (".sram"))) = { 0 }; 
static cyg_uint8 bus1_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE] 
  __attribute__((aligned (2), section (".sram"))) = { 0 }; 
#endif

很显然,应该就是由于上述代码引起的。该代码段的作用是把bus1_tx_bbuf和buf1_rx_bbuf变量定义在.sram段。那这段代码为什么会影响bin格式映像文件输出呢?

先不管为什么要把bus1_tx_bbuf和buf1_rx_bbuf变量定义在.sram段,集中注意力分析:为什么把变量定义在.sram段则不能转换输出bin格式映像文件。这是分析问题的焦点。

我们知道,从elf转换为bin,命令是:

objcopy -O binary image.elf image.bin

知道了怎么从elf转换为bin,自然而然就会问:是什么导致了objcopy不能正常地把elf转换输出bin呢?这时,我们就不得不去了解下objcopy是怎么把elf转换输出bin的。

objcopy命令介绍

下面是objcopy的描述(man objcopy):

The GNU objcopy utility copies the contents of an object file to another.  objcopy uses the GNU BFD Library to read and write the object files.  It can write the destination object file in a format different from that of the source object file.  The exact behavior of objcopy is controlled by command-line options.  Note that objcopy should be able to copy a fully linked file between any two formats. However, copying a relocatable object file between any two formats may not work as expected.

objcopy creates temporary files to do its translations and deletes them afterward.  objcopy uses BFD to do all its translation work; it has access to all the formats described in BFD and thus is able to recognize most formats without being told explicitly.

objcopy can be used to generate S-records by using an output target of srec (e.g., use -O srec).

objcopy can be used to generate a raw binary file by using an output target of binary (e.g., use -O binary).  When objcopy generates a raw binary file, it will essentially produce a memory dump of the contents of the input object file.  All symbols and relocation information will be discarded.  The memory dump will start at the load address of the lowest section copied into the output file.

When generating an S-record or a raw binary file, it may be helpful to use -S to remove sections containing debugging information.  In some cases -R will be useful to remove sections which contain information that is not needed by the binary file.

Note—objcopy is not able to change the endianness of its input files.  If the input format has an endianness (some formats do not), objcopy can only copy the inputs into file formats that have the same endianness or which have no endianness (e.g., srec).  (However, see the –reverse-bytes option.)

也就是说,用objcopy生成binary的时,是从输入文件中地址最小的section开始dump数据到目标文件

另外,在搜索objcopy原理的资料时,还找到了一篇文章,http://www.eefocus.com/article/09-04/71632s.html,其中有说道,如果elf的section地址不连续,在生成bin时,就会出现空洞,section地址间隙越大,空洞也越大。这时就需要特别处理。

先看看我的elf文件section情况,如下图所示:

image

从图中可看到,.sram与.rom_vectors之间,有一个很大的地址间隙。也就是说,转换输出bin时,bin文件会有一个很大的空洞。这就可以解释,在移植stm32 ADC驱动时,出现了生成的bin文件达到了1.2GB大小。

问题解决方法

总结上面的分析,如果设置CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE配置项为256,就会把bus1_tx_bbuf和buf1_rx_bbuf变量定义在.sram段,而.sram与.rom_vectors之间,有一个很大的地址间隙,使得输出的bin文件有一个很大的空洞,导致不能正常转换输出bin文件。

怎么解决呢?如果了解一点链接知识,就会发现,.sram段只是链接的时候才需要用到。链接时用于确定把bus1_tx_bbuf和buf1_rx_bbuf变量放在.sram段哪个地址上。另外,bin文件也不能有.sram段,其开头必须是.rom_vectors段,否则把bin文件load到指定内存地址时,不能找到入口点,导致程序不能运行。

因此,把elf转换生成bin时需要去除.sram段,在执行elf转换bin命令时要加上参数选项:-R .sram

flash测试程序

m25pxx flash驱动带有一个测试程序m25pxx_test.c,我们可以直接使用它来测试spi flash驱动。这个测试程序是往flash的每个sector写入0x5555AAAA和0xAAAA55数据,并检测读写数据是否一致。因此,该测试程序可用来测试spi flash驱动的可靠性和稳定性。

我的板子的测试结果如下图所示:

image

从上图可看到,spi flash某些sector存在读写数据不一致问题,该问题留待后续跟踪。

» 文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明: 原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
分享到:

  4 Responses to “stm32移植ecos #27,串行SPI flash驱动移植(下)”

  1. 这种一个文件有多个段,段与段之间不连续的情况我经常遇到,最多的情况是MCU片内Flash + 外扩的NorFlash/NandFlash。我用的时候,多是用的.elf或者hex格式,而不会用bin。bin文件在涉及这种情况肯定会有类似问题,不过有的工具会好点。像ADS软件,它在转换成BIN的时候,会生成多个BIN文件。objcopy做的还是不够完善。

    为什么要用BIN文件,中间的多余数据一点也没用。拿来烧写也不合适啊?

    • 呵呵,可不能这么个情况就说objcopy做的还不够完善!
      elf是用来调试的映像文件,bin格式有个好处是它相对比较小,当用串口load到内存运行时,比较节省时间!出于这点,我现在比较钟情于bin文件!

Leave a Reply to lishutong Cancel reply

(必须)

(我会替您保密的)(必须)

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

   
© 2012 velep.com | reille blog | 管理| 粤ICP备15065318号-2| 谷歌地图| 百度地图| Suffusion theme|Sayontan Sinha

无觅相关文章插件,快速提升流量