• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015-2017, Armink, <armink.ztl@gmail.com>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * 'Software'), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Function: IAP(In-Application Programming) operating interface.
24  * Created on: 2015-01-05
25  */
26 
27 #include <easyflash.h>
28 
29 #ifdef EF_USING_IAP
30 
31 /* IAP section backup application section start address in flash */
32 static uint32_t bak_app_start_addr = 0;
33 
34 /**
35  * Flash IAP function initialize.
36  *
37  * @return result
38  */
ef_iap_init(void)39 EfErrCode ef_iap_init(void)
40 {
41 	EfErrCode result = EF_NO_ERR;
42 
43 	bak_app_start_addr = EF_START_ADDR ;
44 
45 #if defined(EF_USING_ENV)
46 	bak_app_start_addr += ENV_AREA_SIZE;
47 #endif
48 
49 #if defined(EF_USING_LOG)
50 	bak_app_start_addr += LOG_AREA_SIZE;
51 #endif
52 
53 	return result;
54 }
55 
56 /**
57  * Erase backup area application data.
58  *
59  * @param app_size application size
60  *
61  * @return result
62  */
ef_erase_bak_app(size_t app_size)63 EfErrCode ef_erase_bak_app(size_t app_size)
64 {
65 	EfErrCode result = EF_NO_ERR;
66 
67 	result = ef_port_erase(ef_get_bak_app_start_addr(), app_size);
68 	switch (result) {
69 	case EF_NO_ERR: {
70 		EF_INFO("Erased backup area application OK.\n");
71 		break;
72 	}
73 	case EF_ERASE_ERR: {
74 		EF_INFO("Warning: Erase backup area application fault!\n");
75 		/* will return when erase fault */
76 		return result;
77 	}
78 	}
79 
80 	return result;
81 }
82 
83 /**
84  * Erase user old application by using specified erase function.
85  *
86  * @param user_app_addr application entry address
87  * @param app_size application size
88  * @param app_erase user specified application erase function
89  *
90  * @return result
91  */
ef_erase_spec_user_app(uint32_t user_app_addr,size_t app_size,EfErrCode (* app_erase)(uint32_t addr,size_t size))92 EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size,
93 								 EfErrCode(*app_erase)(uint32_t addr, size_t size))
94 {
95 	EfErrCode result = EF_NO_ERR;
96 
97 	result = app_erase(user_app_addr, app_size);
98 	switch (result) {
99 	case EF_NO_ERR: {
100 		EF_INFO("Erased user application OK.\n");
101 		break;
102 	}
103 	case EF_ERASE_ERR: {
104 		EF_INFO("Warning: Erase user application fault!\n");
105 		/* will return when erase fault */
106 		return result;
107 	}
108 	}
109 
110 	return result;
111 }
112 
113 /**
114  * Erase user old application by using default `ef_port_erase` function.
115  *
116  * @param user_app_addr application entry address
117  * @param app_size application size
118  *
119  * @return result
120  */
ef_erase_user_app(uint32_t user_app_addr,size_t app_size)121 EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t app_size)
122 {
123 	return ef_erase_spec_user_app(user_app_addr, app_size, ef_port_erase);
124 }
125 
126 /**
127  * Erase old bootloader
128  *
129  * @param bl_addr bootloader entry address
130  * @param bl_size bootloader size
131  *
132  * @return result
133  */
ef_erase_bl(uint32_t bl_addr,size_t bl_size)134 EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size)
135 {
136 	EfErrCode result = EF_NO_ERR;
137 
138 	result = ef_port_erase(bl_addr, bl_size);
139 	switch (result) {
140 	case EF_NO_ERR: {
141 		EF_INFO("Erased bootloader OK.\n");
142 		break;
143 	}
144 	case EF_ERASE_ERR: {
145 		EF_INFO("Warning: Erase bootloader fault!\n");
146 		/* will return when erase fault */
147 		return result;
148 	}
149 	}
150 
151 	return result;
152 }
153 
154 /**
155  * Write data of application to backup area.
156  *
157  * @param data a part of application
158  * @param size data size
159  * @param cur_size current write application size
160  * @param total_size application total size
161  *
162  * @return result
163  */
ef_write_data_to_bak(uint8_t * data,size_t size,size_t * cur_size,size_t total_size)164 EfErrCode ef_write_data_to_bak(uint8_t *data, size_t size, size_t *cur_size,
165 							   size_t total_size)
166 {
167 	EfErrCode result = EF_NO_ERR;
168 
169 	/* make sure don't write excess data */
170 	if (*cur_size + size > total_size)
171 		size = total_size - *cur_size;
172 
173 	result = ef_port_write(ef_get_bak_app_start_addr() + *cur_size, (uint32_t *) data, size);
174 	switch (result) {
175 	case EF_NO_ERR: {
176 		*cur_size += size;
177 		EF_DEBUG("Write data to backup area OK.\n");
178 		break;
179 	}
180 	case EF_WRITE_ERR: {
181 		EF_INFO("Warning: Write data to backup area fault!\n");
182 		break;
183 	}
184 	}
185 
186 	return result;
187 }
188 
189 /**
190  * Copy backup area application to application entry by using specified write function.
191  *
192  * @param user_app_addr application entry address
193  * @param app_size application size
194  * @param app_write user specified application write function
195  *
196  * @return result
197  */
ef_copy_spec_app_from_bak(uint32_t user_app_addr,size_t app_size,EfErrCode (* app_write)(uint32_t addr,const uint32_t * buf,size_t size))198 EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size,
199 									EfErrCode(*app_write)(uint32_t addr, const uint32_t *buf, size_t size))
200 {
201 	size_t cur_size;
202 	uint32_t app_cur_addr, bak_cur_addr;
203 	EfErrCode result = EF_NO_ERR;
204 	/* 32 words size buffer */
205 	uint32_t buff[32];
206 
207 	/* cycle copy data */
208 	for (cur_size = 0; cur_size < app_size; cur_size += sizeof(buff)) {
209 		app_cur_addr = user_app_addr + cur_size;
210 		bak_cur_addr = ef_get_bak_app_start_addr() + cur_size;
211 		ef_port_read(bak_cur_addr, buff, sizeof(buff));
212 		result = app_write(app_cur_addr, buff, sizeof(buff));
213 		if (result != EF_NO_ERR)
214 			break;
215 	}
216 
217 	switch (result) {
218 	case EF_NO_ERR: {
219 		EF_INFO("Write data to application entry OK.\n");
220 		break;
221 	}
222 	case EF_WRITE_ERR: {
223 		EF_INFO("Warning: Write data to application entry fault!\n");
224 		break;
225 	}
226 	}
227 
228 	return result;
229 }
230 
231 /**
232  * Copy backup area application to application entry by using default `ef_port_write` function.
233  *
234  * @param user_app_addr application entry address
235  * @param app_size application size
236  *
237  * @return result
238  */
ef_copy_app_from_bak(uint32_t user_app_addr,size_t app_size)239 EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size)
240 {
241 	return ef_copy_spec_app_from_bak(user_app_addr, app_size, ef_port_write);
242 }
243 
244 /**
245  * Copy backup area bootloader to bootloader entry.
246  *
247  * @param bl_addr bootloader entry address
248  * @param bl_size bootloader size
249  *
250  * @return result
251  */
ef_copy_bl_from_bak(uint32_t bl_addr,size_t bl_size)252 EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size)
253 {
254 	size_t cur_size;
255 	uint32_t bl_cur_addr, bak_cur_addr;
256 	EfErrCode result = EF_NO_ERR;
257 	/* 32 words buffer */
258 	uint32_t buff[32];
259 
260 	/* cycle copy data by 32bytes buffer */
261 	for (cur_size = 0; cur_size < bl_size; cur_size += sizeof(buff)) {
262 		bl_cur_addr = bl_addr + cur_size;
263 		bak_cur_addr = ef_get_bak_app_start_addr() + cur_size;
264 		ef_port_read(bak_cur_addr, buff, sizeof(buff));
265 		result = ef_port_write(bl_cur_addr, buff, sizeof(buff));
266 		if (result != EF_NO_ERR)
267 			break;
268 	}
269 
270 	switch (result) {
271 	case EF_NO_ERR: {
272 		EF_INFO("Write data to bootloader entry OK.\n");
273 		break;
274 	}
275 	case EF_WRITE_ERR: {
276 		EF_INFO("Warning: Write data to bootloader entry fault!\n");
277 		break;
278 	}
279 	}
280 
281 	return result;
282 }
283 
284 /**
285  * Get IAP section start address in flash.
286  *
287  * @return size
288  */
ef_get_bak_app_start_addr(void)289 uint32_t ef_get_bak_app_start_addr(void)
290 {
291 	return bak_app_start_addr;
292 }
293 
294 #endif /* EF_USING_IAP */
295