**說明:
本文原創做者『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
後邊就是實際任務函數了,以後再繼續。。隊列