HAL_Linux_Class.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #include "HAL_Linux_Class.h"
  2. #include <assert.h>
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <AP_HAL/AP_HAL.h>
  8. #include <AP_HAL/utility/RCOutput_Tap.h>
  9. #include <AP_HAL/utility/getopt_cpp.h>
  10. #include <AP_HAL_Empty/AP_HAL_Empty.h>
  11. #include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
  12. #include <AP_Module/AP_Module.h>
  13. #include "AnalogIn_ADS1115.h"
  14. #include "AnalogIn_IIO.h"
  15. #include "AnalogIn_Navio2.h"
  16. #include "GPIO.h"
  17. #include "I2CDevice.h"
  18. #include "OpticalFlow_Onboard.h"
  19. #include "RCInput.h"
  20. #include "RCInput_AioPRU.h"
  21. #include "RCInput_Navio2.h"
  22. #include "RCInput_PRU.h"
  23. #include "RCInput_RPI.h"
  24. #include "RCInput_SoloLink.h"
  25. #include "RCInput_UART.h"
  26. #include "RCInput_UDP.h"
  27. #include "RCInput_Multi.h"
  28. #include "RCInput_ZYNQ.h"
  29. #include "RCInput_RCProtocol.h"
  30. #include "RCOutput_AioPRU.h"
  31. #include "RCOutput_Bebop.h"
  32. #include "RCOutput_Disco.h"
  33. #include "RCOutput_PCA9685.h"
  34. #include "RCOutput_PRU.h"
  35. #include "RCOutput_Sysfs.h"
  36. #include "RCOutput_ZYNQ.h"
  37. #include "SPIDevice.h"
  38. #include "SPIUARTDriver.h"
  39. #include "Scheduler.h"
  40. #include "Storage.h"
  41. #include "UARTDriver.h"
  42. #include "Util.h"
  43. #include "Util_RPI.h"
  44. using namespace Linux;
  45. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
  46. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
  47. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE || \
  48. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
  49. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
  50. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK || \
  51. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
  52. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR
  53. static UtilRPI utilInstance;
  54. #else
  55. static Util utilInstance;
  56. #endif
  57. // 5 serial ports on Linux
  58. static UARTDriver uartADriver(true);
  59. static UARTDriver uartCDriver(false);
  60. static UARTDriver uartDDriver(false);
  61. static UARTDriver uartEDriver(false);
  62. static UARTDriver uartFDriver(false);
  63. static UARTDriver uartGDriver(false);
  64. static UARTDriver uartHDriver(false);
  65. static I2CDeviceManager i2c_mgr_instance;
  66. static SPIDeviceManager spi_mgr_instance;
  67. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
  68. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
  69. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
  70. static SPIUARTDriver uartBDriver;
  71. #else
  72. static UARTDriver uartBDriver(false);
  73. #endif
  74. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
  75. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
  76. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
  77. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
  78. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR
  79. static AnalogIn_ADS1115 analogIn;
  80. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
  81. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD || \
  82. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
  83. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
  84. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
  85. static AnalogIn_IIO analogIn;
  86. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
  87. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
  88. static AnalogIn_Navio2 analogIn;
  89. #else
  90. static Empty::AnalogIn analogIn;
  91. #endif
  92. static Storage storageDriver;
  93. /*
  94. use the BBB gpio driver on ERLE, PXF, BBBMINI, BLUE and PocketPilot
  95. */
  96. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
  97. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD || \
  98. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
  99. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
  100. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
  101. static GPIO_BBB gpioDriver;
  102. /*
  103. use the RPI gpio driver on Navio
  104. */
  105. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
  106. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
  107. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK || \
  108. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
  109. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR
  110. static GPIO_RPI gpioDriver;
  111. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
  112. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
  113. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
  114. static GPIO_Sysfs gpioDriver;
  115. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP || \
  116. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO || \
  117. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_AERO
  118. static GPIO_Sysfs gpioDriver;
  119. #else
  120. static Empty::GPIO gpioDriver;
  121. #endif
  122. /*
  123. use the PRU based RCInput driver on ERLE and PXF
  124. */
  125. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
  126. static RCInput_PRU rcinDriver;
  127. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
  128. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
  129. static RCInput_AioPRU rcinDriver;
  130. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE
  131. static RCInput_Multi rcinDriver{2, new RCInput_AioPRU, new RCInput_RCProtocol(NULL, "/dev/ttyO4")};
  132. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
  133. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
  134. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
  135. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK || \
  136. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
  137. static RCInput_RPI rcinDriver;
  138. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ZYNQ || \
  139. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OCPOC_ZYNQ
  140. static RCInput_ZYNQ rcinDriver;
  141. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
  142. static RCInput_UDP rcinDriver;
  143. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO
  144. static RCInput_Multi rcinDriver{2, new RCInput_RCProtocol("/dev/uart-sbus", "/dev/uart-sumd"), new RCInput_UDP()};
  145. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_AERO
  146. static RCInput_SoloLink rcinDriver;
  147. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
  148. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
  149. static RCInput_Navio2 rcinDriver;
  150. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RST_ZYNQ
  151. static RCInput_RCProtocol rcinDriver{"/dev/ttyPS0", NULL};
  152. #else
  153. static RCInput rcinDriver;
  154. #endif
  155. /*
  156. use the PRU based RCOutput driver on ERLE and PXF
  157. */
  158. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
  159. static RCOutput_PRU rcoutDriver;
  160. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
  161. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
  162. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
  163. static RCOutput_AioPRU rcoutDriver;
  164. /*
  165. use the PCA9685 based RCOutput driver on Navio and Erle-Brain 2
  166. */
  167. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
  168. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
  169. static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device(1, PCA9685_PRIMARY_ADDRESS), true, 3, RPI_GPIO_27);
  170. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
  171. static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device(1, PCA9685_PRIMARY_ADDRESS), true, 3, NAVIO_GPIO_PCA_OE);
  172. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
  173. static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device(1, PCA9685_QUATENARY_ADDRESS), false, 0, RPI_GPIO_4);
  174. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK
  175. static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device(1, PCA9685_QUINARY_ADDRESS), false, 0, RPI_GPIO_27);
  176. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR
  177. static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device(1, PCA9685_PRIMARY_ADDRESS), false, 0, RPI_GPIO_27);
  178. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ZYNQ || \
  179. CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OCPOC_ZYNQ
  180. static RCOutput_ZYNQ rcoutDriver;
  181. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
  182. static RCOutput_Bebop rcoutDriver(i2c_mgr_instance.get_device(HAL_RCOUT_BEBOP_BLDC_I2C_BUS, HAL_RCOUT_BEBOP_BLDC_I2C_ADDR));
  183. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO
  184. static RCOutput_Disco rcoutDriver(i2c_mgr_instance.get_device(HAL_RCOUT_DISCO_BLDC_I2C_BUS, HAL_RCOUT_DISCO_BLDC_I2C_ADDR));
  185. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2
  186. static RCOutput_Sysfs rcoutDriver(0, 0, 14);
  187. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_AERO
  188. static ap::RCOutput_Tap rcoutDriver;
  189. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
  190. static RCOutput_Sysfs rcoutDriver(0, 0, 15);
  191. #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RST_ZYNQ
  192. static RCOutput_Sysfs rcoutDriver(0, 0, 8);
  193. #else
  194. static Empty::RCOutput rcoutDriver;
  195. #endif
  196. static Scheduler schedulerInstance;
  197. #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
  198. static OpticalFlow_Onboard opticalFlow;
  199. #else
  200. static Empty::OpticalFlow opticalFlow;
  201. #endif
  202. static Empty::Flash flashDriver;
  203. HAL_Linux::HAL_Linux() :
  204. AP_HAL::HAL(
  205. &uartADriver,
  206. &uartBDriver,
  207. &uartCDriver,
  208. &uartDDriver,
  209. &uartEDriver,
  210. &uartFDriver,
  211. &uartGDriver,
  212. &uartHDriver,
  213. &i2c_mgr_instance,
  214. &spi_mgr_instance,
  215. &analogIn,
  216. &storageDriver,
  217. &uartADriver,
  218. &gpioDriver,
  219. &rcinDriver,
  220. &rcoutDriver,
  221. &schedulerInstance,
  222. &utilInstance,
  223. &opticalFlow,
  224. &flashDriver,
  225. nullptr)
  226. {}
  227. void _usage(void)
  228. {
  229. printf("Usage: -A uartAPath -B uartBPath -C uartCPath -D uartDPath -E uartEPath -F uartFPath -G uartGpath -H uartHpath\n");
  230. printf("Options:\n");
  231. printf("\tserial:\n");
  232. printf(" -A /dev/ttyO4\n");
  233. printf("\t -B /dev/ttyS1\n");
  234. printf("\tnetworking tcp:\n");
  235. printf("\t -C tcp:192.168.2.15:1243:wait\n");
  236. printf("\t -A tcp:11.0.0.2:5678\n");
  237. printf("\t -A udp:11.0.0.2:14550\n");
  238. printf("\tnetworking UDP:\n");
  239. printf("\t -A udp:11.0.0.255:14550:bcast\n");
  240. printf("\t -A udpin:0.0.0.0:14550\n");
  241. printf("\tcustom log path:\n");
  242. printf("\t --log-directory /var/APM/logs\n");
  243. printf("\t -l /var/APM/logs\n");
  244. printf("\tcustom terrain path:\n");
  245. printf("\t --terrain-directory /var/APM/terrain\n");
  246. printf("\t -t /var/APM/terrain\n");
  247. #if AP_MODULE_SUPPORTED
  248. printf("\tmodule support:\n");
  249. printf("\t --module-directory %s\n", AP_MODULE_DEFAULT_DIRECTORY);
  250. printf("\t -M %s\n", AP_MODULE_DEFAULT_DIRECTORY);
  251. #endif
  252. }
  253. void HAL_Linux::run(int argc, char* const argv[], Callbacks* callbacks) const
  254. {
  255. #if AP_MODULE_SUPPORTED
  256. const char *module_path = AP_MODULE_DEFAULT_DIRECTORY;
  257. #endif
  258. assert(callbacks);
  259. int opt;
  260. const struct GetOptLong::option options[] = {
  261. {"uartA", true, 0, 'A'},
  262. {"uartB", true, 0, 'B'},
  263. {"uartC", true, 0, 'C'},
  264. {"uartD", true, 0, 'D'},
  265. {"uartE", true, 0, 'E'},
  266. {"uartF", true, 0, 'F'},
  267. {"uartG", true, 0, 'G'},
  268. {"uartH", true, 0, 'H'},
  269. {"log-directory", true, 0, 'l'},
  270. {"terrain-directory", true, 0, 't'},
  271. {"storage-directory", true, 0, 's'},
  272. {"module-directory", true, 0, 'M'},
  273. {"help", false, 0, 'h'},
  274. {0, false, 0, 0}
  275. };
  276. GetOptLong gopt(argc, argv, "A:B:C:D:E:F:l:t:s:he:SM:",
  277. options);
  278. /*
  279. parse command line options
  280. */
  281. while ((opt = gopt.getoption()) != -1) {
  282. switch (opt) {
  283. case 'A':
  284. uartADriver.set_device_path(gopt.optarg);
  285. break;
  286. case 'B':
  287. uartBDriver.set_device_path(gopt.optarg);
  288. break;
  289. case 'C':
  290. uartCDriver.set_device_path(gopt.optarg);
  291. break;
  292. case 'D':
  293. uartDDriver.set_device_path(gopt.optarg);
  294. break;
  295. case 'E':
  296. uartEDriver.set_device_path(gopt.optarg);
  297. break;
  298. case 'F':
  299. uartFDriver.set_device_path(gopt.optarg);
  300. break;
  301. case 'G':
  302. uartGDriver.set_device_path(gopt.optarg);
  303. break;
  304. case 'H':
  305. uartHDriver.set_device_path(gopt.optarg);
  306. break;
  307. case 'l':
  308. utilInstance.set_custom_log_directory(gopt.optarg);
  309. break;
  310. case 't':
  311. utilInstance.set_custom_terrain_directory(gopt.optarg);
  312. break;
  313. case 's':
  314. utilInstance.set_custom_storage_directory(gopt.optarg);
  315. break;
  316. #if AP_MODULE_SUPPORTED
  317. case 'M':
  318. module_path = gopt.optarg;
  319. break;
  320. #endif
  321. case 'h':
  322. _usage();
  323. exit(0);
  324. default:
  325. printf("Unknown option '%c'\n", (char)opt);
  326. exit(1);
  327. }
  328. }
  329. setup_signal_handlers();
  330. scheduler->init();
  331. gpio->init();
  332. rcout->init();
  333. rcin->init();
  334. uartA->begin(115200);
  335. uartE->begin(115200);
  336. uartF->begin(115200);
  337. uartG->begin(115200);
  338. uartH->begin(115200);
  339. analogin->init();
  340. utilInstance.init(argc+gopt.optind-1, &argv[gopt.optind-1]);
  341. // NOTE: See commit 9f5b4ffca ("AP_HAL_Linux_Class: Correct
  342. // deadlock, and infinite loop in setup()") for details about the
  343. // order of scheduler initialize and setup on Linux.
  344. scheduler->system_initialized();
  345. // possibly load external modules
  346. #if AP_MODULE_SUPPORTED
  347. if (module_path != nullptr) {
  348. AP_Module::init(module_path);
  349. }
  350. #endif
  351. #if AP_MODULE_SUPPORTED
  352. AP_Module::call_hook_setup_start();
  353. #endif
  354. callbacks->setup();
  355. #if AP_MODULE_SUPPORTED
  356. AP_Module::call_hook_setup_complete();
  357. #endif
  358. while (!_should_exit) {
  359. callbacks->loop();
  360. }
  361. rcin->teardown();
  362. I2CDeviceManager::from(i2c_mgr)->teardown();
  363. SPIDeviceManager::from(spi)->teardown();
  364. Scheduler::from(scheduler)->teardown();
  365. }
  366. void HAL_Linux::setup_signal_handlers() const
  367. {
  368. struct sigaction sa = { };
  369. sa.sa_flags = SA_NOCLDSTOP;
  370. sa.sa_handler = HAL_Linux::exit_signal_handler;
  371. sigaction(SIGTERM, &sa, NULL);
  372. sigaction(SIGINT, &sa, NULL);
  373. }
  374. static HAL_Linux halInstance;
  375. void HAL_Linux::exit_signal_handler(int signum)
  376. {
  377. halInstance._should_exit = true;
  378. }
  379. const AP_HAL::HAL &AP_HAL::get_HAL()
  380. {
  381. return halInstance;
  382. }