HAL_ChibiOS_Class.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * This file is free software: you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License as published by the
  4. * Free Software Foundation, either version 3 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This file is distributed in the hope that it will be useful, but
  8. * WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. * See the GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License along
  13. * with this program. If not, see <http://www.gnu.org/licenses/>.
  14. *
  15. * Code by Andrew Tridgell and Siddharth Bharat Purohit
  16. */
  17. #include <AP_HAL/AP_HAL.h>
  18. #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
  19. #include <assert.h>
  20. #include "HAL_ChibiOS_Class.h"
  21. #include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
  22. #include <AP_HAL_ChibiOS/AP_HAL_ChibiOS_Private.h>
  23. #include "shared_dma.h"
  24. #include "sdcard.h"
  25. #include "hwdef/common/usbcfg.h"
  26. #include "hwdef/common/stm32_util.h"
  27. #include "hwdef/common/watchdog.h"
  28. #include <AP_BoardConfig/AP_BoardConfig.h>
  29. #include <AP_InternalError/AP_InternalError.h>
  30. #ifndef HAL_BOOTLOADER_BUILD
  31. #include <AP_Logger/AP_Logger.h>
  32. #endif
  33. #include <hwdef.h>
  34. #ifndef HAL_NO_UARTDRIVER
  35. static HAL_UARTA_DRIVER;
  36. static HAL_UARTB_DRIVER;
  37. static HAL_UARTC_DRIVER;
  38. static HAL_UARTD_DRIVER;
  39. static HAL_UARTE_DRIVER;
  40. static HAL_UARTF_DRIVER;
  41. static HAL_UARTG_DRIVER;
  42. static HAL_UARTH_DRIVER;
  43. #else
  44. static Empty::UARTDriver uartADriver;
  45. static Empty::UARTDriver uartBDriver;
  46. static Empty::UARTDriver uartCDriver;
  47. static Empty::UARTDriver uartDDriver;
  48. static Empty::UARTDriver uartEDriver;
  49. static Empty::UARTDriver uartFDriver;
  50. static Empty::UARTDriver uartGDriver;
  51. static Empty::UARTDriver uartHDriver;
  52. #endif
  53. #if HAL_USE_I2C == TRUE && defined(HAL_I2C_DEVICE_LIST)
  54. static ChibiOS::I2CDeviceManager i2cDeviceManager;
  55. #else
  56. static Empty::I2CDeviceManager i2cDeviceManager;
  57. #endif
  58. #if HAL_USE_SPI == TRUE
  59. static ChibiOS::SPIDeviceManager spiDeviceManager;
  60. #else
  61. static Empty::SPIDeviceManager spiDeviceManager;
  62. #endif
  63. #if HAL_USE_ADC == TRUE && !defined(HAL_DISABLE_ADC_DRIVER)
  64. static ChibiOS::AnalogIn analogIn;
  65. #else
  66. static Empty::AnalogIn analogIn;
  67. #endif
  68. #ifdef HAL_USE_EMPTY_STORAGE
  69. static Empty::Storage storageDriver;
  70. #else
  71. static ChibiOS::Storage storageDriver;
  72. #endif
  73. static ChibiOS::GPIO gpioDriver;
  74. static ChibiOS::RCInput rcinDriver;
  75. #if HAL_USE_PWM == TRUE
  76. static ChibiOS::RCOutput rcoutDriver;
  77. #else
  78. static Empty::RCOutput rcoutDriver;
  79. #endif
  80. static ChibiOS::Scheduler schedulerInstance;
  81. static ChibiOS::Util utilInstance;
  82. static Empty::OpticalFlow opticalFlowDriver;
  83. #ifndef HAL_NO_FLASH_SUPPORT
  84. static ChibiOS::Flash flashDriver;
  85. #else
  86. static Empty::Flash flashDriver;
  87. #endif
  88. #if HAL_WITH_IO_MCU
  89. HAL_UART_IO_DRIVER;
  90. #include <AP_IOMCU/AP_IOMCU.h>
  91. AP_IOMCU iomcu(uart_io);
  92. #endif
  93. HAL_ChibiOS::HAL_ChibiOS() :
  94. AP_HAL::HAL(
  95. &uartADriver,
  96. &uartBDriver,
  97. &uartCDriver,
  98. &uartDDriver,
  99. &uartEDriver,
  100. &uartFDriver,
  101. &uartGDriver,
  102. &uartHDriver,
  103. &i2cDeviceManager,
  104. &spiDeviceManager,
  105. &analogIn,
  106. &storageDriver,
  107. &uartADriver,
  108. &gpioDriver,
  109. &rcinDriver,
  110. &rcoutDriver,
  111. &schedulerInstance,
  112. &utilInstance,
  113. &opticalFlowDriver,
  114. &flashDriver,
  115. nullptr
  116. )
  117. {}
  118. static bool thread_running = false; /**< Daemon status flag */
  119. static thread_t* daemon_task; /**< Handle of daemon task / thread */
  120. extern const AP_HAL::HAL& hal;
  121. /*
  122. set the priority of the main APM task
  123. */
  124. void hal_chibios_set_priority(uint8_t priority)
  125. {
  126. chSysLock();
  127. #if CH_CFG_USE_MUTEXES == TRUE
  128. if ((daemon_task->prio == daemon_task->realprio) || (priority > daemon_task->prio)) {
  129. daemon_task->prio = priority;
  130. }
  131. daemon_task->realprio = priority;
  132. #endif
  133. chSchRescheduleS();
  134. chSysUnlock();
  135. }
  136. thread_t* get_main_thread()
  137. {
  138. return daemon_task;
  139. }
  140. static AP_HAL::HAL::Callbacks* g_callbacks;
  141. static AP_HAL::Util::PersistentData last_persistent_data;
  142. static void main_loop()
  143. {
  144. daemon_task = chThdGetSelfX();
  145. /*
  146. switch to high priority for main loop
  147. */
  148. chThdSetPriority(APM_MAIN_PRIORITY);
  149. #ifdef HAL_I2C_CLEAR_BUS
  150. // Clear all I2C Buses. This can be needed on some boards which
  151. // can get a stuck I2C peripheral on boot
  152. ChibiOS::I2CBus::clear_all();
  153. #endif
  154. ChibiOS::Shared_DMA::init();
  155. peripheral_power_enable();
  156. hal.uartA->begin(115200);
  157. #ifdef HAL_SPI_CHECK_CLOCK_FREQ
  158. // optional test of SPI clock frequencies
  159. ChibiOS::SPIDevice::test_clock_freq();
  160. #endif
  161. hal.uartB->begin(38400);
  162. hal.uartC->begin(57600);
  163. hal.analogin->init();
  164. hal.scheduler->init();
  165. /*
  166. run setup() at low priority to ensure CLI doesn't hang the
  167. system, and to allow initial sensor read loops to run
  168. */
  169. hal_chibios_set_priority(APM_STARTUP_PRIORITY);
  170. if (stm32_was_watchdog_reset()) {
  171. // load saved watchdog data
  172. stm32_watchdog_load((uint32_t *)&utilInstance.persistent_data, (sizeof(utilInstance.persistent_data)+3)/4);
  173. last_persistent_data = utilInstance.persistent_data;
  174. }
  175. schedulerInstance.hal_initialized();
  176. g_callbacks->setup();
  177. #ifdef IOMCU_FW
  178. stm32_watchdog_init();
  179. #elif !defined(HAL_BOOTLOADER_BUILD)
  180. // setup watchdog to reset if main loop stops
  181. if (AP_BoardConfig::watchdog_enabled()) {
  182. stm32_watchdog_init();
  183. }
  184. #ifndef HAL_NO_LOGGING
  185. if (hal.util->was_watchdog_reset()) {
  186. AP::internalerror().error(AP_InternalError::error_t::watchdog_reset);
  187. const AP_HAL::Util::PersistentData &pd = last_persistent_data;
  188. AP::logger().WriteCritical("WDOG", "TimeUS,Task,IErr,IErrCnt,MavMsg,MavCmd,SemLine,FL,FT,FA,FP,ICSR", "QbIIHHHHHIBI",
  189. AP_HAL::micros64(),
  190. pd.scheduler_task,
  191. pd.internal_errors,
  192. pd.internal_error_count,
  193. pd.last_mavlink_msgid,
  194. pd.last_mavlink_cmd,
  195. pd.semaphore_line,
  196. pd.fault_line,
  197. pd.fault_type,
  198. pd.fault_addr,
  199. pd.fault_thd_prio,
  200. pd.fault_icsr);
  201. }
  202. #endif // HAL_NO_LOGGING
  203. #endif // IOMCU_FW
  204. schedulerInstance.watchdog_pat();
  205. hal.scheduler->system_initialized();
  206. thread_running = true;
  207. chRegSetThreadName(SKETCHNAME);
  208. /*
  209. switch to high priority for main loop
  210. */
  211. chThdSetPriority(APM_MAIN_PRIORITY);
  212. while (true) {
  213. g_callbacks->loop();
  214. /*
  215. give up 50 microseconds of time if the INS loop hasn't
  216. called delay_microseconds_boost(), to ensure low priority
  217. drivers get a chance to run. Calling
  218. delay_microseconds_boost() means we have already given up
  219. time from the main loop, so we don't need to do it again
  220. here
  221. */
  222. #ifndef HAL_DISABLE_LOOP_DELAY
  223. if (!schedulerInstance.check_called_boost()) {
  224. hal.scheduler->delay_microseconds(50);
  225. }
  226. #endif
  227. schedulerInstance.watchdog_pat();
  228. }
  229. thread_running = false;
  230. }
  231. void HAL_ChibiOS::run(int argc, char * const argv[], Callbacks* callbacks) const
  232. {
  233. /*
  234. * System initializations.
  235. * - ChibiOS HAL initialization, this also initializes the configured device drivers
  236. * and performs the board-specific initializations.
  237. * - Kernel initialization, the main() function becomes a thread and the
  238. * RTOS is active.
  239. */
  240. #ifdef HAL_USB_PRODUCT_ID
  241. setup_usb_strings();
  242. #endif
  243. #ifdef HAL_STDOUT_SERIAL
  244. //STDOUT Initialistion
  245. SerialConfig stdoutcfg =
  246. {
  247. HAL_STDOUT_BAUDRATE,
  248. 0,
  249. USART_CR2_STOP1_BITS,
  250. 0
  251. };
  252. sdStart((SerialDriver*)&HAL_STDOUT_SERIAL, &stdoutcfg);
  253. #endif
  254. assert(callbacks);
  255. g_callbacks = callbacks;
  256. //Takeover main
  257. main_loop();
  258. }
  259. const AP_HAL::HAL& AP_HAL::get_HAL() {
  260. static const HAL_ChibiOS hal_chibios;
  261. return hal_chibios;
  262. }
  263. #endif