Betaflight源码学习
- Betaflight/src/main/fc/init.c
-
-
-
- 初始化串口 (Serial Port Initialization)
-
- 系统全局初始化 (System Global Initialization)
-
- 初始化任务数据 (Initialize Task Data)
-
- 初始化输入输出 (Initialize IO)
-
- 目标配置初始化 (Target Configuration Initialization)
-
- 配置目标特定的预初始化 (Target Specific Pre-Initialization)
-
- 初始化标志 (Initialization Flags)
-
- 根据配置初始化存储与文件系统 (Initialize Storage and File System Based on Configuration)
-
- 如果配置存储在SD卡上 (Config in SD Card)
- 如果配置存储在外置闪存或内存映射闪存上 (Config in External Flash or Memory Mapped Flash)
-
- 初始化EEPROM (Initialize EEPROM)
-
- 初始化板载信息 (Initialize Board Information)
-
- 检查并设置系统状态 (Check and Set System State)
-
- 调试引脚初始化 (Debug Pin Initialization)
-
- 设置调试模式 (Set Debug Mode)
-
- 目标特定的预初始化 (Target Specific Pre-Initialization)
-
- 初始化LED (Initialize LED)
-
- 初始化外部中断 (Initialize External Interrupts)
-
- 初始化按钮 (Initialize Buttons)
-
- 绑定Spektrum接收机 (Bind Spektrum Receiver)
-
- 设置系统时钟 (Set System Clock)
-
- 处理CPU超频 (Handle CPU Overclocking)
-
- 初始化MCO输出 (Initialize MCO Output)
-
- 初始化定时器 (Initialize Timer)
-
- 初始化总线切换引脚 (Initialize Bus Switch Pin)
-
- 配置UART引脚 (Configure UART Pins)
-
- 初始化串口通信 (Initialize Serial Communication)
-
- 初始化混合器 (Initialize Mixer)
-
- 初始化电机 (Initialize Motors)
-
- 初始化接收机 (Initialize Receiver)
-
- 初始化蜂鸣器 (Initialize Beeper)
-
- 初始化倒相器 (Initialize Inverters)
-
- 根据目标配置初始化总线 (Initialize Buses Based on Target Configuration)
-
- 初始化USB MSC (Initialize USB Mass Storage)
-
- 处理持久化RTC值 (Handle Persistent RTC Value)
-
- 初始化I2C总线 (Initialize I2C Bus)
-
- 检测硬件版本 (Detect Hardware Revision)
-
- 初始化VTX (Initialize VTX)
-
- 初始化相机控制 (Initialize Camera Control)
-
- 初始化ADC (Initialize ADC)
-
- 初始化板载对齐 (Initialize Board Alignment)
-
- 自动检测传感器 (Auto-Detect Sensors)
-
- 设置目标循环时间 (Set Target Loop Time)
-
- 初始化传感器校准 (Initialize Sensor Calibration)
-
- 初始化飞行控制模块 (Initialize Flight Control Modules)
-
- 初始化VTX控制 (Initialize VTX Control)
-
- 初始化云台 (Initialize Gimbal)
-
- 初始化电池监控 (Initialize Battery Monitoring)
-
- 初始化RC设备 (Initialize RC Devices)
-
- 初始化持久化统计数据 (Initialize Persistent Statistics)
-
- 初始化MSP (Initialize MSP)
-
- 初始化CMS、显示设备和OSD (Initialize CMS, Display Devices and OSD)
-
- 设置启动保护时间 (Set Boot Grace Time)
-
- 启用SPI DMA (Enable SPI DMA)
-
- 初始化自动驾驶模式 (Initialize Autopilot Modes)
-
- 初始化GPS救援 (Initialize GPS Rescue)
-
- 初始化调试模块 (Initialize Debug Module)
-
- 初始化未使用的引脚 (Initialize Unused Pins)
-
- 初始化任务调度器 (Initialize Task Scheduler)
-
- 设置系统状态为准备就绪 (Set System State to Ready)
- 总结
-
-
Betaflight/src/main/fc/init.c
betaflight/src/main/fc/init.c
这段代码是Betaflight固件中负责系统初始化的核心部分。它通过一系列的初始化步骤,确保飞行控制器的各个硬件组件和功能模块能够正确启动和运作。下面是对这段代码的逐步分解与详细解释:
1. 初始化串口 (Serial Port Initialization)
c
#if SERIAL_PORT_COUNT > 0
printfSerialInit();
#endif
如果编译配置中定义了串口数量大于0,则初始化串口,使得可以通过串口输出调试信息。
2. 系统全局初始化 (System Global Initialization)
c
systemInit();
进行系统全局的初始化工作,这通常包括时钟设置、中断配置等基本操作。
3. 初始化任务数据 (Initialize Task Data)
c
tasksInitData();
初始化任务数据,这是必要的步骤,因为在任务初始化前任何试图修改任务行为的代码都可能无法达到预期效果。
4. 初始化输入输出 (Initialize IO)
c
IOInitGlobal();
初始化全局输入输出(IO),这是所有IO操作的基础。
5. 目标配置初始化 (Target Configuration Initialization)
c
#if defined(USE_TARGET_CONFIG)
targetConfiguration();
#endif
如果编译配置中定义了USE_TARGET_CONFIG,则进行目标特定的配置。这部分代码通常用于在配置数据加载之前进行必要的硬件设置,以便正确加载配置。
6. 配置目标特定的预初始化 (Target Specific Pre-Initialization)
c
#if defined(USE_CONFIG_TARGET_PREINIT)
configTargetPreInit();
#endif
如果编译配置中定义了USE_CONFIG_TARGET_PREINIT,则调用目标特定的预初始化函数。这部分代码处理一些在配置加载之前的初始化需求。
7. 初始化标志 (Initialization Flags)
c
enum {
FLASH_INIT_ATTEMPTED = (1 << 0),
SD_INIT_ATTEMPTED = (1 << 1),
SPI_BUSSES_INIT_ATTEMPTED = (1 << 2),
QUAD_OCTO_SPI_BUSSES_INIT_ATTEMPTED = (1 << 3),
};
uint8_t initFlags = 0;
定义一组初始化标志,用于记录和检查哪些初始化步骤已经执行。这些标志用于避免重复初始化,或者在某些情况下进行必要的检查。
8. 根据配置初始化存储与文件系统 (Initialize Storage and File System Based on Configuration)
如果配置存储在SD卡上 (Config in SD Card)
c
#ifdef CONFIG_IN_SDCARD
pgResetAll();
if (defined(USE_SDCARD_SPI)) {
configureSPIBusses();
initFlags |= SPI_BUSSES_INIT_ATTEMPTED;
}
sdCardAndFSInit();
initFlags |= SD_INIT_ATTEMPTED;
if (!sdcard_isInserted()) {
failureMode(FAILURE_SDCARD_REQUIRED);
}
while (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY) {
afatfs_poll();
if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_FATAL) {
failureMode(FAILURE_SDCARD_INITIALISATION_FAILED);
}
}
#endif
如果配置存储在SD卡上,则首先初始化SPI总线(如果需要),然后初始化SD卡和文件系统。如果SD卡没有插入,或者文件系统初始化失败,则进入故障模式。
如果配置存储在外置闪存或内存映射闪存上 (Config in External Flash or Memory Mapped Flash)
c
#if defined(CONFIG_IN_EXTERNAL_FLASH) || defined(CONFIG_IN_MEMORY_MAPPED_FLASH)
pgResetAll();
if (defined(CONFIG_IN_EXTERNAL_FLASH)) {
configureSPIBusses();
initFlags |= SPI_BUSSES_INIT_ATTEMPTED;
}
if (defined(CONFIG_IN_MEMORY_MAPPED_FLASH) || defined(CONFIG_IN_EXTERNAL_FLASH)) {
configureQuadSPIBusses();
configureOctoSPIBusses();
initFlags |= QUAD_OCTO_SPI_BUSSES_INIT_ATTEMPTED;
}
bool haveFlash = flashInit(flashConfig());
if (!haveFlash) {
failureMode(FAILURE_EXTERNAL_FLASH_INIT_FAILED);
}
initFlags |= FLASH_INIT_ATTEMPTED;
#endif
如果配置存储在外置闪存或内存映射闪存上,则初始化SPI、QSPI、OSPI总线(如果需要),然后初始化外置闪存。如果闪存初始化失败,则进入故障模式。
9. 初始化EEPROM (Initialize EEPROM)
c
initEEPROM();
ensureEEPROMStructureIsValid();
bool readSuccess = readEEPROM();
初始化EEPROM,并确保其结构有效,然后尝试从EEPROM读取配置。如果读取失败或者配置版本无效,则重置EEPROM。
10. 初始化板载信息 (Initialize Board Information)
c
#if defined(USE_BOARD_INFO)
initBoardInformation();
#endif
如果编译配置中定义了USE_BOARD_INFO,则初始化板载信息。
11. 检查并设置系统状态 (Check and Set System State)
c
systemState |= SYSTEM_STATE_CONFIG_LOADED;
设置系统状态为配置已加载。
12. 调试引脚初始化 (Debug Pin Initialization)
c
#ifdef USE_DEBUG_PIN
dbgPinInit();
#endif
如果编译配置中定义了USE_DEBUG_PIN,则初始化调试引脚。
13. 设置调试模式 (Set Debug Mode)
c
debugMode = systemConfig()->debug_mode;
根据配置设置调试模式。
14. 目标特定的预初始化 (Target Specific Pre-Initialization)
c
#ifdef TARGET_PREINIT
targetPreInit();
#endif
如果编译配置中定义了TARGET_PREINIT,则调用目标特定的预初始化函数。
15. 初始化LED (Initialize LED)
c
#if !defined(USE_VIRTUAL_LED)
ledInit(statusLedConfig());
#endif
LED2_ON;
如果编译配置中没有定义USE_VIRTUAL_LED,则初始化LED。设置状态LED为亮。
16. 初始化外部中断 (Initialize External Interrupts)
c
#if !defined(SIMULATOR_BUILD)
EXTIInit();
#endif
如果这不是一个模拟器构建,则初始化外部中断。
17. 初始化按钮 (Initialize Buttons)
c
#if defined(USE_BUTTONS)
buttonsInit();
delayMicroseconds(10);
// 允许EEPROM重置通过双按钮按下实现(不需电源重启)
#ifdef DEBUG
#define EEPROM_RESET_PRECONDITION true
#else
#define EEPROM_RESET_PRECONDITION (!isMPUSoftReset())
#endif
if (EEPROM_RESET_PRECONDITION) {
if (defined(BUTTON_A_PIN) && defined(BUTTON_B_PIN)) {
uint8_t secondsRemaining = 5;
bool bothButtonsHeld;
do {
bothButtonsHeld = buttonAPressed() && buttonBPressed();
if (bothButtonsHeld) {
if (--secondsRemaining == 0) {
resetEEPROM();
#ifdef USE_PERSISTENT_OBJECTS
persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE);
#endif
systemReset();
}
delay(1000);
LED0_TOGGLE;
}
} while (bothButtonsHeld);
}
}
#undef EEPROM_RESET_PRECONDITION
#endif
如果编译配置中定义了USE_BUTTONS,则初始化按钮。允许用户通过双按钮按下重置EEPROM,这在调试模式下始终是可能的,而在普通运行模式下仅在不是软重启的情况下允许。
18. 绑定Spektrum接收机 (Bind Spektrum Receiver)
c
#if defined(USE_SPEKTRUM_BIND)
if (featureIsEnabled(FEATURE_RX_SERIAL)) {
switch (rxConfig()->serialrx_provider) {
case SERIALRX_SPEKTRUM1024:
case SERIALRX_SPEKTRUM2048:
case SERIALRX_SRXL:
spektrumBind(rxConfigMutable());
break;
}
}
#endif
如果编译配置中定义了USE_SPEKTRUM_BIND,并且接收机提供者是Spektrum系列,则绑定Spektrum接收机。
19. 设置系统时钟 (Set System Clock)
c
#if PLATFORM_TRAIT_CONFIG_HSE
systemClockSetHSEValue(systemConfig()->hseMhz * 1000000U);
#endif
根据配置设置系统时钟频率。
20. 处理CPU超频 (Handle CPU Overclocking)
c
#ifdef USE_OVERCLOCK
OverclockRebootIfNecessary(systemConfig()->cpu_overclock);
#endif
如果编译配置中定义了USE_OVERCLOCK,则根据配置进行CPU超频处理。
21. 初始化MCO输出 (Initialize MCO Output)
c
#ifdef USE_MCO
mcoInit();
#endif
如果编译配置中定义了USE_MCO,则初始化MCO(主时钟输出)。
22. 初始化定时器 (Initialize Timer)
c
#ifdef USE_TIMER
timerInit();
#endif
如果编译配置中定义了USE_TIMER,则初始化定时器。
23. 初始化总线切换引脚 (Initialize Bus Switch Pin)
c
#ifdef BUS_SWITCH_PIN
busSwitchInit();
#endif
如果编译配置中定义了BUS_SWITCH_PIN,则初始化总线切换引脚。
24. 配置UART引脚 (Configure UART Pins)
c
#if defined(USE_UART) && !defined(SIMULATOR_BUILD)
uartPinConfigure(serialPinConfig());
#endif
如果编译配置中定义了USE_UART,并且这不是一个模拟器构建,则配置UART引脚。
25. 初始化串口通信 (Initialize Serial Communication)
c
serialInit(featureIsEnabled(FEATURE_SOFTSERIAL));
初始化串口通信,如果编译配置中定义了FEATURE_SOFTSERIAL,则启用软串口。
26. 初始化混合器 (Initialize Mixer)
c
mixerInit(mixerConfig()->mixerMode);
初始化混合器,混合器用于混合输入通道的控制信号以驱动电机和其他输出设备。
27. 初始化电机 (Initialize Motors)
c
#ifdef USE_MOTOR
motorDevInit(getMotorCount());
systemState |= SYSTEM_STATE_MOTORS_READY;
#endif
如果编译配置中定义了USE_MOTOR,则初始化电机。设置系统状态为电机已准备好。
28. 初始化接收机 (Initialize Receiver)
c
do {
#if defined(USE_RX_PPM)
if (featureIsEnabled(FEATURE_RX_PPM)) {
ppmRxInit(ppmConfig());
break;
}
#endif
#if defined(USE_RX_PWM)
if (featureIsEnabled(FEATURE_RX_PARALLEL_PWM)) {
pwmRxInit(pwmConfig());
break;
}
#endif
} while (false);
根据接收机类型初始化接收机。如果接收机类型为PPM或PWM,则分别初始化。
29. 初始化蜂鸣器 (Initialize Beeper)
c
#ifdef USE_BEEPER
beeperInit(beeperDevConfig());
#endif
如果编译配置中定义了USE_BEEPER,则初始化蜂鸣器。
30. 初始化倒相器 (Initialize Inverters)
c
#if defined(USE_INVERTER) && !defined(SIMULATOR_BUILD)
initInverters(serialPinConfig());
#endif
如果编译配置中定义了USE_INVERTER,则初始化倒相器。倒相器用于反转某些输出信号的极性。
31. 根据目标配置初始化总线 (Initialize Buses Based on Target Configuration)
c
#ifdef TARGET_BUS_INIT
targetBusInit();
#else
// 根据编译选项,SPI/QSPI/OSPI初始化可能已被执行。
if (!(initFlags & SPI_BUSSES_INIT_ATTEMPTED)) {
configureSPIBusses();
initFlags |= SPI_BUSSES_INIT_ATTEMPTED;
}
if (!(initFlags & QUAD_OCTO_SPI_BUSSES_INIT_ATTEMPTED)) {
configureQuadSPIBusses();
configureOctoSPIBusses();
initFlags |= QUAD_OCTO_SPI_BUSSES_INIT_ATTEMPTED;
}
#if defined(USE_SDCARD_SDIO) && !defined(CONFIG_IN_SDCARD) && PLATFORM_TRAIT_SDIO_INIT
sdioPinConfigure();
SDIO_GPIO_Init();
#endif
#endif
根据目标配置初始化总线。如果编译配置中定义了TARGET_BUS_INIT,则调用目标特定的总线初始化函数;否则,根据配置初始化SPI、QSPI、OSPI总线。
32. 初始化USB MSC (Initialize USB Mass Storage)
c
#ifdef USE_USB_MSC
mscInit();
if (mscCheckBootAndReset() || mscCheckButton()) {
ledInit(statusLedConfig());
if (blackboxConfig()->device == BLACKBOX_DEVICE_SDCARD) {
if (sdcardConfig()->mode) {
if (!(initFlags & SD_INIT_ATTEMPTED)) {
sdCardAndFSInit();
initFlags |= SD_INIT_ATTEMPTED;
}
}
}
if (defined(USE_FLASHFS)) {
if (blackboxConfig()->device == BLACKBOX_DEVICE_FLASH) {
emfat_init_files();
}
}
// 尽可能启用SPI DMA
#ifdef USE_SPI
spiInitBusDMA();
#endif
if (mscStart() == 0) {
mscWaitForButton();
} else {
systemResetFromMsc();
}
}
#endif
如果编译配置中定义了USE_USB_MSC,则初始化USB MSC(Mass Storage Control)。如果检测到USB设备插入或按钮按下,则初始化SD卡或外部闪存,并启动MSC模式。
33. 处理持久化RTC值 (Handle Persistent RTC Value)
c
#ifdef USE_PERSISTENT_MSC_RTC
persistentObjectWrite(PERSISTENT_OBJECT_RTC_HIGH, 0);
persistentObjectWrite(PERSISTENT_OBJECT_RTC_LOW, 0);
#endif
如果编译配置中定义了USE_PERSISTENT_MSC_RTC,则清空持久化的RTC值。
34. 初始化I2C总线 (Initialize I2C Bus)
c
#ifdef USE_I2C
i2cPinConfigure(i2cConfig(0));
#ifdef USE_I2C_DEVICE_0
i2cInit(I2CDEV_0);
#endif
// 更多I2C设备初始化...
#endif
如果编译配置中定义了USE_I2C,则配置并初始化I2C总线。
35. 检测硬件版本 (Detect Hardware Revision)
c
#ifdef USE_HARDWARE_REVISION_DETECTION
updateHardwareRevision();
#endif
如果编译配置中定义了USE_HARDWARE_REVISION_DETECTION,则检测并更新硬件版本信息。
36. 初始化VTX (Initialize VTX)
c
#ifdef USE_VTX_RTC6705
bool useRTC6705 = rtc6705IOInit(vtxIOConfig());
#endif
如果编译配置中定义了USE_VTX_RTC6705,则初始化VTX(视频传输模块)。
37. 初始化相机控制 (Initialize Camera Control)
c
#ifdef USE_CAMERA_CONTROL
cameraControlInit();
#endif
如果编译配置中定义了USE_CAMERA_CONTROL,则初始化相机控制模块。
38. 初始化ADC (Initialize ADC)
c
#ifdef USE_ADC
adcInit(adcConfig());
#endif
如果编译配置中定义了USE_ADC,则初始化ADC(模拟数字转换器)。
39. 初始化板载对齐 (Initialize Board Alignment)
c
initBoardAlignment(boardAlignment());
初始化板载对齐,用于校准飞行控制器的姿态传感器(如加速度计和陀螺仪)。
40. 自动检测传感器 (Auto-Detect Sensors)
c
if (!sensorsAutodetect()) {
if (isSystemConfigured()) {
indicateFailure(FAILURE_MISSING_ACC, 2);
}
setArmingDisabled(ARMING_DISABLED_NO_GYRO);
}
自动检测传感器(如加速度计和陀螺仪)。如果检测失败,则禁用武装,并通过LED指示错误。
41. 设置目标循环时间 (Set Target Loop Time)
c
systemState |= SYSTEM_STATE_SENSORS_READY;
gyroSetTargetLooptime(pidConfig()->pid_process_denom);
validateAndFixGyroConfig();
gyroSetTargetLooptime(pidConfig()->pid_process_denom);
设置系统状态为传感器已准备好,并根据PID配置设置目标循环时间。校验并修正陀螺仪配置,然后再次设置目标循环时间。
42. 初始化传感器校准 (Initialize Sensor Calibration)
c
#ifdef USE_ACC
accStartCalibration();
#endif
gyroStartCalibration(false);
#ifdef USE_BARO
baroStartCalibration();
#endif
根据传感器类型初始化校准过程。如果编译配置中定义了USE_ACC、USE_BARO,则分别初始化加速度计和气压计的校准。
43. 初始化飞行控制模块 (Initialize Flight Control Modules)
c
positionInit();
autopilotInit();
// 更多飞行控制模块初始化...
初始化飞行控制器的各种模块,包括位置初始化、自动驾驶仪初始化等。
44. 初始化VTX控制 (Initialize VTX Control)
c
#ifdef USE_VTX_CONTROL
vtxControlInit();
// 更多VTX模块初始化...
#endif
如果编译配置中定义了USE_VTX_CONTROL,则初始化VTX控制模块。
45. 初始化云台 (Initialize Gimbal)
c
#ifdef USE_GIMBAL
gimbalInit();
#endif
如果编译配置中定义了USE_GIMBAL,则初始化云台模块。
46. 初始化电池监控 (Initialize Battery Monitoring)
c
batteryInit();
初始化电池监控模块,用于监测电池电压和电流等信息。
47. 初始化RC设备 (Initialize RC Devices)
c
#ifdef USE_RCDEVICE
rcdeviceInit();
#endif
如果编译配置中定义了USE_RCDEVICE,则初始化RC设备。
48. 初始化持久化统计数据 (Initialize Persistent Statistics)
c
#ifdef USE_PERSISTENT_STATS
statsInit();
#endif
如果编译配置中定义了USE_PERSISTENT_STATS,则初始化持久化统计数据模块。
49. 初始化MSP (Initialize MSP)
c
mspInit();
mspSerialInit();
初始化MSP(MultiWii Serial Protocol),这是用于与地面站软件进行通信的主要协议。
50. 初始化CMS、显示设备和OSD (Initialize CMS, Display Devices and OSD)
c
#ifdef USE_CMS
cmsInit();
#endif
#if (defined(USE_OSD) || (defined(USE_MSP_DISPLAYPORT) && defined(USE_CMS)))
displayPort_t *osdDisplayPort = NULL;
#endif
#if defined(USE_OSD)
osdDisplayPortDevice_e osdDisplayPortDevice = OSD_DISPLAYPORT_DEVICE_NONE;
// 根据配置选择OSD设备
if (featureIsEnabled(FEATURE_OSD)) {
osdDisplayPortDevice_e device;
// 根据视频系统选择设备
if (vcdProfile()->video_system == VIDEO_SYSTEM_HD) {
device = OSD_DISPLAYPORT_DEVICE_MSP;
} else {
device = osdConfig()->displayPortDevice;
}
// 初始化OSD设备
switch(device) {
case OSD_DISPLAYPORT_DEVICE_AUTO:
FALLTHROUGH;
case OSD_DISPLAYPORT_DEVICE_FRSKYOSD:
osdDisplayPort = frskyOsdDisplayPortInit(vcdProfile()->video_system);
if (osdDisplayPort || device == OSD_DISPLAYPORT_DEVICE_FRSKYOSD) {
osdDisplayPortDevice = OSD_DISPLAYPORT_DEVICE_FRSKYOSD;
break;
}
FALLTHROUGH;
case OSD_DISPLAYPORT_DEVICE_MAX7456:
if (max7456DisplayPortInit(vcdProfile(), &osdDisplayPort) || device == OSD_DISPLAYPORT_DEVICE_MAX7456) {
osdDisplayPortDevice = OSD_DISPLAYPORT_DEVICE_MAX7456;
break;
}
FALLTHROUGH;
case OSD_DISPLAYPORT_DEVICE_MSP:
osdDisplayPort = displayPortMspInit();
if (osdDisplayPort || device == OSD_DISPLAYPORT_DEVICE_MSP) {
osdDisplayPortDevice = OSD_DISPLAYPORT_DEVICE_MSP;
break;
}
FALLTHROUGH;
case OSD_DISPLAYPORT_DEVICE_NONE:
default:
break;
}
// 初始化OSD
osdInit(osdDisplayPort, osdDisplayPortDevice);
if (osdDisplayPortDevice == OSD_DISPLAYPORT_DEVICE_NONE) {
featureDisableImmediate(FEATURE_OSD);
}
}
#endif
#if defined(USE_CMS) && defined(USE_MSP_DISPLAYPORT)
if (!osdDisplayPort) {
cmsDisplayPortRegister(displayPortMspInit());
}
#endif
#ifdef USE_DASHBOARD
if (featureIsEnabled(FEATURE_DASHBOARD)) {
dashboardInit();
// 根据配置显示固定页面或启用页面循环
#ifdef USE_OLED_GPS_DEBUG_PAGE_ONLY
dashboardShowFixedPage(PAGE_GPS);
#else
dashboardResetPageCycling();
dashboardEnablePageCycling();
#endif
}
#endif
#ifdef USE_TELEMETRY
if (featureIsEnabled(FEATURE_TELEMETRY)) {
telemetryInit();
}
#endif
初始化CMS(Configuration Management System)、显示设备和OSD(On-Screen Display)。根据配置选择合适的OSD设备,并初始化。
51. 设置启动保护时间 (Set Boot Grace Time)
c
setArmingDisabled(ARMING_DISABLED_BOOT_GRACE_TIME);
设置启动保护时间,在此期间飞行控制器不会允许武装,以防止启动时的误操作。
52. 启用SPI DMA (Enable SPI DMA)
c
#if defined(USE_SPI) && defined(USE_SPI_DMA_ENABLE_EARLY)
spiInitBusDMA();
#endif
#ifdef USE_MOTOR
motorPostInit();
motorEnable();
#endif
#if defined(USE_SPI) && defined(USE_SPI_DMA_ENABLE_LATE) && !defined(USE_SPI_DMA_ENABLE_EARLY)
spiInitBusDMA();
#endif
根据编译配置启用SPI DMA(直接内存访问)。DMA可以提高数据传输效率。电机的后初始化和启用也需要在此期间进行。
53. 初始化自动驾驶模式 (Initialize Autopilot Modes)
c
#ifdef USE_ALTITUDE_HOLD
altHoldInit();
#endif
#ifdef USE_POSITION_HOLD
posHoldInit();
#endif
如果编译配置中定义了USE_ALTITUDE_HOLD或USE_POSITION_HOLD,则分别初始化高度保持和位置保持模块。
54. 初始化GPS救援 (Initialize GPS Rescue)
c
#ifdef USE_GPS_RESCUE
if (featureIsEnabled(FEATURE_GPS)) {
gpsRescueInit();
}
#endif
如果编译配置中定义了USE_GPS_RESCUE,并且GPS功能已启用,则初始化GPS救援模块。
55. 初始化调试模块 (Initialize Debug Module)
c
debugInit();
初始化调试模块,用于在调试模式下提供更多信息。
56. 初始化未使用的引脚 (Initialize Unused Pins)
c
unusedPinsInit();
初始化未使用的引脚,将其设置为默认状态,避免误操作。
57. 初始化任务调度器 (Initialize Task Scheduler)
c
tasksInit();
初始化任务调度器,用于管理飞行控制器中的各种任务。
58. 设置系统状态为准备就绪 (Set System State to Ready)
c
systemState |= SYSTEM_STATE_READY;
设置系统状态为准备就绪,表示飞行控制器已经成功启动并准备好执行任务。
总结
这段代码的主要功能是对Betaflight飞行控制器进行初始化。它涵盖了从基本的系统配置到各种硬件设备和功能模块的初始化,确保飞行控制器能够正确地读取配置、检测传感器、初始化接收机、电机和其他外设,并准备好在飞行过程中执行各种控制任务。代码中的条件编译宏使得可以根据不同的硬件配置和编译选项启用或禁用相应的初始化逻辑。