@@ -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