02 Crazyflie Source Preview
Crazyflie源码分析
一、源代码结构
./ | Root, contains the Makefile
+ init | 主文件目录,很简单 Contains the main.c
+ config | 配置文件,包括系统任务配置文件,freertos配置文件, stm32配置文件 Configuration files
+ drivers | 传感器底层访问驱动 Hardware driver layer
| + src | Drivers source code
| + interface | Drivers header files. Interface to the HAL layer
+ hal | 硬件抽象层 Hardware abstraction layer 主要包括sensors
| + src | HAL source code
| + interface | HAL header files. Interface with the other parts of the program
+ modules | 主要飞控代码 Firmware operating code and headers 角度计算 pid 等
| + src | Firmware tasks source code and main.c
| + interface | Operating headers. Configure the firmware environment
+ utils | CRC校验 IIR滤波器等 Utils code. Implement utility block like the console.
| + src | Utils source code
| + interface | Utils header files. Interface with the other parts of the program
+ platform | 平台信息 Platform specific files. Not really used yet
+ tools | Misc. scripts for LD, OpenOCD, make, version control, ...
| | *** The two following folders contains the unmodified files ***
+ lib | Libraries
| + FreeRTOS | Source FreeRTOS folder. Cleaned up from the useless files
| + STM32... | STM32外设库 Library folders of the ST STM32 peripheral libs
| + CMSIS | ARM标准库 Core abstraction layer
二、运行任务
系统启动时主要运行的任务有,adcTask,crtpTxTask,crtpRxTask,eskylinkTask,infoTask,logTask,memTask,paramTask,pmTask,stabilizerTask,syslinkTask,systemTask,prvIdleTask,prvTimerTask和usblinkTask等任务.分析链接
Adc_f103.c (drivers\src): xTaskCreate(adcTask, (const signed char * const)"ADC",
Crtp.c (modules\src): xTaskCreate(crtpTxTask, (const signed char * const)CRTP_TX_TASK_NAME,
Crtp.c (modules\src): xTaskCreate(crtpRxTask, (const signed char * const)CRTP_RX_TASK_NAME,
Eskylink.c (hal\src): xTaskCreate(eskylinkTask, (const signed char * const)ESKYLINK_TASK_NAME,
Info.c (modules\src): xTaskCreate(infoTask, (const signed char * const)"Info",
Log.c (modules\src): xTaskCreate(logTask, (const signed char * const)LOG_TASK_NAME,
Mem.c (modules\src): xTaskCreate(memTask, (const signed char * const)MEM_TASK_NAME,
Nrf24link.c (hal\src): xTaskCreate(nrf24linkTask, (const signed char * const)NRF24LINK_TASK_NAME,
Param.c (modules\src): xTaskCreate(paramTask, (const signed char * const)PARAM_TASK_NAME,
Pidctrl.c (modules\src): xTaskCreate(pidCrtlTask, (const signed char * const)"PIDCrtl",
Pm_f103.c (hal\src): xTaskCreate(pmTask, (const signed char * const)PM_TASK_NAME,
Pm_f405.c (hal\src): xTaskCreate(pmTask, (const signed char * const)PM_TASK_NAME,
Stabilizer.c (modules\src): xTaskCreate(stabilizerTask, (const signed char * const)STABILIZER_TASK_NAME,
Syslink.c (hal\src): if (xTaskCreate(syslinkTask, (const signed char * const)SYSLINK_TASK_NAME,
System.c (modules\src): xTaskCreate(systemTask, (const signed char * const)SYSTEM_TASK_NAME,
Task.h (lib\freertos\include): * Type by which tasks are referenced. For example, a call to xTaskCreate
Task.h (lib\freertos\include): portBASE_TYPE xTaskCreate(
Task.h (lib\freertos\include): * xTaskCreate() can only be used to create a task that has unrestricted
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): * \defgroup xTaskCreate xTaskCreate
Task.h (lib\freertos\include):#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) )
Task.h (lib\freertos\include): * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
Task.h (lib\freertos\include): * At least one task should be created via a call to xTaskCreate ()
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
Task.h (lib\freertos\include): xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
Task.h (lib\freertos\include): * xTaskCreate() and xTaskCreateRestricted() macros.
Tasks.c (lib\freertos): xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle );
Tasks.c (lib\freertos): xReturn = xTaskCreate( prvIdleTask, ( signed char * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL );
Timers.c (lib\freertos): xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
Timers.c (lib\freertos): xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
Usblink.c (hal\src): xTaskCreate(usblinkTask, (const signed char * const)USBLINK_TASK_NAME,
三、源码风格总结
Crazyflie项目中有很多巧妙的类型定义,可以很方便的解决问题,也可能是本人才疏学浅表示第一看看到这么用
1. 两种方式检索同一区域(union)
以下可以实现两种检索方式检索同一片内存区域,可以使用
typedef union {
struct {
float x;
float y;
float z;
};
float axis[3];
} Axis3f;
2. 使用枚举类型计数
以下枚举类型成员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;
3. 紧凑的数据类型
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编译器不是紧凑模式的,我在windows下,用vc的编译器也不是紧凑的,用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
4. git工程中如何引用其他仓库
使用将其他仓库一起clone
git submodule init
git submodule update
5. 在makefile中添加宏定义
在Crazyflie的固件代码中,宏一般都定义在文件Makefile中.可以使用CFLAGS += -D的方式配置固件功能
# Flag that can be added to config.mk
CFLAGS += -DUSE_UART_CRTP # Set CRTP link to UART
CFLAGS += -DUSE_ESKYLINK # Set CRTP link to E-SKY receiver
CFLAGS += -DENABLE_UART # To enable the uart
CFLAGS += -DDEBUG_PRINT_ON_UART # Redirect the console output to the UART
CFLAGS += -DTOSH_DATA_LENGTH=114
相当于编译时
gcc -DTOSH_DATA_LENGTH=114 xx.c
相当于文件中添加
#define TOSH_DATA_LENGTH 114
最后更新于
这有帮助吗?