搭建开发环境

[English]

ESP-IDF 环境搭建

请参照 ESP-IDF 编程指南,按照步骤设置 ESP-IDF。

注意事项:

  • 推荐安装 ESP-IDF release/v4.4 分支;

  • 请完成 ESP-IDF 所有安装步骤;

  • 建议首先编译一个 ESP-IDF 示例程序,用以检查安装的完整性。

获取项目源代码

测试版本代码,目前放在 GitHub 仓库,可使用 git 工具获取:

git clone https://github.com/espressif/esp-drone.git

项目软件主要由飞控内核、硬件驱动和依赖库组成:

  • 飞控内核来自 Crazyflie 开源工程,主要包括硬件抽象层和飞控程序。

  • 硬件驱动按照硬件接口进行了文件结构划分,包括 I2C 设备和 SPI 设备等。

  • 依赖库包括 ESP-IDF 提供的默认组件,以及来自第三方的 DSP 等。

代码文件结构如下所示:

espdrone_file_structure
.
├── components                        | 项目组件目录
│   ├── config                              | 系统 task 配置
│   │   └── include
│   ├── core                                 | 系统内核目录
│   │   └── crazyflie                  | crazyflie 内核
│   │       ├── hal                         | 硬件抽象代码
│   │       └── modules             |  飞行控制代码
│   ├── drivers                            | 硬件驱动目录
│   │   ├── deck                         | 硬件扩展接口驱动
│   │   ├── general                    | 一般设备目录
│   │   │   ├── adc                     | ADC 驱动,用于电压监测
│   │   │   ├── buzzer              | 蜂鸣器驱动,用于状态反馈
│   │   │   ├── led                     | LED 驱动,用于状态反馈
│   │   │   ├── motors             | 电机驱动,用于推力输出
│   │   │   └── wifi                    | Wi-Fi 驱动,用于通信
│   │   ├── i2c_bus                   | I2C 驱动
│   │   ├── i2c_devices           | I2C 设备目录
│   │   │   ├── eeprom           | eeprom 驱动,用于参数存储
│   │   │   ├── hmc5883l         | hmc5883l 磁罗盘传感器
│   │   │   ├── mpu6050          | mpu6050 陀螺仪加速度计传感器
│   │   │   ├── ms5611             | ms5611 气压传感器
│   │   │   ├── vl53l0                 | Vl53l0 激光传感器(最大测距 2 m)
│   │   │   └── vl53l1                 |  Vl53l1 激光传感器(最大测距 4 m)
│   │   └── spi_devices           | SPI 设备目录
│   │       └── pmw3901           | pmw3901 光流传感器
│   ├── lib                                      | 外部库目录
│   │   └── dsp_lib                    | dsp 库
│   ├── platform                         | 用于支持多平台
│   └── utils                                  | 工具函数目录
├── CMakeLists.txt                    | 工具函数
├── LICENSE                                | 开源协议
├── main                                       | 入口函数
├── README.md                        | 项目说明
└── sdkconfig.defaults            | 默认参数

详情可查阅espdrone_file_structure

源代码风格

两种方式检索同一区域(union)

实现两种检索方式检索同一片内存区域,可以使用:

typedef union {
  struct {
        float x;
        float y;
        float z;
  };
  float axis[3];
} Axis3f;

使用枚举类型计数

以下枚举类型成员 SensorImplementation_COUNT,始终可以代表枚举类型中成员的个数。巧妙利用了枚举类型第一个成员默认为 0 的特点。

typedef enum {
  #ifdef SENSOR_INCLUDED_BMI088_BMP388
  SensorImplementation_bmi088_bmp388,
  #endif

  #ifdef SENSOR_INCLUDED_BMI088_SPI_BMP388
  SensorImplementation_bmi088_spi_bmp388,
  #endif

  #ifdef SENSOR_INCLUDED_MPU9250_LPS25H
  SensorImplementation_mpu9250_lps25h,
  #endif

  #ifdef SENSOR_INCLUDED_MPU6050_HMC5883L_MS5611
  SensorImplementation_mpu6050_HMC5883L_MS5611,
  #endif

  #ifdef SENSOR_INCLUDED_BOSCH
  SensorImplementation_bosch,
  #endif

  SensorImplementation_COUNT,
} SensorImplementation_t;

紧凑的数据类型

struct cppmEmuPacket_s {
  struct {
      uint8_t numAuxChannels : 4;   // Set to 0 through MAX_AUX_RC_CHANNELS
      uint8_t reserved : 4;
  } hdr;
  uint16_t channelRoll;
  uint16_t channelPitch;
  uint16_t channelYaw;
  uint16_t channelThrust;
  uint16_t channelAux[MAX_AUX_RC_CHANNELS];
} __attribute__((packed));

__attribute__((packed)) 的作用是:使编译器取消结构在编译过程中的优化对齐,而按照实际占用字节数进行对齐。这是 GCC 特有的语法,与操作系统无关,与编译器有关。GCC 和 VC(在 Windows 下)的编译器为非紧凑模式,TC 的编译器为紧凑模式。例如:

在 TC 下:struct my{ char ch; int a;} sizeof(int)=2;sizeof(my)=3;(紧凑模式)
在 GCC 下:struct my{ char ch; int a;} sizeof(int)=4;sizeof(my)=8;(非紧凑模式)
在 GCC 下:struct my{ char ch; int a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5