**说明:
本文原创做者『Allen5G』
首发于微信公众号『Allen5G』,关注获取更多干货!
标签:编程,软件,算法,思惟**算法
先看看整个工程的任务关系
手机APP是须要本身开发APP的,暂时没空搞,坐等官方。。编程
而后主要就是上位机和遥控器的使用了
上位机经过USB链接四轴,须要烧录固件BootLoader
遥控器使用NFR无线通讯,这个也是可玩性最高的地方,固然也是最核心的部分---姿态解算和姿态控制,以后主要要研究的就是这块代码微信
整个系统是基于Freertos系统,因此函数也是在系统中进行任务切换函数
看下main函数部分:
首先说下代码风格很喜欢,多是强迫症,注释必须对其spa
#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,确实是轻量级操做系统,被精简了不少,队列使用体验不是很好,此次被应用到小四轴上,看看实际效果怎么样吧!.net
后边的建立任务就是调用下面的函数,能够配置优先级及堆栈大小,都是容易忽视的问题!!code
而后就是启动任务调度:它会建立一个空闲任务、初始化一些静态变量,最主要的,它会初始化系统节拍定时器并设置好相应的中断,而后启动第一个任务。
大牛分析 FreeRTOS调度器启动过程分析:https://blog.csdn.net/zhzht19...
vTaskStartScheduler(); /开启任务调度/blog
后边就是实际任务函数了,以后再继续。。队列