AML8613 MBOX系统下更换SPI Flash后无法烧录调试的问题

AMLogic的8613 MBOX是一个非常不错的视频播放系统,稳定、成熟度高,成本也较低。其开发的AVOS应该是基于uC/OS内核做的,运行效率很高。其开发的模式也很有意思,没有文档,网上也找不着资料,只能手把手地教,甚至连它的开发环境也只能到其公司去安装。开发过程中遇到问题是常有的事,有时只能自己摸索。前几天我自己就遇到个SPI问题,在这里记录一下供参考。
AML8613 MBOX系统下更换SPI Flash后无法烧录调试的问题_第1张图片
起因是换了一个开发板。这块新板的SPI-Flash的型号跟原板不同,原板的是25x32VSIG,新板是N25S32-75HE,测试的结果是可以调试,但烧录时瞬间假烧完成,重新上电没反应。问AML那边的支持,答曰可能不支持该型号,底层驱动的代码只有原厂才有无法获取修改,建议换SPI。
 
于是买了跟原板一样的25x32 SPI换上去,但不知是不是硬件不兼容,这次索性连调试都无法进行了,直接下载完就校验出错。把原板的SPI拖下来,焊到新板上,问题依旧。
 
换回新板N25S32的SPI,调试跟踪,发现是打开SPI设备时出错了,尝试调用SPIGetDevice()获取设备信息,结果是返回空。意思是没有找到支持的SPI设备。因为系统支持的SPI已经在bsp.c里列明了,只支持以下几种:
SPISupport(&spi_w25x16);
SPISupport(&spi_w25q16);
SPISupport(&spi_mx25l3205d);
SPISupport(&spi_w25x32);
SPISupport(&spi_w25x16V);
SPISupport(&spi_MX25L800);
SPISupport(&spi_en25b32b);
SPISupport(&spi_MX25L160);
SPISupport(&spi_en25f32b);
  
另外spi_flash.h里还有几种SPI的声明,但经测试加入系统后仍然无法识别N25S32。
为了探明SPI的识别原理,找出各型号SPI的区别,我写了一个函数,将系统能支持的SPI的所有信息全打印出来。spi_flash.h里有SPI结构的定义:
typedef struct{
  unsigned   deviceId;
  char*     chipname;
  unsigned   chip_size; // chip size in byte
  unsigned  block_size;
  unsigned  sector_size;
  SpiFlashOpResult (*erase_chip)  (SpiFlashDevice *device);
  SpiFlashOpResult (*erase_block)(SpiFlashDevice *device, unsigned block_num);  
  SpiFlashOpResult (*erase_sector)(SpiFlashDevice *device, unsigned sector_num);
  SpiFlashOpResult (*write_address)(SpiFlashDevice *device, unsigned spiaddr, unsigned *src_addr,  int len);
  SpiFlashOpResult (*read_address)(SpiFlashDevice *device, unsigned spiaddr, unsigned *dest_addr,  int len);
  int (* get_sector_num)(SpiFlashDevice *device,unsigned spiaddr);
  void     *fs_offset;
  unsigned  fs_kb;
}SpiFlashChip;
 
 
其中很明显,erase_chip、erase_block、write_address等函数是一样的,在spi_flash.h里有相应的实现。我们只需要打印其它信息:
//added by huz
int spi_info_i=0;
void print_spi_info(const SpiFlashChip * spi)
{
  if(spi==NULL)
  {
    printf("spi is null/n");
    return;
  }
  spi_info_i++;
  printf("spi_%d info :/n",spi_info_i);
 
  printf("deviceId: %d (HEX:%X)/n",spi->deviceId,spi->deviceId);
  printf("chipname: %s/n",spi->chipname);
  printf("chip_size: %d/n",spi->chip_size);
  printf("block_size: %d/n",spi->block_size);
  printf("sector_size: %d/n",spi->sector_size);
  printf("fs_offset: %X/n",((int)spi->fs_offset));
  printf("fs_kb: %d/n/n",spi->fs_kb);
}
void print_spi_infos()
{
  printf("by huz - spi infos:/n/n");
  print_spi_info(&spi_w25x16);
  print_spi_info(&spi_w25q16);
  print_spi_info(&spi_mx25l3205d);
  print_spi_info(&spi_w25x32);
  print_spi_info(&spi_w25x16V);
  ...
  print_spi_info(&spi_s25fl032p);
}
 
运行结果,在JTAG调试时输出如下:
by huz - spi infos:
spi_1 info :
deviceId: 1388783 (HEX:1530EF)
chipname: WINBOND W25X16
chip_size: 2097152
block_size: 65536
sector_size: 4096
fs_offset: 1FF000
fs_kb: 4096
 
