乐趣区

MiniFly四轴学习系列2四轴部分main函数

** 说明:
本文原创作者『Allen5G』
首发于微信公众号『Allen5G』, 关注获取更多干货!
标签:编程,软件,算法,思维 **


先看看整个工程的任务关系
手机 APP 是需要自己开发 APP 的,暂时没空搞,坐等官方。。

然后主要就是上位机和遥控器的使用了
上位机通过 USB 连接四轴,需要烧录固件 BootLoader
遥控器使用 NFR 无线通信,这个也是可玩性最高的地方,当然也是最核心的部分 — 姿态解算和姿态控制,之后主要要研究的就是这块代码

整个系统是基于 Freertos 系统,所以函数也是在系统中进行任务切换

看下 main 函数部分:
首先说下代码风格很喜欢,可能是强迫症,注释必须对其

#include "system.h" /* 头文件集合 */

TaskHandle_t startTaskHandle; // 创建句柄
static void startTask(void *arg);// 声明创建函数
int main() // 主函数
{systemInit();           /* 底层硬件初始化 */ 
    xTaskCreate(startTask, "START_TASK", 300, NULL, 2, &startTaskHandle);  /* 创建起始任务 */
    vTaskStartScheduler();  /* 开启任务调度 */
    while(1){};}
/* 创建任务 */
void startTask(void *arg)
{taskENTER_CRITICAL();   /* 进入临界区 */
    
    xTaskCreate(radiolinkTask, "RADIOLINK", 150, NULL, 5, NULL);        /* 创建无线连接任务 */
    
    xTaskCreate(usblinkRxTask, "USBLINK_RX", 150, NULL, 4, NULL);       /* 创建 usb 接收任务 */
    xTaskCreate(usblinkTxTask, "USBLINK_TX", 150, NULL, 3, NULL);       /* 创建 usb 发送任务 */
    
    xTaskCreate(atkpTxTask, "ATKP_TX", 150, NULL, 3, NULL);             /* 创建 atkp 发送任务任务 */
    xTaskCreate(atkpRxAnlTask, "ATKP_RX_ANL", 300, NULL, 6, NULL);      /* 创建 atkp 解析任务 */
    
    xTaskCreate(configParamTask, "CONFIG_TASK", 150, NULL, 1, NULL);    /* 创建参数配置任务 */
    
    xTaskCreate(pmTask, "PWRMGNT", 150, NULL, 2, NULL);                 /* 创建电源管理任务 */
    xTaskCreate(sensorsTask, "SENSORS", 450, NULL, 4, NULL);            /* 创建传感器处理任务 */
    
    xTaskCreate(stabilizerTask, "STABILIZER", 450, NULL, 5, NULL);      /* 创建姿态任务 */
    
    xTaskCreate(wifiLinkTask, "WIFILINK", 150, NULL, 4, NULL);          /* 创建通信连接任务 */
    
    xTaskCreate(expModuleMgtTask, "EXP_MODULE", 150, NULL, 1, NULL);    /* 创建扩展模块管理任务 */    
    
    printf("Free heap: %d bytes\n", xPortGetFreeHeapSize());            /* 打印剩余堆栈大小 */
    
    vTaskDelete(startTaskHandle);                                       /* 删除开始任务 */
        
    taskEXIT_CRITICAL();    /* 退出临界区 */}
void vApplicationIdleHook(void)
{
    static u32 tickWatchdogReset = 0;
    portTickType tickCount = getSysTickCnt();
    if (tickCount - tickWatchdogReset > WATCHDOG_RESET_MS) // 添加独立看门狗
    {
        tickWatchdogReset = tickCount;
        watchdogReset();}
    
    __WFI();    /* 进入低功耗模式 */}

main 函数正常步骤:
先是硬件初始化:基本都是 32 的基础操作,后边看哪部分时涉及到了再说吧!

void systemInit(void)
{
    u8 cnt = 0;
    
    nvicInit();         /* 中断配置初始化 */
    extiInit();         /* 外部中断初始化 */ 
    delay_init(96);     /*delay 初始化 */
    ledInit();          /*led 初始化 */
    ledseqInit();       /*led 灯序列初始化 */
    
    commInit();         /* 通信初始化  STM32 & NRF51822 */
    atkpInit();         /* 传输协议初始化 */
    consoleInit();      /* 打印初始化 */
    printf("<--------------------->\n");
    
    wifiModuleInit();   /*WIFI 模块初始化 */
    configParamInit();  /* 初始化配置参数 */
    pmInit();           /* 电源管理初始化 */
    stabilizerInit();   /* 电机 传感器 PID 初始化 */
    expModuleDriverInit();/* 扩展模块驱动初始化 */
    
    if(systemTest() == true)
    {while(cnt++ < 5)    /* 初始化通过 左上绿灯快闪 5 次 */
        {ledFlashOne(LED_GREEN_L, 50, 50);
        }           
    }else
    {while(1)        /* 初始化错误 右上红灯间隔 1s 快闪 5 次 */
        {if(cnt++ > 4)
            {
                cnt=0;
                delay_xms(1000);
            }
            ledFlashOne(LED_RED_R, 50, 50);     
        }
    }
    
    watchdogInit(WATCHDOG_RESET_MS);    /* 看门狗初始化 */
    
}
static bool systemTest(void)
{
    bool pass = true;
    
    pass &= ledseqTest();
    pass &= pmTest();
    pass &= configParamTest();
    pass &= commTest();
    pass &= stabilizerTest();   
    pass &= watchdogTest();
    
    return pass;
}

之后就是创建任务,一般上系统就是为了减少逻辑难度,看过 APM 飞控的代码也是上了操作系统(NuttX 实时操作系统)
但是上 Freertos 真是第一次,之前也是使用过几次 Freertos,确实是轻量级操作系统,被精简了很多,队列使用体验不是很好,这次被应用到小四轴上,看看实际效果怎么样吧!

后边的创建任务就是调用下面的函数,可以配置优先级及堆栈大小,都是容易忽视的问题!!

然后就是启动任务调度:它会创建一个空闲任务、初始化一些静态变量,最主要的,它会初始化系统节拍定时器并设置好相应的中断,然后启动第一个任务。
大牛分析 FreeRTOS 调度器启动过程分析 :https://blog.csdn.net/zhzht19…
vTaskStartScheduler(); / 开启任务调度/

后边就是实际任务函数了,之后再继续。。

退出移动版