ZuluSCSI_bootloader.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Simple bootloader that loads new firmware from SD card.
  2. #include <ZuluSCSI_platform.h>
  3. #include "ZuluSCSI_log.h"
  4. #include <SdFat.h>
  5. #include <string.h>
  6. #ifdef AZPLATFORM_BOOTLOADER_SIZE
  7. extern SdFs SD;
  8. extern FsFile g_logfile;
  9. bool find_firmware_image(FsFile &file, char name[MAX_FILE_PATH + 1])
  10. {
  11. FsFile root;
  12. root.open("/");
  13. while (file.openNext(&root, O_READ))
  14. {
  15. if (file.isDir()) continue;
  16. int namelen = file.getName(name, MAX_FILE_PATH);
  17. if (namelen >= 11 &&
  18. strncasecmp(name, "zuluscsi", 8) == 0 &&
  19. strncasecmp(name + namelen - 3, "bin", 3) == 0)
  20. {
  21. root.close();
  22. azlog("Found firmware file: ", name);
  23. return true;
  24. }
  25. file.close();
  26. }
  27. root.close();
  28. return false;
  29. }
  30. bool program_firmware(FsFile &file)
  31. {
  32. uint32_t fwsize = file.size() - AZPLATFORM_BOOTLOADER_SIZE;
  33. uint32_t num_pages = (fwsize + AZPLATFORM_FLASH_PAGE_SIZE - 1) / AZPLATFORM_FLASH_PAGE_SIZE;
  34. static uint8_t buffer[AZPLATFORM_FLASH_PAGE_SIZE];
  35. if (fwsize > AZPLATFORM_FLASH_TOTAL_SIZE)
  36. {
  37. azlog("Firmware too large: ", (int)fwsize, " flash size ", (int)AZPLATFORM_FLASH_TOTAL_SIZE);
  38. return false;
  39. }
  40. if (!file.seek(AZPLATFORM_BOOTLOADER_SIZE))
  41. {
  42. azlog("Seek failed");
  43. return false;
  44. }
  45. for (int i = 0; i < num_pages; i++)
  46. {
  47. if (i % 2)
  48. LED_ON();
  49. else
  50. LED_OFF();
  51. if (file.read(buffer, AZPLATFORM_FLASH_PAGE_SIZE) <= 0)
  52. {
  53. azlog("Firmware file read failed on page ", i);
  54. return false;
  55. }
  56. if (!azplatform_rewrite_flash_page(AZPLATFORM_BOOTLOADER_SIZE + i * AZPLATFORM_FLASH_PAGE_SIZE, buffer))
  57. {
  58. azlog("Flash programming failed on page ", i);
  59. return false;
  60. }
  61. }
  62. return true;
  63. }
  64. extern "C"
  65. int bootloader_main(void)
  66. {
  67. azplatform_init();
  68. g_azlog_debug = true;
  69. azlog("Bootloader version: " __DATE__ " " __TIME__ " " PLATFORM_NAME);
  70. if (SD.begin(SD_CONFIG) || SD.begin(SD_CONFIG))
  71. {
  72. FsFile fwfile;
  73. char name[MAX_FILE_PATH + 1];
  74. if (find_firmware_image(fwfile, name))
  75. {
  76. if (program_firmware(fwfile))
  77. {
  78. azlog("Firmware update successful!");
  79. fwfile.close();
  80. if (!SD.remove(name))
  81. {
  82. azlog("Failed to remove firmware file");
  83. }
  84. }
  85. else
  86. {
  87. azlog("Firmware update failed!");
  88. azplatform_emergency_log_save();
  89. }
  90. }
  91. }
  92. else
  93. {
  94. azlog("Bootloader SD card init failed");
  95. }
  96. azlog("Bootloader continuing to main firmware");
  97. azplatform_boot_to_main_firmware();
  98. return 0;
  99. }
  100. #endif