spi_2 info :
deviceId: 1392879 (HEX:1540EF)
chipname: WINBOND W25Q16
chip_size: 2097152
block_size: 65536
sector_size: 4096
fs_offset: 1FF000
fs_kb: 4096
 
spi_3 info :
deviceId: 1450178 (HEX:1620C2)
chipname: MX25L3205D
chip_size: 4194304
block_size: 65536
sector_size: 4096
fs_offset: 3FF000
fs_kb: 4096
 
spi_4 info :
deviceId: 1454319 (HEX:1630EF)
chipname: WINBOND W25X32
chip_size: 4194304
block_size: 65536
sector_size: 4096
fs_offset: 3FF000
fs_kb: 4096
 
spi_5 info :
deviceId: 1388783 (HEX:1530EF)
chipname: WINBOND W25X16V
chip_size: 2097152
block_size: 65536
sector_size: 4096
fs_offset: 1FF000
fs_kb: 4096
 
...
 
spi_17 info :
deviceId: 1376769 (HEX:150201)
chipname: SPANSION S25FL032P
chip_size: 4194304
block_size: 65536
sector_size: 4096
fs_offset: 3F0000
fs_kb: 65536
 
 
很显然,deviceId和chipname是决定SPI型号用的,而deviceId应该是关键,每个SPI的deviceId都不一样,系统初始化时应该是会把支持的SPI的deviceId轮询一次,如果有响应的话则说明对应型号的SPI接到系统上了。
于是在网上查了下N25S32-75HE的资料,其中有设备ID的说明:
AML8613 MBOX系统下更换SPI Flash后无法烧录调试的问题_第2张图片
跟上述打印的信息一比较,显然我们需要的设备ID是0x1630D5。于是手工增加了一个SPI的定义:
const SpiFlashChip spi_N25S32XX={
    0x1630d5,
    "QTHUZ N25S32", 
    (32/8)*1024*1024,
    65536,
    4*1024, 
    SPIEraseChip,
    SPIEraseBlock,
    SPIEraseSector, 
    SPIWrite, 
    SPIRead,
    SPIGetSectorNum,
    (void *) 0x3ff000, 
     4*1024, };
 
SPISupport(&spi_N25S32);
接着运行,发现用SPIGetDevice()确实能找到SPI了。于是修改了代码,满怀希望地开始烧录,但最终仍然是写入失败,断点停在一个写参数的位置。
分析了一下原因,这时除了chipname,其它参数都是相当正确的。由于没有SPI的驱动代码,也无法判断原因,只能猜测是AML做了什么手脚。
由于N25S32的芯片号称是跟W25X32兼容的,于是我又想到,如果直接用W25X32的定义,强制在内存中修改其设备ID,也许可以骗过AML。说干就干,我在SPI初始化前加入以下代码:
int devid=0x1630d5;
memcpy((void*)&(spi_w25x32.deviceId),(void*)&devid,4);
再次运行,用SPIGetDevice()获取并打印SPI信息如下:
spi_1 info :
deviceId: 1454293 (HEX:1630D5)
chipname: WINBOND W25X32
chip_size: 4194304
block_size: 65536
sector_size: 4096
fs_offset: 3FF000
fs_kb: 4096
呵呵,W25X32的设备ID被修改成0x1630d5。接着修改代码执行烧录,这次终于烧录成功:
>make prom
Using Sun Microsystems Inc. Java version 1.6.0_06 on Windows.
Welcome to the GUI version of the MetaWare Debugger, v8.2.5 (1362).
License SeeCode expires
USB JTAG Firmware (Ver1.04) / DLL (Ver1.05)
Parallel port driver (gportio.sys) version 4 (fast) detected.
ELF segment #0 addr 0x3800000 size 0x000130     .
ELF segment #1 addr 0x3800500 size 0x370b14     ................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
.........
ELF segment #1 addr 0x3b71014 zero 0x024f30     (program zeroes BSS)
[1] Progress display created was 10920e28
License SC_AC expires
Added by huz - Burn start...
spi_1 info :
deviceId: 1454293 (HEX:1630D5)
chipname: WINBOND W25X32
chip_size: 4194304
block_size: 65536
sector_size: 4096
fs_offset: 3FF000
fs_kb: 4096
by huz - open source: /dev/ramdisk0
by huz - loop segs
by huz - open target: /dev/spi
by huz - upgrade start...
upgrading in progress 99%  
by huz - clean memory
by huz - exiting...
by huz - Burn OK, can power down now.
Shutting down all processes...Done
重新上电,终于在视频输出上看到亲切的开机界面了。
 

你可能感兴趣的:(struct,测试,Flash,hex,n2,parallel)