LCOV - code coverage report
Current view: top level - AP_HAL_Linux - HAL_Linux_Class.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 5 122 4.1 %
Date: 2026-09-09 11:02:08 Functions: 2 7 28.6 %

          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             : }

Generated by: LCOV version 1.14