@@ -43,44 +43,75 @@ BUILD_ASSERT((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0),
4343 "FLASH_WRITE_BLOCK_SIZE" );
4444#endif
4545
46+ static int scramble_mcuboot_trailer (struct flash_img_context * ctx )
47+ {
48+ int rc = 0 ;
49+
50+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
51+ if (stream_flash_bytes_written (& ctx -> stream ) == 0 ) {
52+ off_t toff = boot_get_trailer_status_offset (ctx -> flash_area -> fa_size );
53+ off_t offset ;
54+ size_t size ;
55+ const struct flash_parameters * fparams =
56+ flash_get_parameters (flash_area_get_device (ctx -> flash_area ));
57+ #ifdef CONFIG_STREAM_FLASH_ERASE
58+ /* for erasable devices prgressive-erase works only along with
59+ * CONFIG_STREAM_FLASH_ERASE option*/
60+ if (flash_params_get_erase_cap (fparams ) & FLASH_ERASE_C_EXPLICIT ) {
61+ /* On devices with explicit erase we are aligning to page
62+ * layout.
63+ */
64+ struct flash_pages_info info ;
65+
66+ rc = flash_get_page_info_by_offs (flash_area_get_device (ctx -> flash_area ),
67+ if (rc != 0 ) {
68+ return rc ;
69+ }
70+ offset = info .start_offset ;
71+ size = info .size ;
72+
73+ } else
74+ #endif
75+ {
76+
77+ /* On devices with no erase, we are aligning to write block
78+ * size.
79+ */
80+ offset = (toff + fparams -> write_block_size - 1 ) &
81+ ~(fparams -> write_block_size - 1 );
82+ /* No alignment correction neede here, offset is corrected already */
83+ size = ctx -> flash_area -> fa_size - offset ;
84+ }
85+
86+ rc = flash_area_flatten (ctx -> flash_area , offset , size );
87+ }
88+ #endif
89+
90+ return rc ;
91+ }
92+
93+
4694int flash_img_buffered_write (struct flash_img_context * ctx , const uint8_t * data ,
4795 size_t len , bool flush )
4896{
4997 int rc ;
5098
51- rc = stream_flash_buffered_write (& ctx -> stream , data , len , flush );
52- if (!flush ) {
99+ /* If there is need to erase trailer, that should happen before any
100+ * write is done to partition.
101+ */
102+ rc = scramble_mcuboot_trailer (ctx );
103+ if (rc != 0 ) {
53104 return rc ;
54105 }
55106
56- #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
57- ssize_t status_offset = boot_get_trailer_status_offset (
58- ctx -> flash_area -> fa_size );
59107
60- #ifdef CONFIG_STREAM_FLASH_ERASE
61- const struct flash_parameters * fparams =
62- flash_get_parameters (flash_area_get_device (ctx -> flash_area ));
63-
64- if ((flash_params_get_erase_cap (fparams ) & FLASH_ERASE_C_EXPLICIT )) {
65- /* use pistine-page-erase procedure for a device which needs it */
66- rc = stream_flash_erase_page (& ctx -> stream ,
67- ctx -> flash_area -> fa_off +
68- status_offset );
69- } else
70- #endif
71- {
72- if (status_offset > stream_flash_bytes_written (& ctx -> stream )) {
73- rc = flash_area_flatten (ctx -> flash_area , status_offset ,
74- ctx -> flash_area -> fa_off - status_offset );
75- } else {
76- rc = 0 ;
77- }
78- }
79-
80- if (rc ) {
108+ /* if CONFIG_IMG_ERASE_PROGRESSIVELY is enabled the enabled CONFIG_STREAM_FLASH_ERASE
109+ * ensures that stream_flash erases flash progresively.
110+ */
111+ rc = stream_flash_buffered_write (& ctx -> stream , data , len , flush );
112+ if (!flush ) {
81113 return rc ;
82114 }
83- #endif
84115
85116 flash_area_close (ctx -> flash_area );
86117 ctx -> flash_area = NULL ;
0 commit comments