mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-07 08:28:30 -04:00
e40785b002
This allows us to re-use I2CDevice from I2CDriver while the drivers are converted. We create a fake device with addr = 0 for each I2CDriver but we only use the register/unregister logic. The transfer logic still uses the methods from I2CDriver in order to use the right address. Now we can interoperate I2CDevice drivers with the ones base in I2CDriver since they are going to use the same semaphore and bus. The I2CDriver constructors were changed to re-use the logic in I2CDevice (it uses a number rather than an string) and the semaphore doesn't live outside anymore, its embedded in the fake I2CDevice, as well as the bus's file descritor.
339 lines
11 KiB
C++
339 lines
11 KiB
C++
#include <AP_HAL/AP_HAL.h>
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
|
|
|
#include <assert.h>
|
|
|
|
#include "HAL_Linux_Class.h"
|
|
#include "AP_HAL_Linux_Private.h"
|
|
|
|
#include <AP_HAL/utility/getopt_cpp.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <AP_HAL_Empty/AP_HAL_Empty.h>
|
|
#include <AP_HAL_Empty/AP_HAL_Empty_Private.h>
|
|
|
|
using namespace Linux;
|
|
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
|
|
static UtilRPI utilInstance;
|
|
#else
|
|
static Util utilInstance;
|
|
#endif
|
|
|
|
// 3 serial ports on Linux for now
|
|
static UARTDriver uartADriver(true);
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
|
|
static SPIUARTDriver uartBDriver;
|
|
#else
|
|
static UARTDriver uartBDriver(false);
|
|
#endif
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT
|
|
static RPIOUARTDriver uartCDriver;
|
|
#else
|
|
static UARTDriver uartCDriver(false);
|
|
#endif
|
|
static UARTDriver uartDDriver(false);
|
|
static UARTDriver uartEDriver(false);
|
|
|
|
static I2CDeviceManager i2c_mgr_instance;
|
|
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
static I2CDriver i2cDriver0(0);
|
|
static I2CDriver i2cDriver1(1);
|
|
static I2CDriver i2cDriver2(2);
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static I2CDriver i2cDriver0(2);
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE
|
|
static const std::vector<const char *> i2c_devpaths({
|
|
/* UEFI with lpss set to ACPI */
|
|
"/devices/platform/80860F41:05",
|
|
/* UEFI with lpss set to PCI */
|
|
"/devices/pci0000:00/0000:00:18.6",
|
|
});
|
|
static I2CDriver i2cDriver0(i2c_devpaths);
|
|
/* One additional emulated bus */
|
|
static I2CDriver i2cDriver1(10);
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
static Semaphore i2cSemaphore0;
|
|
static Empty::I2CDriver i2cDriver0(&i2cSemaphore0);
|
|
#else
|
|
static I2CDriver i2cDriver0(1);
|
|
#endif
|
|
|
|
static SPIDeviceManager spiDeviceManager;
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
|
|
static AnalogIn_ADS1115 analogIn;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT
|
|
static AnalogIn_Raspilot analogIn;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
static Empty::AnalogIn analogIn;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLE || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static AnalogIn_IIO analogIn;
|
|
#else
|
|
static AnalogIn analogIn;
|
|
#endif
|
|
|
|
/*
|
|
select between FRAM and FS
|
|
*/
|
|
#if LINUX_STORAGE_USE_FRAM == 1
|
|
static Storage_FRAM storageDriver;
|
|
#else
|
|
static Storage storageDriver;
|
|
#endif
|
|
|
|
/*
|
|
use the BBB gpio driver on ERLE, PXF and BBBMINI
|
|
*/
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static GPIO_BBB gpioDriver;
|
|
/*
|
|
use the RPI gpio driver on Navio
|
|
*/
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
|
|
static GPIO_RPI gpioDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
static GPIO_Sysfs gpioDriver;
|
|
#else
|
|
static Empty::GPIO gpioDriver;
|
|
#endif
|
|
|
|
/*
|
|
use the PRU based RCInput driver on ERLE and PXF
|
|
*/
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
|
|
static RCInput_PRU rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static RCInput_AioPRU rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
|
|
static RCInput_RPI rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT
|
|
static RCInput_Raspilot rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ZYNQ
|
|
static RCInput_ZYNQ rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
static RCInput_UDP rcinDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE
|
|
static RCInput_UART rcinDriver("/dev/ttyS2");
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
static RCInput_DSM rcinDriver;
|
|
#else
|
|
static RCInput rcinDriver;
|
|
#endif
|
|
|
|
/*
|
|
use the PRU based RCOutput driver on ERLE and PXF
|
|
*/
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBOARD
|
|
static RCOutput_PRU rcoutDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static RCOutput_AioPRU rcoutDriver;
|
|
/*
|
|
use the PCA9685 based RCOutput driver on Navio and Erle-Brain 2
|
|
*/
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_NAVIO || CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ERLEBRAIN2 || \
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXFMINI
|
|
static RCOutput_PCA9685 rcoutDriver(PCA9685_PRIMARY_ADDRESS, true, 3, RPI_GPIO_27);
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BH
|
|
static RCOutput_PCA9685 rcoutDriver(PCA9685_QUATENARY_ADDRESS, false, 0, RPI_GPIO_4);
|
|
/*
|
|
use the STM32 based RCOutput driver on Raspilot
|
|
*/
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_RASPILOT
|
|
static RCOutput_Raspilot rcoutDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_ZYNQ
|
|
static RCOutput_ZYNQ rcoutDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
static RCOutput_Bebop rcoutDriver;
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE
|
|
static RCOutput_PCA9685 rcoutDriver(PCA9685_PRIMARY_ADDRESS, false, 0, MINNOW_GPIO_S5_1);
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
static RCOutput_QFLIGHT rcoutDriver;
|
|
#else
|
|
static Empty::RCOutput rcoutDriver;
|
|
#endif
|
|
|
|
static Scheduler schedulerInstance;
|
|
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP ||\
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE ||\
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
|
static OpticalFlow_Onboard opticalFlow;
|
|
#else
|
|
static Empty::OpticalFlow opticalFlow;
|
|
#endif
|
|
|
|
HAL_Linux::HAL_Linux() :
|
|
AP_HAL::HAL(
|
|
&uartADriver,
|
|
&uartBDriver,
|
|
&uartCDriver,
|
|
&uartDDriver,
|
|
&uartEDriver,
|
|
&i2c_mgr_instance,
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
&i2cDriver0,
|
|
&i2cDriver1,
|
|
&i2cDriver2,
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE
|
|
&i2cDriver0,
|
|
&i2cDriver1,
|
|
NULL,
|
|
#else
|
|
&i2cDriver0,
|
|
NULL,
|
|
NULL,
|
|
#endif
|
|
&spiDeviceManager,
|
|
&analogIn,
|
|
&storageDriver,
|
|
&uartADriver,
|
|
&gpioDriver,
|
|
&rcinDriver,
|
|
&rcoutDriver,
|
|
&schedulerInstance,
|
|
&utilInstance,
|
|
&opticalFlow)
|
|
{}
|
|
|
|
void _usage(void)
|
|
{
|
|
printf("Usage: -A uartAPath -B uartBPath -C uartCPath -D uartDPath -E uartEPath\n");
|
|
printf("Options:\n");
|
|
printf("\t-serial: -A /dev/ttyO4\n");
|
|
printf("\t -B /dev/ttyS1\n");
|
|
printf("\t-tcp: -C tcp:192.168.2.15:1243:wait\n");
|
|
printf("\t -A tcp:11.0.0.2:5678\n");
|
|
printf("\t -A udp:11.0.0.2:5678\n");
|
|
printf("\t-custom log path:\n");
|
|
printf("\t --log-directory /var/APM/logs\n");
|
|
printf("\t -l /var/APM/logs\n");
|
|
printf("\t-custom terrain path:\n");
|
|
printf("\t --terrain-directory /var/APM/terrain\n");
|
|
printf("\t -t /var/APM/terrain\n");
|
|
}
|
|
|
|
void HAL_Linux::run(int argc, char* const argv[], Callbacks* callbacks) const
|
|
{
|
|
assert(callbacks);
|
|
|
|
int opt;
|
|
const struct GetOptLong::option options[] = {
|
|
{"uartA", true, 0, 'A'},
|
|
{"uartB", true, 0, 'B'},
|
|
{"uartC", true, 0, 'C'},
|
|
{"uartD", true, 0, 'D'},
|
|
{"uartE", true, 0, 'E'},
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
{"dsm", true, 0, 'S'},
|
|
{"ESC", true, 0, 'e'},
|
|
#endif
|
|
{"log-directory", true, 0, 'l'},
|
|
{"terrain-directory", true, 0, 't'},
|
|
{"help", false, 0, 'h'},
|
|
{0, false, 0, 0}
|
|
};
|
|
|
|
GetOptLong gopt(argc, argv, "A:B:C:D:E:l:t:he:S",
|
|
options);
|
|
|
|
/*
|
|
parse command line options
|
|
*/
|
|
while ((opt = gopt.getoption()) != -1) {
|
|
switch (opt) {
|
|
case 'A':
|
|
uartADriver.set_device_path(gopt.optarg);
|
|
break;
|
|
case 'B':
|
|
uartBDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
case 'C':
|
|
uartCDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
case 'D':
|
|
uartDDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
case 'E':
|
|
uartEDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_QFLIGHT
|
|
case 'e':
|
|
rcoutDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
case 'S':
|
|
rcinDriver.set_device_path(gopt.optarg);
|
|
break;
|
|
#endif // CONFIG_HAL_BOARD_SUBTYPE
|
|
case 'l':
|
|
utilInstance.set_custom_log_directory(gopt.optarg);
|
|
break;
|
|
case 't':
|
|
utilInstance.set_custom_terrain_directory(gopt.optarg);
|
|
break;
|
|
case 'h':
|
|
_usage();
|
|
exit(0);
|
|
default:
|
|
printf("Unknown option '%c'\n", (char)opt);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
scheduler->init();
|
|
gpio->init();
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP
|
|
i2c->begin();
|
|
i2c1->begin();
|
|
i2c2->begin();
|
|
#elif CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_MINLURE
|
|
i2c->begin();
|
|
i2c1->begin();
|
|
#else
|
|
i2c->begin();
|
|
#endif
|
|
spi->init();
|
|
rcout->init();
|
|
rcin->init();
|
|
uartA->begin(115200);
|
|
uartE->begin(115200);
|
|
analogin->init();
|
|
utilInstance.init(argc+gopt.optind-1, &argv[gopt.optind-1]);
|
|
|
|
// NOTE: See commit 9f5b4ffca ("AP_HAL_Linux_Class: Correct
|
|
// deadlock, and infinite loop in setup()") for details about the
|
|
// order of scheduler initialize and setup on Linux.
|
|
scheduler->system_initialized();
|
|
callbacks->setup();
|
|
|
|
for (;;) {
|
|
callbacks->loop();
|
|
}
|
|
}
|
|
|
|
const AP_HAL::HAL& AP_HAL::get_HAL() {
|
|
static const HAL_Linux hal;
|
|
return hal;
|
|
}
|
|
|
|
#endif
|