HAL_SITL_Class.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include <AP_HAL/AP_HAL.h>
  2. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  3. #include <assert.h>
  4. #include <errno.h>
  5. #include <signal.h>
  6. #include <stdio.h>
  7. #include "AP_HAL_SITL.h"
  8. #include "AP_HAL_SITL_Namespace.h"
  9. #include "HAL_SITL_Class.h"
  10. #include "Scheduler.h"
  11. #include "AnalogIn.h"
  12. #include "UARTDriver.h"
  13. #include "Storage.h"
  14. #include "RCInput.h"
  15. #include "RCOutput.h"
  16. #include "GPIO.h"
  17. #include "SITL_State.h"
  18. #include "Util.h"
  19. #include <AP_BoardConfig/AP_BoardConfig.h>
  20. #include <AP_HAL_Empty/AP_HAL_Empty.h>
  21. #include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
  22. #include <AP_InternalError/AP_InternalError.h>
  23. #include <AP_Logger/AP_Logger.h>
  24. using namespace HALSITL;
  25. static Storage sitlStorage;
  26. static SITL_State sitlState;
  27. static Scheduler sitlScheduler(&sitlState);
  28. static RCInput sitlRCInput(&sitlState);
  29. static RCOutput sitlRCOutput(&sitlState);
  30. static AnalogIn sitlAnalogIn(&sitlState);
  31. static GPIO sitlGPIO(&sitlState);
  32. // use the Empty HAL for hardware we don't emulate
  33. static Empty::I2CDeviceManager i2c_mgr_instance;
  34. static Empty::SPIDeviceManager emptySPI;
  35. static Empty::OpticalFlow emptyOpticalFlow;
  36. static Empty::Flash emptyFlash;
  37. static UARTDriver sitlUart0Driver(0, &sitlState);
  38. static UARTDriver sitlUart1Driver(1, &sitlState);
  39. static UARTDriver sitlUart2Driver(2, &sitlState);
  40. static UARTDriver sitlUart3Driver(3, &sitlState);
  41. static UARTDriver sitlUart4Driver(4, &sitlState);
  42. static UARTDriver sitlUart5Driver(5, &sitlState);
  43. static UARTDriver sitlUart6Driver(6, &sitlState);
  44. static UARTDriver sitlUart7Driver(7, &sitlState);
  45. static Util utilInstance(&sitlState);
  46. HAL_SITL::HAL_SITL() :
  47. AP_HAL::HAL(
  48. &sitlUart0Driver, /* uartA */
  49. &sitlUart1Driver, /* uartB */
  50. &sitlUart2Driver, /* uartC */
  51. &sitlUart3Driver, /* uartD */
  52. &sitlUart4Driver, /* uartE */
  53. &sitlUart5Driver, /* uartF */
  54. &sitlUart6Driver, /* uartG */
  55. &sitlUart7Driver, /* uartH */
  56. &i2c_mgr_instance,
  57. &emptySPI, /* spi */
  58. &sitlAnalogIn, /* analogin */
  59. &sitlStorage, /* storage */
  60. &sitlUart0Driver, /* console */
  61. &sitlGPIO, /* gpio */
  62. &sitlRCInput, /* rcinput */
  63. &sitlRCOutput, /* rcoutput */
  64. &sitlScheduler, /* scheduler */
  65. &utilInstance, /* util */
  66. &emptyOpticalFlow, /* onboard optical flow */
  67. &emptyFlash, /* flash driver */
  68. nullptr), /* CAN */
  69. _sitl_state(&sitlState)
  70. {}
  71. static char *new_argv[100];
  72. /*
  73. save watchdog data
  74. */
  75. static bool watchdog_save(const uint32_t *data, uint32_t nwords)
  76. {
  77. int fd = ::open("persistent.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644);
  78. bool ret = false;
  79. if (fd != -1) {
  80. if (::write(fd, data, nwords*4) == (ssize_t)(nwords*4)) {
  81. ret = true;
  82. }
  83. ::close(fd);
  84. }
  85. return ret;
  86. }
  87. /*
  88. load watchdog data
  89. */
  90. static bool watchdog_load(uint32_t *data, uint32_t nwords)
  91. {
  92. int fd = ::open("persistent.dat", O_RDONLY, 0644);
  93. bool ret = false;
  94. if (fd != -1) {
  95. ret = (::read(fd, data, nwords*4) == (ssize_t)(nwords*4));
  96. ::close(fd);
  97. }
  98. return ret;
  99. }
  100. /*
  101. implement watchdoh reset via SIGALRM
  102. */
  103. static void sig_alrm(int signum)
  104. {
  105. static char env[] = "SITL_WATCHDOG_RESET=1";
  106. putenv(env);
  107. printf("GOT SIGALRM\n");
  108. execv(new_argv[0], new_argv);
  109. }
  110. void HAL_SITL::run(int argc, char * const argv[], Callbacks* callbacks) const
  111. {
  112. assert(callbacks);
  113. _sitl_state->init(argc, argv);
  114. scheduler->init();
  115. uartA->begin(115200);
  116. rcin->init();
  117. rcout->init();
  118. // spi->init();
  119. analogin->init();
  120. if (getenv("SITL_WATCHDOG_RESET")) {
  121. AP::internalerror().error(AP_InternalError::error_t::watchdog_reset);
  122. if (watchdog_load((uint32_t *)&utilInstance.persistent_data, (sizeof(utilInstance.persistent_data)+3)/4)) {
  123. uartA->printf("Loaded watchdog data");
  124. }
  125. }
  126. // form a new argv, removing problem parameters. This is used for reboot
  127. uint8_t new_argv_offset = 0;
  128. for (uint8_t i=0; i<ARRAY_SIZE(new_argv) && i<argc; i++) {
  129. if (!strcmp(argv[i], "-w")) {
  130. // don't wipe params on reboot
  131. continue;
  132. }
  133. new_argv[new_argv_offset++] = argv[i];
  134. }
  135. callbacks->setup();
  136. scheduler->system_initialized();
  137. if (getenv("SITL_WATCHDOG_RESET")) {
  138. const AP_HAL::Util::PersistentData &pd = util->persistent_data;
  139. AP::logger().WriteCritical("WDOG", "TimeUS,Task,IErr,IErrCnt,MavMsg,MavCmd,SemLine", "QbIIHHH",
  140. AP_HAL::micros64(),
  141. pd.scheduler_task,
  142. pd.internal_errors,
  143. pd.internal_error_count,
  144. pd.last_mavlink_msgid,
  145. pd.last_mavlink_cmd,
  146. pd.semaphore_line);
  147. }
  148. bool using_watchdog = AP_BoardConfig::watchdog_enabled();
  149. if (using_watchdog) {
  150. signal(SIGALRM, sig_alrm);
  151. alarm(2);
  152. }
  153. uint32_t last_watchdog_save = AP_HAL::millis();
  154. while (!HALSITL::Scheduler::_should_reboot) {
  155. callbacks->loop();
  156. HALSITL::Scheduler::_run_io_procs();
  157. uint32_t now = AP_HAL::millis();
  158. if (now - last_watchdog_save >= 100 && using_watchdog) {
  159. // save persistent data every 100ms
  160. last_watchdog_save = now;
  161. watchdog_save((uint32_t *)&utilInstance.persistent_data, (sizeof(utilInstance.persistent_data)+3)/4);
  162. }
  163. if (using_watchdog) {
  164. // note that this only works for a speedup of 1
  165. alarm(2);
  166. }
  167. }
  168. actually_reboot();
  169. }
  170. void HAL_SITL::actually_reboot()
  171. {
  172. execv(new_argv[0], new_argv);
  173. AP_HAL::panic("PANIC: REBOOT FAILED: %s", strerror(errno));
  174. }
  175. const AP_HAL::HAL& AP_HAL::get_HAL() {
  176. static const HAL_SITL hal;
  177. return hal;
  178. }
  179. #endif // CONFIG_HAL_BOARD == HAL_BOARD_SITL