@@ -18,6 +18,11 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
1818#include <dfu/flash_img.h>
1919#include <inttypes.h>
2020
21+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
22+ #include <dfu/mcuboot.h>
23+ #include <flash.h>
24+ #endif
25+
2126BUILD_ASSERT_MSG ((CONFIG_IMG_BLOCK_BUF_SIZE % DT_FLASH_WRITE_BLOCK_SIZE == 0 ),
2227 "CONFIG_IMG_BLOCK_BUF_SIZE is not a multiple of "
2328 "DT_FLASH_WRITE_BLOCK_SIZE" );
@@ -52,6 +57,63 @@ static bool flash_verify(const struct flash_area *fa, off_t offset,
5257 return (len == 0 ) ? true : false;
5358}
5459
60+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
61+
62+ static int flash_sector_from_off (struct flash_area const * fap , off_t off ,
63+ struct flash_sector * sector )
64+ {
65+ struct flash_pages_info page ;
66+ struct device * flash_dev ;
67+ int rc = - ENODEV ;
68+
69+ flash_dev = flash_area_get_device (fap );
70+ if (flash_dev ) {
71+ rc = flash_get_page_info_by_offs (flash_dev , off , & page );
72+ if (rc == 0 ) {
73+ sector -> fs_off = page .start_offset ;
74+ sector -> fs_size = page .size ;
75+ }
76+ }
77+
78+ return rc ;
79+ }
80+
81+ /**
82+ * Erase the image slot progressively
83+ *
84+ * This function erases a flash page to which offset belongs if only this page
85+ * wasn't erased before.
86+ *
87+ * @param[in] ctx context of the image collection process.
88+ * @param[in] off offset from the beginning of the image flash area beginning
89+ *
90+ * @return 0 on success, negative errno code on fail.
91+ */
92+ static int flash_progressive_erase (struct flash_img_context * ctx , off_t off )
93+ {
94+ struct flash_sector sector ;
95+ int rc ;
96+
97+ rc = flash_sector_from_off (ctx -> flash_area , off , & sector );
98+ if (rc ) {
99+ LOG_ERR ("Unable to determine flash sector size" );
100+ } else {
101+ if (ctx -> off_last != sector .fs_off ) {
102+ ctx -> off_last = sector .fs_off ;
103+ LOG_INF ("Erasing sector at offset 0x%x" , sector .fs_off );
104+ rc = flash_area_erase (ctx -> flash_area , sector .fs_off ,
105+ sector .fs_size );
106+ if (rc ) {
107+ LOG_ERR ("Error %d while erasing sector" , rc );
108+ }
109+ }
110+ }
111+
112+ return rc ;
113+ }
114+
115+ #endif /* CONFIG_IMG_ERASE_PROGRESSIVELY */
116+
55117static int flash_sync (struct flash_img_context * ctx )
56118{
57119 int rc = 0 ;
@@ -61,6 +123,11 @@ static int flash_sync(struct flash_img_context *ctx)
61123 CONFIG_IMG_BLOCK_BUF_SIZE - ctx -> buf_bytes );
62124 }
63125
126+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
127+ flash_progressive_erase (ctx , ctx -> bytes_written +
128+ CONFIG_IMG_BLOCK_BUF_SIZE );
129+ #endif
130+
64131 rc = flash_area_write (ctx -> flash_area , ctx -> bytes_written , ctx -> buf ,
65132 CONFIG_IMG_BLOCK_BUF_SIZE );
66133 if (rc ) {
@@ -121,6 +188,11 @@ int flash_img_buffered_write(struct flash_img_context *ctx, u8_t *data,
121188 return rc ;
122189 }
123190 }
191+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
192+ /* erase the image trailer area if it was not erased */
193+ flash_progressive_erase (ctx ,
194+ BOOT_TRAILER_IMG_STATUS_OFFS (ctx -> flash_area ));
195+ #endif
124196
125197 flash_area_close (ctx -> flash_area );
126198 ctx -> flash_area = NULL ;
@@ -137,6 +209,9 @@ int flash_img_init(struct flash_img_context *ctx)
137209{
138210 ctx -> bytes_written = 0 ;
139211 ctx -> buf_bytes = 0U ;
212+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
213+ ctx -> off_last = -1 ;
214+ #endif
140215 return flash_area_open (DT_FLASH_AREA_IMAGE_1_ID ,
141216 (const struct flash_area * * )& (ctx -> flash_area ));
142217}
0 commit comments