Hi, 

 I think my previous mail may have been missed by the
experts.
Please help me find the right experts, as I do not have the
experience to build and test a solution. 
Maybe Nemui Trinomius can take
a look at this. 

Details on failure can be found below:

 I propose the
following solution. 

 - Line 1126 current code:
 while (bytes_remaining
> 0) {
 uint32_t thisrun_bytes;
 if (bytes_remaining >=
lpc2000_info->cmd51_max_buffer)
 thisrun_bytes =
lpc2000_info->cmd51_max_buffer;
 else if (bytes_remaining >= 1024)

thisrun_bytes = 1024;
 else if ((bytes_remaining >= 512) ||
(!lpc2000_info->cmd51_can_256b))
 thisrun_bytes = 512;
 else if
((bytes_remaining >= 256) || (!lpc2000_info->cmd51_can_64b))

thisrun_bytes = 256;
 else
 thisrun_bytes = 64;

 - Solution 1: Improve
second else:
 while (bytes_remaining > 0) {
 uint32_t thisrun_bytes;
 if
(bytes_remaining >= lpc2000_info->cmd51_max_buffer)
 thisrun_bytes =
lpc2000_info->cmd51_max_buffer;
 else if (bytes_remaining >= 1024)

thisrun_bytes = 1024;
 else if ((bytes_remaining >= 512) ||
(!(lpc2000_info->cmd51_can_256b || lpc2000_info->cmd51_can_64b)))

thisrun_bytes = 512;
 else if ((bytes_remaining >= 256) ||
(!lpc2000_info->cmd51_can_64b))
 thisrun_bytes = 256;
 else

thisrun_bytes = 64;

 - Solution 2: Add check on maximum of
thisrun_bytes:
 while (bytes_remaining > 0) {
 uint32_t thisrun_bytes;

if (bytes_remaining >= lpc2000_info->cmd51_max_buffer)
 thisrun_bytes =
lpc2000_info->cmd51_max_buffer;
 else if (bytes_remaining >= 1024)

thisrun_bytes = 1024;
 else if ((bytes_remaining >= 512) ||
(!(lpc2000_info->cmd51_can_256b))
 thisrun_bytes = 512;
 else if
((bytes_remaining >= 256) || (!lpc2000_info->cmd51_can_64b))

thisrun_bytes = 256;
 else
 thisrun_bytes = 64;
 if (thisrun_bytes >
lpc2000_info->cmd51_max_buffer)
 thisrun_bytes =
lpc2000_info->cmd51_max_buffer; 

 - Solution 3: Remove all the
cmd51_can_xxxx fields. Note that cmd51_can_8192b is never used!:
 while
(bytes_remaining > 0) {
 uint32_t thisrun_bytes;
 if (bytes_remaining >=
lpc2000_info->cmd51_max_buffer)
 thisrun_bytes =
lpc2000_info->cmd51_max_buffer;
 else 
 thisrun_bytes =
lpc2000_info->cmd51_dst_boundary;

 Reviewing the code I would say
solution 3 is the best, and IMO correct.
lpc2000_info->cmd51_dst_boundary seems to be set properly under all
conditions.

 The error occurs when
 lpc2000_info->cmd51_max_buffer ==
256 && bank->num_sectors > 1 

Failure mode: LPC81x tries to get
uploaded with 512 bytes (possible in itself) but crosses a sector
boundary which is not prepared for flashing. 

Impacted are (only)
LCP810, LPC811 and LPC812.
 Probability of occurence is around 25%.

 I
hope this can be solved before 0.9.0 gets released.

 SevenW 

 SevenW
wrote on 10-3-2015 14:14:  

I get an error code 9 when flashing a
LPC810. Looking into the code it seems to be related to the size of the
image being flashed. Code is in src/flash/nor/lpc2000.c. 

Flashing
happens in chunks of 256 bytes: 

lpc2000_info->cmd51_max_buffer [1] =
256; /* smallest MCU in the series, LPC810, has 1 kB of SRAM */

Until
the last chunk. It turns to a size of 512 bytes. This is normally OK,
but not if this last chunk crosses a sector boundary (sector size is
1KB). Then the LPC returns "SECTOR NOT PREPARED".The calculation of the
sectors to be prepared is OK. But now suddenly 256 bytes to many are
flashed. Logging looks like this:

Line 59: Debug: 1865 19408
lpc2000.c:1156 lpc2000_write(): writing 0x100 bytes to address
0x400
Line 56: Debug: 1862 19401 lpc2000.c:808 lpc2000_iap_call(): IAP
command = 50 (0x00000000, 0x00000001, 0x00002ee0, 0x00002ee0,
0x00000000) completed with result = 00000000 
 Line 170: Debug: 1975
19517 lpc2000.c:808 lpc2000_iap_call(): IAP command = 51 (0x00000400,
0x10000104, 0x00000100, 0x00002ee0, 0x00000000) completed with result =
00000000 
Line 275: Debug: 2080 19623 lpc2000.c:808 lpc2000_iap_call():
IAP command = 50 (0x00000000, 0x00000001, 0x00002ee0, 0x00002ee0,
0x00000000) completed with result = 00000000 
Line 278: Debug: 2083
19628 lpc2000.c:1156 lpc2000_write(): writing 0x100 bytes to address
0x500 
Line 389: Debug: 2193 19732 lpc2000.c:808 lpc2000_iap_call(): IAP
command = 51 (0x00000500, 0x10000104, 0x00000100, 0x00002ee0,
0x00000000) completed with result = 00000000 
Line 494: Debug: 2298
19838 lpc2000.c:808 lpc2000_iap_call(): IAP command = 50 (0x00000000,
0x00000001, 0x00002ee0, 0x00002ee0, 0x00000000) completed with result =
00000000 
Line 497: Debug: 2301 19843 lpc2000.c:1156 lpc2000_write():
writing 0x100 bytes to address 0x600 
Line 608: Debug: 2411 19953
lpc2000.c:808 lpc2000_iap_call(): IAP command = 51 (0x00000600,
0x10000104, 0x00000100, 0x00002ee0, 0x00000000) completed with result =
00000000 
Line 713: Debug: 2516 20058 lpc2000.c:808 lpc2000_iap_call():
IAP command = 50 (0x00000000, 0x00000001, 0x00002ee0, 0x00002ee0,
0x00000000) completed with result = 00000000 
Line 716: Debug: 2519
20065 lpc2000.c:1156 lpc2000_write(): writing 0x200 bytes to address
0x700 
Line 821: Debug: 2624 20175 lpc2000.c:808 lpc2000_iap_call(): IAP
command = 51 (0x00000700, 0x10000104, 0x00000200, 0x00002ee0,
0x00000000) completed with result = 00000009 
Line 822: Warn : 2625
20176 lpc2000.c:1174 lpc2000_write(): lpc2000 returned 9 

The problem
is in this code form lpc2000.c:

01109 while (bytes_remaining > 0)
{
01110 uint32_t thisrun_bytes;
01111 if (bytes_remaining >=
lpc2000_info->cmd51_max_buffer [2])
01112 thisrun_bytes =
lpc2000_info->cmd51_max_buffer [3];
01113 else if (bytes_remaining >=
1024)
01114 thisrun_bytes = 1024;
01115 else if ((bytes_remaining >=
512) || (!lpc2000_info->cmd51_can_256b [4]))
01116 thisrun_bytes =
512;
01117 else if ((bytes_remaining >= 256) ||
(!lpc2000_info->cmd51_can_64b [5]))
01118 thisrun_bytes = 256;
01119
else
01120 thisrun_bytes = 64;
01121

Where
(!lpc2000_info->cmd51_can_256b [6]) evaluates to true, assiging 512 to
thisrun_bytes, while cmd51_max_buffer=256)

In my case first_sector=0,
and last_sector=1.
  

Links:
------
[1]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#a23af55d8061198f18831a2f488ad2b53
[2]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#a23af55d8061198f18831a2f488ad2b53
[3]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#a23af55d8061198f18831a2f488ad2b53
[4]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#ac338930dfe01115e67ac25c3248cc5f6
[5]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#a0ec3dd44f6d76fdcf5f543663f98eb43
[6]
http://openocd.sourceforge.net/doc/doxygen/html/structlpc2000__flash__bank.html#ac338930dfe01115e67ac25c3248cc5f6
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to