bootloader.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. #include "bootloader.h"
  13. #include "bootloader_types.h"
  14. #include "bootloader_util.h"
  15. #include "bootloader_settings.h"
  16. #include "dfu.h"
  17. #include "dfu_transport.h"
  18. #include "nrf.h"
  19. #include "app_error.h"
  20. #include "nrf_sdm.h"
  21. #include "nrf_mbr.h"
  22. #include "nordic_common.h"
  23. #include "crc16.h"
  24. #include "pstorage.h"
  25. #include "app_scheduler.h"
  26. #include "nrf_delay.h"
  27. #include "sdk_common.h"
  28. #define IRQ_ENABLED 0x01 /**< Field identifying if an interrupt is enabled. */
  29. #define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */
  30. /**@brief Enumeration for specifying current bootloader status.
  31. */
  32. typedef enum
  33. {
  34. BOOTLOADER_UPDATING, /**< Bootloader status for indicating that an update is in progress. */
  35. BOOTLOADER_SETTINGS_SAVING, /**< Bootloader status for indicating that saving of bootloader settings is in progress. */
  36. BOOTLOADER_COMPLETE, /**< Bootloader status for indicating that all operations for the update procedure has completed and it is safe to reset the system. */
  37. BOOTLOADER_TIMEOUT, /**< Bootloader status field for indicating that a timeout has occured and current update process should be aborted. */
  38. BOOTLOADER_RESET, /**< Bootloader status field for indicating that a reset has been requested and current update process should be aborted. */
  39. } bootloader_status_t;
  40. static pstorage_handle_t m_bootsettings_handle; /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */
  41. static bootloader_status_t m_update_status; /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */
  42. /**@brief Function for handling callbacks from pstorage module.
  43. *
  44. * @details Handles pstorage results for clear and storage operation. For detailed description of
  45. * the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t.
  46. */
  47. static void pstorage_callback_handler(pstorage_handle_t * p_handle,
  48. uint8_t op_code,
  49. uint32_t result,
  50. uint8_t * p_data,
  51. uint32_t data_len)
  52. {
  53. // If we are in BOOTLOADER_SETTINGS_SAVING state and we receive an PSTORAGE_STORE_OP_CODE
  54. // response then settings has been saved and update has completed.
  55. if ((m_update_status == BOOTLOADER_SETTINGS_SAVING) && (op_code == PSTORAGE_STORE_OP_CODE))
  56. {
  57. m_update_status = BOOTLOADER_COMPLETE;
  58. }
  59. APP_ERROR_CHECK(result);
  60. }
  61. /**@brief Function for waiting for events.
  62. *
  63. * @details This function will place the chip in low power mode while waiting for events from
  64. * the SoftDevice or other peripherals. When interrupted by an event, it will call the
  65. * @ref app_sched_execute function to process the received event. This function will return
  66. * when the final state of the firmware update is reached OR when a tear down is in
  67. * progress.
  68. */
  69. static void wait_for_events(void)
  70. {
  71. for (;;)
  72. {
  73. // Wait in low power state for any events.
  74. uint32_t err_code = sd_app_evt_wait();
  75. APP_ERROR_CHECK(err_code);
  76. // Event received. Process it from the scheduler.
  77. app_sched_execute();
  78. if ((m_update_status == BOOTLOADER_COMPLETE) ||
  79. (m_update_status == BOOTLOADER_TIMEOUT) ||
  80. (m_update_status == BOOTLOADER_RESET))
  81. {
  82. // When update has completed or a timeout/reset occured we will return.
  83. return;
  84. }
  85. }
  86. }
  87. bool bootloader_app_is_valid(uint32_t app_addr)
  88. {
  89. // const bootloader_settings_t * p_bootloader_settings;
  90. // There exists an application in CODE region 1.
  91. if (*((uint32_t *)app_addr) == EMPTY_FLASH_MASK)
  92. {
  93. return false;
  94. }
  95. else //zhou
  96. {
  97. return true;
  98. }
  99. // //bool success = false;
  100. // bool success = true; //just make the setting page checking success,PS: setting page data generate by nrfutil software automatic
  101. // bootloader_util_settings_get(&p_bootloader_settings);
  102. // // The application in CODE region 1 is flagged as valid during update.
  103. // if (p_bootloader_settings->bank_0 == BANK_VALID_APP)
  104. // {
  105. // uint16_t image_crc = 0;
  106. // // A stored crc value of 0 indicates that CRC checking is not used.
  107. // if (p_bootloader_settings->bank_0_crc != 0)
  108. // {
  109. // image_crc = crc16_compute((uint8_t *)DFU_BANK_0_REGION_START,
  110. // p_bootloader_settings->bank_0_size,
  111. // NULL);
  112. // }
  113. // success = (image_crc == p_bootloader_settings->bank_0_crc);
  114. // }
  115. // return success;
  116. }
  117. static void bootloader_settings_save(bootloader_settings_t * p_settings)
  118. {
  119. uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t));
  120. APP_ERROR_CHECK(err_code);
  121. err_code = pstorage_store(&m_bootsettings_handle,
  122. (uint8_t *)p_settings,
  123. sizeof(bootloader_settings_t),
  124. 0);
  125. APP_ERROR_CHECK(err_code);
  126. }
  127. void bootloader_dfu_update_process(dfu_update_status_t update_status)
  128. {
  129. static bootloader_settings_t settings;
  130. const bootloader_settings_t * p_bootloader_settings;
  131. bootloader_util_settings_get(&p_bootloader_settings);
  132. if (update_status.status_code == DFU_UPDATE_APP_COMPLETE)
  133. {
  134. settings.bank_0_crc = update_status.app_crc;
  135. settings.bank_0_size = update_status.app_size;
  136. settings.bank_0 = BANK_VALID_APP;
  137. settings.bank_1 = BANK_INVALID_APP;
  138. m_update_status = BOOTLOADER_SETTINGS_SAVING;
  139. bootloader_settings_save(&settings);
  140. }
  141. else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE)
  142. {
  143. settings.bank_0_crc = update_status.app_crc;
  144. settings.bank_0_size = update_status.sd_size +
  145. update_status.bl_size +
  146. update_status.app_size;
  147. settings.bank_0 = BANK_VALID_SD;
  148. settings.bank_1 = BANK_INVALID_APP;
  149. settings.sd_image_size = update_status.sd_size;
  150. settings.bl_image_size = update_status.bl_size;
  151. settings.app_image_size = update_status.app_size;
  152. settings.sd_image_start = update_status.sd_image_start;
  153. m_update_status = BOOTLOADER_SETTINGS_SAVING;
  154. bootloader_settings_save(&settings);
  155. }
  156. else if (update_status.status_code == DFU_UPDATE_BOOT_COMPLETE)
  157. {
  158. settings.bank_0 = p_bootloader_settings->bank_0;
  159. settings.bank_0_crc = p_bootloader_settings->bank_0_crc;
  160. settings.bank_0_size = p_bootloader_settings->bank_0_size;
  161. settings.bank_1 = BANK_VALID_BOOT;
  162. settings.sd_image_size = update_status.sd_size;
  163. settings.bl_image_size = update_status.bl_size;
  164. settings.app_image_size = update_status.app_size;
  165. m_update_status = BOOTLOADER_SETTINGS_SAVING;
  166. bootloader_settings_save(&settings);
  167. }
  168. else if (update_status.status_code == DFU_UPDATE_SD_SWAPPED)
  169. {
  170. if (p_bootloader_settings->bank_0 == BANK_VALID_SD)
  171. {
  172. settings.bank_0_crc = 0;
  173. settings.bank_0_size = 0;
  174. settings.bank_0 = BANK_INVALID_APP;
  175. }
  176. // This handles cases where SoftDevice was not updated, hence bank0 keeps its settings.
  177. else
  178. {
  179. settings.bank_0 = p_bootloader_settings->bank_0;
  180. settings.bank_0_crc = p_bootloader_settings->bank_0_crc;
  181. settings.bank_0_size = p_bootloader_settings->bank_0_size;
  182. }
  183. settings.bank_1 = BANK_INVALID_APP;
  184. settings.sd_image_size = 0;
  185. settings.bl_image_size = 0;
  186. settings.app_image_size = 0;
  187. m_update_status = BOOTLOADER_SETTINGS_SAVING;
  188. bootloader_settings_save(&settings);
  189. }
  190. else if (update_status.status_code == DFU_TIMEOUT)
  191. {
  192. // Timeout has occurred. Close the connection with the DFU Controller.
  193. uint32_t err_code = dfu_transport_close();
  194. APP_ERROR_CHECK(err_code);
  195. m_update_status = BOOTLOADER_TIMEOUT;
  196. }
  197. else if (update_status.status_code == DFU_BANK_0_ERASED)
  198. {
  199. settings.bank_0_crc = 0;
  200. settings.bank_0_size = 0;
  201. settings.bank_0 = BANK_INVALID_APP;
  202. settings.bank_1 = p_bootloader_settings->bank_1;
  203. bootloader_settings_save(&settings);
  204. }
  205. else if (update_status.status_code == DFU_RESET)
  206. {
  207. m_update_status = BOOTLOADER_RESET;
  208. }
  209. else
  210. {
  211. // No implementation needed.
  212. }
  213. }
  214. uint32_t bootloader_init(void)
  215. {
  216. uint32_t err_code;
  217. pstorage_module_param_t storage_params = {.cb = pstorage_callback_handler};
  218. err_code = pstorage_init();
  219. VERIFY_SUCCESS(err_code);
  220. m_bootsettings_handle.block_id = BOOTLOADER_SETTINGS_ADDRESS;
  221. err_code = pstorage_register(&storage_params, &m_bootsettings_handle);
  222. return err_code;
  223. }
  224. uint32_t bootloader_dfu_start(void)
  225. {
  226. uint32_t err_code;
  227. // Clear swap if banked update is used.
  228. err_code = dfu_init();
  229. VERIFY_SUCCESS(err_code);
  230. err_code = dfu_transport_update_start();
  231. wait_for_events();
  232. return err_code;
  233. }
  234. /**@brief Function for disabling all interrupts before jumping from bootloader to application.
  235. */
  236. static void interrupts_disable(void)
  237. {
  238. uint32_t interrupt_setting_mask;
  239. uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.
  240. // Fetch the current interrupt settings.
  241. interrupt_setting_mask = NVIC->ISER[0];
  242. for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
  243. {
  244. if (interrupt_setting_mask & (IRQ_ENABLED << irq))
  245. {
  246. // The interrupt was enabled, and hence disable it.
  247. NVIC_DisableIRQ((IRQn_Type)irq);
  248. }
  249. }
  250. }
  251. void bootloader_app_start(uint32_t app_addr)
  252. {
  253. // If the applications CRC has been checked and passed, the magic number will be written and we
  254. // can start the application safely.
  255. uint32_t err_code = sd_softdevice_disable();
  256. APP_ERROR_CHECK(err_code);
  257. interrupts_disable();
  258. err_code = sd_softdevice_vector_table_base_set(CODE_REGION_1_START);
  259. APP_ERROR_CHECK(err_code);
  260. bootloader_util_app_start(CODE_REGION_1_START);
  261. }
  262. bool bootloader_dfu_sd_in_progress(void)
  263. {
  264. const bootloader_settings_t * p_bootloader_settings;
  265. bootloader_util_settings_get(&p_bootloader_settings);
  266. if (p_bootloader_settings->bank_0 == BANK_VALID_SD ||
  267. p_bootloader_settings->bank_1 == BANK_VALID_BOOT)
  268. {
  269. return true;
  270. }
  271. return false;
  272. }
  273. uint32_t bootloader_dfu_sd_update_continue(void)
  274. {
  275. uint32_t err_code;
  276. if ((dfu_sd_image_validate() == NRF_SUCCESS) &&
  277. (dfu_bl_image_validate() == NRF_SUCCESS))
  278. {
  279. return NRF_SUCCESS;
  280. }
  281. // Ensure that flash operations are not executed within the first 100 ms seconds to allow
  282. // a debugger to be attached.
  283. nrf_delay_ms(100);
  284. err_code = dfu_sd_image_swap();
  285. APP_ERROR_CHECK(err_code);
  286. err_code = dfu_sd_image_validate();
  287. APP_ERROR_CHECK(err_code);
  288. err_code = dfu_bl_image_swap();
  289. APP_ERROR_CHECK(err_code);
  290. return err_code;
  291. }
  292. uint32_t bootloader_dfu_sd_update_finalize(void)
  293. {
  294. dfu_update_status_t update_status = {DFU_UPDATE_SD_SWAPPED, };
  295. bootloader_dfu_update_process(update_status);
  296. wait_for_events();
  297. return NRF_SUCCESS;
  298. }
  299. void bootloader_settings_get(bootloader_settings_t * const p_settings)
  300. {
  301. const bootloader_settings_t * p_bootloader_settings;
  302. bootloader_util_settings_get(&p_bootloader_settings);
  303. p_settings->bank_0 = p_bootloader_settings->bank_0;
  304. p_settings->bank_0_crc = p_bootloader_settings->bank_0_crc;
  305. p_settings->bank_0_size = p_bootloader_settings->bank_0_size;
  306. p_settings->bank_1 = p_bootloader_settings->bank_1;
  307. p_settings->sd_image_size = p_bootloader_settings->sd_image_size;
  308. p_settings->bl_image_size = p_bootloader_settings->bl_image_size;
  309. p_settings->app_image_size = p_bootloader_settings->app_image_size;
  310. p_settings->sd_image_start = p_bootloader_settings->sd_image_start;
  311. }