Розробка драйверів
Драйвери пристроїв PX4 базуються на Device фреймворку.
Створення драйвера
PX4 майже виключно використовує дані з uORB. Драйвери для поширених типів периферійних пристроїв повинні публікувати правильні повідомлення uORB (наприклад: гіроскоп, акселерометр, датчики тиску тощо).
Найкращий підхід до створення нового драйвера - почати з аналогічного драйвера як шаблону (див. src/drivers).
Більш детальну інформацію про роботу з конкретними шинами вводу/виводу та датчиками можна знайти у розділі Шини датчиків та приводів.
Публікація правильних тем uORB є єдиним патерном, якого повинні повинні дотримуватися драйвери.
Архітектура ядра
PX4 є реактивною системою і використовує uORB для публікації/підписки на комунікаційні повідомлення. Файлові дескриптори не потрібні або не використовуються для основної роботи системи. Використовуються дві основні API:
- Система публікації/підписки, яка має файлову, мережеву або загальну пам'ять, залежно від системи, на якій працює PX4.
- Глобальний реєстр пристроїв, який можна використовувати для переліку пристроїв та отримання/налаштування їх конфігурації. Це може бути простий зв'язаний список або схема файлової системи.
Ідентифікатори пристрою(ID)
PX4 використовує ідентифікатори пристроїв для постійної ідентифікації окремих сенсорів у всій системі. Ці ідентифікатори зберігаються в параметрах конфігурації та використовуються для відповідності значень калібрування сенсора, а також для визначення того, який сенсор зареєстрований в якому записі журналу.
Порядок датчиків (наприклад, якщо є /dev/mag0
і альтернативний /dev/mag1
) не визначає пріоритет - пріоритет зберігається як частина опублікованої теми uORB.
Приклад декодування
Для прикладу трьох магнітометрів у системі використовуйте журнал польотів (.px4log) для вивантаження параметрів. Три параметри кодують ідентифікатори датчиків, а MAG_PRIME
визначає, який магнітометр вибрано основним датчиком. Кожен MAGx_ID є 24-бітним числом і повинен бути доповнений зліва нулями для ручного декодування.
CAL_MAG0_ID = 73225.0
CAL_MAG1_ID = 66826.0
CAL_MAG2_ID = 263178.0
CAL_MAG_PRIME = 73225.0
Це зовнішній HMC5983, підключений через I2C, шину 1 за адресою 0x1E
: він буде показаний у файлі журналу як IMU.MagX
.
# device ID 73225 in 24-bit binary:
00000001 00011110 00001 001
# decodes to:
HMC5883 0x1E bus 1 I2C
Це внутрішній HMC5983, підключений через SPI, шина 1, слот вибору slave 5. У файлі журналу це буде показано як IMU1.MagX
.
# device ID 66826 in 24-bit binary:
00000001 00000101 00001 010
# decodes to:
HMC5883 dev 5 bus 1 SPI
І це внутрішній магнітометр MPU9250, підключений через SPI, шина 1, слот вибору slave 4. У файлі журналу це буде показано як IMU2.MagX
.
# device ID 263178 in 24-bit binary:
00000100 00000100 00001 010
#decodes to:
MPU9250 dev 4 bus 1 SPI
Кодування ID пристрою
Ідентифікатор пристрою - це 24-бітове число відповідно до цього формату. Зверніть увагу, що перші поля - це молодші біти у наведеному вище прикладі декодування.
C
struct DeviceStructure {
enum DeviceBusType bus_type : 3;
uint8_t bus: 5; // which instance of the bus type
uint8_t address; // address on the bus (eg. I2C address)
uint8_t devtype; // device class specific device type
};
bus_type
декодується відповідно до:
C
enum DeviceBusType {
DeviceBusType_UNKNOWN = 0,
DeviceBusType_I2C = 1,
DeviceBusType_SPI = 2,
DeviceBusType_UAVCAN = 3,
};
і devtype
декодується відповідно до:
C
#define DRV_MAG_DEVTYPE_HMC5883 0x01
#define DRV_MAG_DEVTYPE_LSM303D 0x02
#define DRV_MAG_DEVTYPE_ACCELSIM 0x03
#define DRV_MAG_DEVTYPE_MPU9250 0x04
#define DRV_ACC_DEVTYPE_LSM303D 0x11
#define DRV_ACC_DEVTYPE_BMA180 0x12
#define DRV_ACC_DEVTYPE_MPU6000 0x13
#define DRV_ACC_DEVTYPE_ACCELSIM 0x14
#define DRV_ACC_DEVTYPE_GYROSIM 0x15
#define DRV_ACC_DEVTYPE_MPU9250 0x16
#define DRV_GYR_DEVTYPE_MPU6000 0x21
#define DRV_GYR_DEVTYPE_L3GD20 0x22
#define DRV_GYR_DEVTYPE_GYROSIM 0x23
#define DRV_GYR_DEVTYPE_MPU9250 0x24
#define DRV_RNG_DEVTYPE_MB12XX 0x31
#define DRV_RNG_DEVTYPE_LL40LS 0x32
Відлагодження
Для загальних тем відладки див. : Debugging/Logging.
Докладне ведення журналу
Драйвери (та інші модулі) за замовчуванням виводять мінімально докладні рядки логів (наприклад, для PX4_DEBUG
, PX4_WARN
, PX4_ERR
і т.д.).
Докладність логів визначається під час збирання за допомогою макросів RELEASE_BUILD
(за замовчуванням), DEBUG_BUILD
(докладно) або TRACE_BUILD
(дуже докладно).
Змініть рівень протоколювання за допомогою COMPILE_FLAGS
у функції драйвера px4_add_module
(CMakeLists.txt). У наведеному нижче фрагменті коду показано необхідну зміну, щоб увімкнути налагодження на рівні DEBUG_BUILD для окремого модуля або драйвера.
px4_add_module(
MODULE templates__module
MAIN module
COMPILE_FLAGS
-DDEBUG_BUILD
SRCS
module.cpp
DEPENDS
modules__uORB
)
TIP
Докладний лог також можна увімкнути для кожного файлу, додавши #define DEBUG_BUILD
у самому верху .cpp-файлу (перед будь-якими модулями).