硬件初始化 定义一个bsp_init初始化函数,把初始化外设的函数都放到那里面去,
1 2 3 4 static void BSP_INIT (void ) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_GPIO_Config(); }
创建单任务——SRAM静态内存 静态内存,即预先定义好的全局变量,这些变量保存值内部SRAM中。他们是运行前分配的,之前用ucos是就一直使用的是静态内存,
定义任务函数 任务必须返回值,是死循环,要延时时,要使用freertos提供的延时函数,不能自己写一个for循环延时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 static void LED_Task(void* parameter){ while(1){ LED(ON); vTaskDelay(500); // 延时500个tick LED(OFF); vTaskDelay(500); // 延时500个tick } } 下面这种做法是不对的 /*static void LED_Task(void* parameter){ while(1){ for(i=0; i < 0xfffff; i++){ i++; } LED(ON); for(i=0; i < 0xfffff; i++){ i++; } LED(OFF); } }*/
空闲任务与定时器任务函数 使用静态创建任务时,需要将 configSUPPORT_STATIC_ALLOCATION 置为1,(貌似freertos并不能控制stm32硬件支不支持静态内存,只是对系统做了一个限制)。同时,支持静态内存后,我们还必须为空闲任务(idle)和定时器(timer)分配任务堆栈,不能是动态分配,即需要实现 vApplicationGetIdleTaskMemory 和 vApplicationGetTimerTaskMemory两个函数。代码中有如下解释:
1 2 3 4 5 6 7 #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) extern void vApplicationGetTimerTaskMemory ( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) ; #endif
两个任务实现如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH]; static StaticTask_t Idle_Task_TCB;static StaticTask_t Timer_Task_TCB;void vApplicationGetTimerTaskMemory ( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ) { *ppxTimerTaskTCBBuffer = &Timer_Task_TCB; *ppxTimerTaskStackBuffer = Timer_Task_Stack; *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } void vApplicationGetIdleTaskMemory ( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &Idle_Task_TCB; *ppxIdleTaskStackBuffer = Idle_Task_Stack; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; }
定义任务栈与任务控制块 与ucos极其类似
1 2 3 4 5 6 static StackType_t AppTaskCreate_Stack[configMINIMAL_STACK_SIZE];static StackType_t LED_Task_Stack[configMINIMAL_STACK_SIZE];static StaticTask_t AppTaskCreate_TCB;static StaticTask_t LED_Task_TCB;
静态创建任务 静态任务创建函数——xTaskCreateStatic
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 static void AppTaskCreate (void ) { TaskHandle_t LED_Task_Handle; taskENTER_CRITICAL(); LED_Task_Handle = xTaskCreateStatic((TaskFunction_t)LED_Task, (const char *)"LED_Task" , (uint32_t )configMINIMAL_STACK_SIZE, (void *)NULL , (UBaseType_t)3 , (StackType_t*)LED_Task_Stack, (StaticTask_t*)&LED_Task_TCB); if (NULL != LED_Task_Handle) printf ("LED TASK 任务创建成功" ); else printf ("LED TASK 任务创建失败" ); vTaskDelete(AppTaskCreate_Handle); taskEXIT_CRITICAL(); } int main (void ) { int i = 0 ; TaskHandle_t AppTaskCreate_Handle; BSP_INIT(); AppTaskCreate_Handle = xTaskCreateStatic((TaskFunction_t)AppTaskCreate, (const char *)"AppTaskCreate" , (uint32_t )configMINIMAL_STACK_SIZE, (void *)NULL , (UBaseType_t)3 , (StackType_t*)AppTaskCreate_Stack, (StaticTask_t*)&AppTaskCreate_TCB); if (NULL != AppTaskCreate_Handle) vTaskStartScheduler(); while (1 ); }
创建单任务——SRAM动态内存 动态内存空间的堆来自哪——在SRAM中定义一个大数组,供FreeRTOS的动态分配内存使用,第一次使用时会对堆进行初始化,这些代码在heap_x.c中
1 2 3 4 5 6 7 8 9 10 11 12 1 //系统所有总的堆大小 2 #define configTOTAL_HEAP_SIZE ((size_t)(36*1024)) (1) 3 static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; (2) 4 /* 如果这是第一次调用 malloc 那么堆将需要 5 初始化,以设置空闲块列表。*/ 6 if ( pxEnd == NULL ) 7 { 8 prvHeapInit(); (3) 9 } else 10 { 11 mtCOVERAGE_TEST_MARKER(); 12 }
定义任务函数 与创建静态任务时一致
定义任务控制块指针 不需要预先定义好全局静态的控制块空间,任务创建时任务控制块会自动创建,任务创建函数会返回一个任务控制块指针,所以要预先定义一个任务控制块指针(任务句柄)。