Line data Source code
1 : #include "HAL_Linux_Class.h"
2 :
3 : #include <assert.h>
4 : #include <signal.h>
5 : #include <sched.h>
6 : #include <stdio.h>
7 : #include <stdlib.h>
8 : #include <unistd.h>
9 :
10 : #include <AP_HAL/AP_HAL.h>
11 : #include <AP_HAL/utility/RCOutput_Tap.h>
12 : #include <AP_HAL/utility/getopt_cpp.h>
13 : #include <AP_HAL_Empty/AP_HAL_Empty.h>
14 : #include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
15 : #include <AP_Module/AP_Module.h>
16 :
17 : #include "AnalogIn_ADS1115.h"
18 : #include "AnalogIn_IIO.h"
19 : #include "AnalogIn_Navio2.h"
20 : #include "GPIO.h"
21 : #include "I2CDevice.h"
22 : #include "OpticalFlow_Onboard.h"
23 : #include "RCInput.h"
24 : #include "RCInput_AioPRU.h"
25 : #include "RCInput_PRU.h"
26 : #include "RCInput_RPI.h"
27 : #include "RCInput_SoloLink.h"
28 : #include "RCInput_UDP.h"
29 : #include "RCInput_Multi.h"
30 : #include "RCInput_ZYNQ.h"
31 : #include "RCInput_RCProtocol.h"
32 : #include "RCOutput_AioPRU.h"
33 : #include "RCOutput_AioPRU_PB2.h"
34 : #include "RCOutput_Bebop.h"
35 : #include "RCOutput_Disco.h"
36 : #include "RCOutput_Multi.h"
37 : #include "RCOutput_PCA9685.h"
38 : #include "RCOutput_PRU.h"
39 : #include "RCOutput_Sysfs.h"
40 : #include "RCOutput_ZYNQ.h"
41 : #include "RCOutput_RPI.h"
42 : #include "SPIDevice.h"
43 : #include "SPIUARTDriver.h"
44 : #include "Scheduler.h"
45 : #include "Storage.h"
46 : #include "UARTDriver.h"
47 : #include "Util.h"
48 : #include "Util_RPI.h"
49 : #include "CANSocketIface.h"
50 :
51 : using namespace Linux;
52 :
53 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
54 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
55 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE || \
56 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
57 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
58 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK || \
59 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
60 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR || \
61 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OBAL_V1 || \
62 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_CANZERO || \
63 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PILOTPI
64 : static UtilRPI utilInstance;
65 : #else
66 : static Util utilInstance;
67 : #endif
68 :
69 : // 10 serial ports on Linux
70 : static UARTDriver serial0Driver(true);
71 : static UARTDriver serial1Driver(false);
72 : static UARTDriver serial2Driver(false);
73 : // serial3Driver declared below depending on board type
74 : static UARTDriver serial4Driver(false);
75 : static UARTDriver serial5Driver(false);
76 : static UARTDriver serial6Driver(false);
77 : static UARTDriver serial7Driver(false);
78 : static UARTDriver serial8Driver(false);
79 : static UARTDriver serial9Driver(false);
80 :
81 : static I2CDeviceManager i2c_mgr_instance;
82 : static SPIDeviceManager spi_mgr_instance;
83 :
84 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
85 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
86 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
87 : static SPIUARTDriver serial3Driver;
88 : #else
89 : static UARTDriver serial3Driver(false);
90 : #endif
91 :
92 : static UARTDriver* serialDrivers[] = {
93 : &serial0Driver,
94 : &serial1Driver,
95 : &serial2Driver,
96 : &serial3Driver,
97 : &serial4Driver,
98 : &serial5Driver,
99 : &serial6Driver,
100 : &serial7Driver,
101 : &serial8Driver,
102 : &serial9Driver,
103 : };
104 :
105 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
106 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
107 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
108 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
109 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR || \
110 : ((CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OBAL_V1) && (OBAL_ALLOW_ADC ==1)) || \
111 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_CANZERO || \
112 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PILOTPI || \
113 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_T3_GEM_O1
114 : static AnalogIn_ADS1115 analogIn;
115 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
116 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD || \
117 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
118 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
119 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET || \
120 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET2
121 : static AnalogIn_IIO analogIn;
122 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
123 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
124 : static AnalogIn_Navio2 analogIn;
125 : #else
126 : static Empty::AnalogIn analogIn;
127 : #endif
128 :
129 : static Storage storageDriver;
130 :
131 : /*
132 : use the BBB gpio driver on ERLE, PXF, BBBMINI, BLUE, PocketPilot e PocketPilot 2
133 : */
134 : #if HAL_LINUX_GPIO_BBB_ENABLED
135 : static GPIO_BBB gpioDriver;
136 : #elif HAL_LINUX_GPIO_NAVIGATOR_ENABLED
137 : static GPIO_Navigator gpioDriver;
138 : #elif HAL_LINUX_GPIO_RPI_ENABLED
139 : static GPIO_RPI gpioDriver;
140 : #elif HAL_LINUX_GPIO_SYSFS_ENABLED
141 : static GPIO_Sysfs gpioDriver;
142 : #elif HAL_LINUX_GPIO_PB2_ENABLED
143 : static GPIO_PB2 gpioDriver;
144 : #else
145 : static Empty::GPIO gpioDriver;
146 : #endif
147 :
148 : /*
149 : use the PRU based RCInput driver on ERLE and PXF
150 : */
151 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
152 : static RCInput_PRU rcinDriver;
153 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
154 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET || \
155 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET2
156 : static RCInput_AioPRU rcinDriver;
157 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE
158 : static RCInput_Multi rcinDriver{2, NEW_NOTHROW RCInput_AioPRU, NEW_NOTHROW RCInput_RCProtocol(NULL, "/dev/ttyO4")};
159 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
160 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
161 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
162 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK || \
163 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI || \
164 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OBAL_V1 || \
165 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_CANZERO
166 : static RCInput_RPI rcinDriver;
167 : #elif AP_RCPROTOCOL_ZYNQ_ENABLED
168 : static RCInput_ZYNQ rcinDriver;
169 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
170 : static RCInput_UDP rcinDriver;
171 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO
172 : static RCInput_Multi rcinDriver{2, NEW_NOTHROW RCInput_RCProtocol("/dev/uart-sbus", "/dev/uart-sumd"), NEW_NOTHROW RCInput_UDP()};
173 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_AERO
174 : static RCInput_SoloLink rcinDriver;
175 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PILOTPI
176 : static RCInput_RCProtocol rcinDriver{"/dev/ttyAMA0", NULL};
177 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_VNAV || \
178 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR || \
179 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2 || \
180 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE || \
181 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_T3_GEM_O1
182 : // this is needed to allow for RC input using SERIALn_PROTOCOL=23. No fd is opened
183 : // in the linux driver and instead user needs to provide a uart via SERIALn_PROTOCOL
184 : static RCInput_RCProtocol rcinDriver{nullptr, nullptr};
185 : #else
186 : static RCInput rcinDriver;
187 : #endif
188 :
189 : /*
190 : use the PRU based RCOutput driver on ERLE and PXF
191 : */
192 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
193 : static RCOutput_PRU rcoutDriver;
194 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI || \
195 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BLUE || \
196 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET
197 : static RCOutput_AioPRU rcoutDriver;
198 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_POCKET2
199 : static RCOutput_AioPRU_PB2 rcoutDriver;
200 : /*
201 : use the PCA9685 based RCOutput driver on Navio and Erle-Brain 2
202 : */
203 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
204 : CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
205 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(1, PCA9685_PRIMARY_ADDRESS), 24576000, 3, RPI_GPIO_<27>());
206 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO
207 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(1, PCA9685_PRIMARY_ADDRESS), 24576000, 3, NAVIO_GPIO_PCA_OE);
208 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
209 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(1, PCA9685_QUATENARY_ADDRESS), 0, 0, RPI_GPIO_<4>());
210 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DARK
211 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(1, PCA9685_QUINARY_ADDRESS), 0, 0, RPI_GPIO_<27>());
212 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIGATOR
213 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(4, PCA9685_PRIMARY_ADDRESS), 24576000, 0, RPI_GPIO_<26>());
214 : #elif AP_RCOUTPUT_ZYNQ_ENABLED
215 : static RCOutput_ZYNQ rcoutDriver;
216 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
217 : static RCOutput_Bebop rcoutDriver(i2c_mgr_instance.get_device(HAL_RCOUT_BEBOP_BLDC_I2C_BUS, HAL_RCOUT_BEBOP_BLDC_I2C_ADDR));
218 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO
219 : static RCOutput_Disco rcoutDriver(i2c_mgr_instance.get_device(HAL_RCOUT_DISCO_BLDC_I2C_BUS, HAL_RCOUT_DISCO_BLDC_I2C_ADDR));
220 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO2
221 : static RCOutput_Sysfs rcoutDriver(0, 0, 14);
222 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_AERO
223 : static ap::RCOutput_Tap rcoutDriver;
224 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_EDGE
225 : static RCOutput_Sysfs rcoutDriver(0, 0, 15);
226 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_OBAL_V1
227 : static RCOutput_PCA9685 rcoutDriver(i2c_mgr_instance.get_device_ptr(1, PCA9685_PRIMARY_ADDRESS), 0, 0, RPI_GPIO_<17>());
228 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_CANZERO
229 : static RCOutput_Sysfs rcoutDriver(0, 0, 2);
230 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PILOTPI
231 : RCOutput_Multi::RCOutputGroup rcoutPcaDriver = {16, NEW_NOTHROW RCOutput_PCA9685(i2c_mgr_instance.get_device_ptr(1, PCA9685_PRIMARY_ADDRESS), 24576000, 0, -1) };
232 : RCOutput_Multi::RCOutputGroup rcoutSysfsDriver = {2, NEW_NOTHROW RCOutput_Sysfs(0, 0, 2)};
233 : static RCOutput_Multi rcoutDriver{2, &rcoutPcaDriver, &rcoutSysfsDriver};
234 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_T3_GEM_O1
235 : static RCOutput_Sysfs rcoutDriver(0, 0, 7);
236 : #elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RPI
237 : static RCOutput_RPI rcoutDriver;
238 : #else
239 : static Empty::RCOutput rcoutDriver;
240 : #endif
241 :
242 : static Scheduler schedulerInstance;
243 :
244 : #if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
245 : static OpticalFlow_Onboard opticalFlow;
246 : #else
247 : static Empty::OpticalFlow opticalFlow;
248 : #endif
249 :
250 : #if HAL_WITH_DSP
251 : static Empty::DSP dspDriver;
252 : #endif
253 : static Empty::Flash flashDriver;
254 : static Empty::WSPIDeviceManager wspi_mgr_instance;
255 :
256 : #if HAL_NUM_CAN_IFACES
257 : static CANIface* canDrivers[HAL_NUM_CAN_IFACES];
258 : #endif
259 :
260 48 : HAL_Linux::HAL_Linux() :
261 : AP_HAL::HAL(
262 : &serial0Driver,
263 : &serial1Driver,
264 : &serial2Driver,
265 : &serial3Driver,
266 : &serial4Driver,
267 : &serial5Driver,
268 : &serial6Driver,
269 : &serial7Driver,
270 : &serial8Driver,
271 : &serial9Driver,
272 : &i2c_mgr_instance,
273 : &spi_mgr_instance,
274 : &wspi_mgr_instance,
275 : &analogIn,
276 : &storageDriver,
277 : &serial0Driver,
278 : &gpioDriver,
279 : &rcinDriver,
280 : &rcoutDriver,
281 : &schedulerInstance,
282 : &utilInstance,
283 : &opticalFlow,
284 : &flashDriver,
285 : #if HAL_WITH_DSP
286 : &dspDriver,
287 : #endif
288 : #if HAL_NUM_CAN_IFACES
289 : (AP_HAL::CANIface**)canDrivers
290 : #else
291 : nullptr
292 : #endif
293 48 : )
294 48 : {}
295 :
296 0 : void _usage(void)
297 : {
298 0 : printf("Usage: --serial0 serial0Path --serial1 serial1Path \n");
299 0 : printf("Examples:\n");
300 0 : printf("\tserial (0 through 9 available):\n");
301 0 : printf("\t --serial0 /dev/ttyO4\n");
302 0 : printf("\t --serial3 /dev/ttyS1\n");
303 0 : printf("\tlegacy UART options are deprecated, their mappings are:\n");
304 0 : printf("\t -A/--uartA is SERIAL0\n");
305 0 : printf("\t -C/--uartC is SERIAL1\n"); // ordering captures the historical use of uartB as SERIAL3
306 0 : printf("\t -D/--uartD is SERIAL2\n");
307 0 : printf("\t -B/--uartB is SERIAL3\n");
308 0 : printf("\t -E/--uartE is SERIAL4\n");
309 0 : printf("\t -F/--uartF is SERIAL5\n");
310 0 : printf("\t -G/--uartG is SERIAL6\n");
311 0 : printf("\t -H/--uartH is SERIAL7\n");
312 0 : printf("\t -I/--uartI is SERIAL8\n");
313 0 : printf("\t -J/--uartJ is SERIAL9\n");
314 0 : printf("\tnetworking tcp:\n");
315 0 : printf("\t --serial1 tcp:192.168.2.15:1243:wait\n");
316 0 : printf("\t --serial0 tcp:11.0.0.2:5678\n");
317 0 : printf("\t --serial0 udp:11.0.0.2:14550\n");
318 0 : printf("\t --serial0 udp:11.0.0.2:14550\n");
319 0 : printf("\tnetworking UDP:\n");
320 0 : printf("\t --serial0 udp:11.0.0.255:14550:bcast\n");
321 0 : printf("\t --serial0 udpin:0.0.0.0:14550\n");
322 0 : printf("\tcustom log path:\n");
323 0 : printf("\t --log-directory /var/APM/logs\n");
324 0 : printf("\t -l /var/APM/logs\n");
325 0 : printf("\tcustom terrain path:\n");
326 0 : printf("\t --terrain-directory /var/APM/terrain\n");
327 0 : printf("\t -t /var/APM/terrain\n");
328 0 : printf("\tcustom storage path:\n");
329 0 : printf("\t --storage-directory /var/APM/storage\n");
330 0 : printf("\t -s /var/APM/storage\n");
331 : #if AP_MODULE_SUPPORTED
332 0 : printf("\tmodule support:\n");
333 0 : printf("\t --module-directory %s\n", AP_MODULE_DEFAULT_DIRECTORY);
334 0 : printf("\t -M %s\n", AP_MODULE_DEFAULT_DIRECTORY);
335 : #endif
336 0 : printf("\tcpu affinity:\n");
337 0 : printf("\t --cpu-affinity 1 (single cpu) or 1,3 (multiple cpus) or 1-3 (range of cpus)\n");
338 0 : printf("\t -c 1 (single cpu) or 1,3 (multiple cpus) or 1-3 (range of cpus)\n");
339 0 : }
340 :
341 0 : void HAL_Linux::run(int argc, char* const argv[], Callbacks* callbacks) const
342 : {
343 : #if AP_MODULE_SUPPORTED
344 0 : const char *module_path = AP_MODULE_DEFAULT_DIRECTORY;
345 : #endif
346 :
347 : enum long_options {
348 : CMDLINE_SERIAL0 = 1, // must be in 0-9 order and numbered consecutively
349 : CMDLINE_SERIAL1,
350 : CMDLINE_SERIAL2,
351 : CMDLINE_SERIAL3,
352 : CMDLINE_SERIAL4,
353 : CMDLINE_SERIAL5,
354 : CMDLINE_SERIAL6,
355 : CMDLINE_SERIAL7,
356 : CMDLINE_SERIAL8,
357 : CMDLINE_SERIAL9,
358 : };
359 :
360 : int opt;
361 0 : const struct GetOptLong::option options[] = {
362 : {"uartA", true, 0, 'A'},
363 : {"uartB", true, 0, 'B'},
364 : {"uartC", true, 0, 'C'},
365 : {"uartD", true, 0, 'D'},
366 : {"uartE", true, 0, 'E'},
367 : {"uartF", true, 0, 'F'},
368 : {"uartG", true, 0, 'G'},
369 : {"uartH", true, 0, 'H'},
370 : {"uartI", true, 0, 'I'},
371 : {"uartJ", true, 0, 'J'},
372 : {"serial0", true, 0, CMDLINE_SERIAL0},
373 : {"serial1", true, 0, CMDLINE_SERIAL1},
374 : {"serial2", true, 0, CMDLINE_SERIAL2},
375 : {"serial3", true, 0, CMDLINE_SERIAL3},
376 : {"serial4", true, 0, CMDLINE_SERIAL4},
377 : {"serial5", true, 0, CMDLINE_SERIAL5},
378 : {"serial6", true, 0, CMDLINE_SERIAL6},
379 : {"serial7", true, 0, CMDLINE_SERIAL7},
380 : {"serial8", true, 0, CMDLINE_SERIAL8},
381 : {"serial9", true, 0, CMDLINE_SERIAL9},
382 : {"log-directory", true, 0, 'l'},
383 : {"terrain-directory", true, 0, 't'},
384 : {"storage-directory", true, 0, 's'},
385 : {"module-directory", true, 0, 'M'},
386 : {"defaults", true, 0, 'd'},
387 : {"cpu-affinity", true, 0, 'c'},
388 : {"help", false, 0, 'h'},
389 : {0, false, 0, 0}
390 : };
391 :
392 : GetOptLong gopt(argc, argv, "A:B:C:D:E:F:G:H:I:J:l:t:s:he:SM:c:",
393 0 : options);
394 :
395 : /*
396 : parse command line options
397 : */
398 0 : while ((opt = gopt.getoption()) != -1) {
399 0 : switch (opt) {
400 0 : case 'A':
401 : case 'B':
402 : case 'C':
403 : case 'D':
404 : case 'E':
405 : case 'F':
406 : case 'G':
407 : case 'H':
408 : case 'I':
409 : case 'J': {
410 0 : int uart_idx = opt - 'A';
411 : // ordering captures the historical use of uartB as SERIAL3
412 : static const uint8_t mapping[] = { 0, 3, 1, 2, 4, 5, 6, 7, 8, 9 };
413 0 : int serial_idx = mapping[uart_idx];
414 0 : printf("WARNING: deprecated option --uart%c/-%c will be removed in "
415 : "a future release. Use --serial%d instead.\n",
416 : (char)opt, (char)opt, serial_idx);
417 0 : serialDrivers[serial_idx]->set_device_path(gopt.optarg);
418 0 : break;
419 : }
420 0 : case CMDLINE_SERIAL0:
421 : case CMDLINE_SERIAL1:
422 : case CMDLINE_SERIAL2:
423 : case CMDLINE_SERIAL3:
424 : case CMDLINE_SERIAL4:
425 : case CMDLINE_SERIAL5:
426 : case CMDLINE_SERIAL6:
427 : case CMDLINE_SERIAL7:
428 : case CMDLINE_SERIAL8:
429 : case CMDLINE_SERIAL9:
430 0 : serialDrivers[opt - CMDLINE_SERIAL0]->set_device_path(gopt.optarg);
431 0 : break;
432 0 : case 'l':
433 0 : utilInstance.set_custom_log_directory(gopt.optarg);
434 0 : break;
435 0 : case 't':
436 0 : utilInstance.set_custom_terrain_directory(gopt.optarg);
437 0 : break;
438 0 : case 's':
439 0 : utilInstance.set_custom_storage_directory(gopt.optarg);
440 0 : break;
441 : #if AP_MODULE_SUPPORTED
442 0 : case 'M':
443 0 : module_path = gopt.optarg;
444 0 : break;
445 : #endif
446 0 : case 'd':
447 0 : utilInstance.set_custom_defaults_path(gopt.optarg);
448 0 : break;
449 0 : case 'c':
450 : cpu_set_t cpu_affinity;
451 0 : if (!utilInstance.parse_cpu_set(gopt.optarg, &cpu_affinity)) {
452 0 : fprintf(stderr, "Could not parse cpu affinity: %s\n", gopt.optarg);
453 0 : exit(1);
454 : }
455 0 : Linux::Scheduler::from(scheduler)->set_cpu_affinity(cpu_affinity);
456 0 : break;
457 0 : case 'h':
458 0 : _usage();
459 0 : exit(0);
460 0 : default:
461 0 : printf("Unknown option '%c'\n", (char)opt);
462 0 : exit(1);
463 : }
464 : }
465 :
466 : // NOTE: signal handlers are only set before the main loop, so
467 : // that if anything before the loops hangs, the default signals
468 : // can still stop the process proprely, although without proper
469 : // teardown.
470 : // This isn't perfect, but still prevents an unkillable process.
471 :
472 0 : scheduler->init();
473 0 : gpio->init();
474 0 : rcout->init();
475 0 : rcin->init();
476 0 : serial(0)->begin(115200);
477 0 : analogin->init();
478 0 : utilInstance.init(argc+gopt.optind-1, &argv[gopt.optind-1]);
479 :
480 : // NOTE: See commit 9f5b4ffca ("AP_HAL_Linux_Class: Correct
481 : // deadlock, and infinite loop in setup()") for details about the
482 : // order of scheduler initialize and setup on Linux.
483 0 : scheduler->set_system_initialized();
484 :
485 : // possibly load external modules
486 : #if AP_MODULE_SUPPORTED
487 0 : if (module_path != nullptr) {
488 0 : AP_Module::init(module_path);
489 : }
490 : #endif
491 :
492 : #if AP_MODULE_SUPPORTED
493 0 : AP_Module::call_hook_setup_start();
494 : #endif
495 0 : callbacks->setup();
496 : #if AP_MODULE_SUPPORTED
497 0 : AP_Module::call_hook_setup_complete();
498 : #endif
499 :
500 0 : setup_signal_handlers();
501 :
502 0 : while (!_should_exit) {
503 0 : callbacks->loop();
504 : }
505 :
506 : // At least try to stop all PWM before shutting down
507 0 : rcout->force_safety_on();
508 0 : rcin->teardown();
509 0 : I2CDeviceManager::from(i2c_mgr)->teardown();
510 0 : SPIDeviceManager::from(spi)->teardown();
511 0 : Scheduler::from(scheduler)->teardown();
512 0 : }
513 :
514 0 : void HAL_Linux::setup_signal_handlers() const
515 : {
516 0 : struct sigaction sa = { };
517 :
518 0 : sa.sa_flags = SA_NOCLDSTOP;
519 0 : sa.sa_handler = HAL_Linux::exit_signal_handler;
520 0 : sigaction(SIGTERM, &sa, NULL);
521 0 : sigaction(SIGINT, &sa, NULL);
522 0 : }
523 :
524 : HAL_Linux hal_linux;
525 :
526 0 : void HAL_Linux::exit_signal_handler(int signum)
527 : {
528 0 : hal_linux._should_exit = true;
529 0 : }
530 :
531 40 : const AP_HAL::HAL &AP_HAL::get_HAL()
532 : {
533 40 : return hal_linux;
534 : }
535 :
536 0 : AP_HAL::HAL &AP_HAL::get_HAL_mutable()
537 : {
538 0 : return hal_linux;
539 : }
|