d1s meils烧录导致xfel工具烧写失效
-
全志d1s烧录melis官方打出来的img镜像后,xfel工具烧录.bin文件到spinorflash不进去,读取正常。只能用刷机工具烧录。
-
-
此回复已被删除! -
晕哥, 这个具体怎么操作呢 ,就是下载了melis生成的镜像, xfel下载bin文件进spinor进不去,导致这个板子基本半废了状态。然后为什么会导致这个问题呢,很多方法都尝试了。0.0
-
@danfeng
因为官方sdk生成的img是基于android的,xfel不认识。 -
@whycan 晕哥 我大概看了一下这个xfel工具的开源源码,应该里面就是对spinorflash直接操作,擦除下载读取吧,那么为什么下载了melis会导致xfel工具下载不进去呢,应该跟里面运行什么系统无关吧。
-
@whycan 而且我刷机linux-tina,xfel还是识别不了。尝试用另外一块没刷过melis的d1s,刷机linux-tina之后是可以xfel正常写入的。很疑惑,这个问题。晕哥,你的板子应该也可以复现此问题,不知道什么问题,很是疑惑。怀疑过spinorflash写保护,通信模式是否更改了,但是通过实验证明,应该不是这方面的问题,但是xfel相当于直接操作spinorflash,跟里面跑的操作系统应该也没问题。就很是不解。
-
@danfeng
① 烧录驱动不同
② flash要先擦后写板子硬件正常,理论上不会写不进去
-
@whycan 目前烧录进两块板子都是这个问题,读spinor正常,写入(包括擦除)显示正常,实际是没写(擦除)进去的,排除硬件问题。spinor能读,img能够通过刷机工具刷进去,驱动应该没问题。实在疑惑,解决这个问题好多天了,哈哈哈。谢谢晕哥的解答了,我再研究研究吧。
-
@danfeng 在 d1s meils烧录导致xfel工具烧写失效 中说:
@whycan 目前烧录进两块板子都是这个问题,读spinor正常,写入(包括擦除)显示正常,实际是没写(擦除)进去的,排除硬件问题。spinor能读,img能够通过刷机工具刷进去,驱动应该没问题。实在疑惑,解决这个问题好多天了,哈哈哈。谢谢晕哥的解答了,我再研究研究吧。
不排除xfel工具有bug。
写入全是0xFF文件,然后读出来,是否正常?
-
@whycan 下载过melis的板子,如果下载了tina的镜像,bin文件xfel根本就烧写不进去。如果下载了网上有一些rtos的镜像,能够烧写一次bin,第二次就xfel烧录不进去,然后这种情况,第一次烧录16M字节的0xff,读取与写入是没问题的。就感觉melis给spinor设定了权限一样。如果说里面的系统软件问题,比如文件系统之类的,还可能出现这种情况,但是xfel直接操作spinor读写的,跟软件没关系。目前是原因都未知,0.0
-
@danfeng
有一个更简单一点的方法,flash引脚飞八根线到 usb烧录器(淘宝有卖,几块钱),也不用纠结这些问题了。 -
此回复已被删除! -
@whycan 晕哥,先是spinorflash飞线出来,jlink直接下载。如果没有下载melis,是没问题,后面下载了那个镜像,jlink-spi都烧录不进去了,所以可以肯定的是,spinorflash写了保护(最开始也是怀疑此问题,但是读寄存器,然后一些实验情况,让我排除了这种情况,失误了)。后续直接GDB调试,让d1s板子在SRAM里跑spinorflash保护擦除,问题成功解决。具体操作:发送0x98,unlock指令,然后清除status register3的WPS位为0,即可。具体spi实现代码,参考韦东山的spinorflash的操作例程。
-
@danfeng
现在问题来了,在哪里lock了flash? -
@whycan 因为烧录melis镜像才有这个问题,也许melis对spinorflash进行了写保护操作,防止spinor因物理等原因导致spinor出问题(百度是这么解释的)。而这个melis里面具体设置之类的,目前还没有深入。其实我还是有疑惑的,比如:1.这个melis根本没跑起来,为什么就对spinorflash设置了。2.写保护了,为什么能刷机,不应该刷机都不被允许吗。3.下载了网上有一个rtos镜像,能够成功的下载一次,假设那个rtos也许对spinorflash解锁了,能够下载,但是为什么只有一次。
-
@danfeng 有个对比方式,去确认哪里lock spi flash了。
1,先用镊子短接SPI NOR FLASH的数据脚到地,再上电启动,测试xfel烧写,擦除功能(大概率正常)
2,不短接,进入fel模式,比如在加载melis系统后再进入fel模式,这种情况,有可能会出现melis lock spi flash了。进入fel有多种方式,1,空flash,2,短路flash,3利用系统自带的efex相关指令进入。lock flash仅可能发生在运行部分代码后导致的结果。
-
-
查看xfel代码,发现在spinor_helper_init时,已经对spi nor flash芯片做了reset处理,难道reset处理也不能unlock spi nor flash吗?可以尝试将unlock指令加在spinor_helper_init里试试
/* spi select */ cbuf[clen++] = SPI_CMD_SELECT; /* chip reset */ cbuf[clen++] = SPI_CMD_FAST; cbuf[clen++] = 2; cbuf[clen++] = 0x66; cbuf[clen++] = 0x99; /* spi deselect */ cbuf[clen++] = SPI_CMD_DESELECT; /* spi select */ cbuf[clen++] = SPI_CMD_SELECT; /* wait busy */ cbuf[clen++] = SPI_CMD_SPINOR_WAIT; /* spi deselect */ cbuf[clen++] = SPI_CMD_DESELECT; /* spi select */ cbuf[clen++] = SPI_CMD_SELECT; /* write enable */ cbuf[clen++] = SPI_CMD_FAST; cbuf[clen++] = 1; cbuf[clen++] = pdat->info.opcode_write_enable; /* spi deselect */ cbuf[clen++] = SPI_CMD_DESELECT; /* spi select */ cbuf[clen++] = SPI_CMD_SELECT; /* write status */ cbuf[clen++] = SPI_CMD_FAST; cbuf[clen++] = 2; cbuf[clen++] = OPCODE_WRSR; cbuf[clen++] = 0; /* spi deselect */ cbuf[clen++] = SPI_CMD_DESELECT; /* spi select */ cbuf[clen++] = SPI_CMD_SELECT; /* wait busy */ cbuf[clen++] = SPI_CMD_SPINOR_WAIT; /* spi deselect */ cbuf[clen++] = SPI_CMD_DESELECT;
-
@tripod9 spi nor flash的写保护功能,从各种现象推测得出,保护位应该是持久化的,即使断电,重启,都无法改变状态,只要被锁定了,只有被解锁才能再次写入。这个要求也能解释你为何只能跑一次某些rtos,这个rtos肯定自作主张的锁定了spi nor flash,只要运行一次,就被搞了。我手上没有条件试验这个问题,可以在xfel加解锁代码,彻底解决此类问题。
-
打这个补丁,可以帮忙测试下。
diff --git a/spinor.c b/spinor.c index 7a30307..8cc6e95 100644 --- a/spinor.c +++ b/spinor.c @@ -287,6 +287,85 @@ static inline int spinor_info(struct xfel_ctx_t * ctx, struct spinor_pdata_t * p return 0; } +static inline uint8_t spinor_read_sr3(struct xfel_ctx_t * ctx, struct spinor_pdata_t * pdat) +{ + uint8_t tx[1]; + uint8_t rx[1]; + + tx[0] = 0x15; + rx[0] = 0x0; + fel_spi_xfer(ctx, pdat->swapbuf, pdat->swaplen, pdat->cmdlen, tx, 1, rx, 1); + return rx[0]; +} + +static inline int spinor_global_unlock(struct xfel_ctx_t * ctx, struct spinor_pdata_t * pdat) +{ + uint8_t cbuf[256]; + uint32_t clen = 0; + uint8_t sr3 = spinor_read_sr3(ctx, pdat); + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* write enable */ + cbuf[clen++] = SPI_CMD_FAST; + cbuf[clen++] = 1; + cbuf[clen++] = pdat->info.opcode_write_enable; + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* global block/sector unlock */ + cbuf[clen++] = SPI_CMD_FAST; + cbuf[clen++] = 1; + cbuf[clen++] = 0x98; + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* wait busy */ + cbuf[clen++] = SPI_CMD_SPINOR_WAIT; + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* write enable */ + cbuf[clen++] = SPI_CMD_FAST; + cbuf[clen++] = 1; + cbuf[clen++] = pdat->info.opcode_write_enable; + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* write status 3 and clear wps bit */ + cbuf[clen++] = SPI_CMD_FAST; + cbuf[clen++] = 2; + cbuf[clen++] = 0x11; + cbuf[clen++] = sr3 & ~(0x1 << 4); + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* spi select */ + cbuf[clen++] = SPI_CMD_SELECT; + /* wait busy */ + cbuf[clen++] = SPI_CMD_SPINOR_WAIT; + /* spi deselect */ + cbuf[clen++] = SPI_CMD_DESELECT; + + /* end */ + cbuf[clen++] = SPI_CMD_END; + if(clen <= pdat->cmdlen) + { + fel_chip_spi_run(ctx, cbuf, clen); + return 1; + } + return 0; +} + + static int spinor_helper_init(struct xfel_ctx_t * ctx, struct spinor_pdata_t * pdat) { uint8_t cbuf[256]; @@ -370,6 +449,7 @@ static int spinor_helper_init(struct xfel_ctx_t * ctx, struct spinor_pdata_t * p if(clen <= pdat->cmdlen) { fel_chip_spi_run(ctx, cbuf, clen); + spinor_global_unlock(ctx, pdat); return 1; } }
-
@tripod9 xfel-windows-v1.3.0.7z 试试这个xfel,看是否解决问题了
-
@tripod9 大概看了一下,这个顺序是没问题的,后面有时间测试一下,如果测试成功,再反馈给你。谢谢老哥们的帮忙。
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号