移植freeRTOS
1.下载freeRTOS,解压后获取文件夹 FreeRTOSv9.0.0,在项目目录下新建FreeRTOS文件夹,用来存放OS源码。复制 FreeRTOSv9.0.0 下 Source 目录中的全部文件到新建的FreeRTOS文件夹,如图:
2.把 portable\RVDS\ARM_CM4F 中的文件放置在 portable 下,这里选择 portable\MemMang 下的 heap_4 方式放置于 portable 下,删除 portable 下的其余文件:
3.新建 FreeRTOSConfig.h文件,可以从demo中复制,或者自行按需配置,这里作以下配置:
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 0
#define configUSE_QUEUE_SETS 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_APPLICATION_TASK_TAG 0
#define configGENERATE_RUN_TIME_STATS 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION 0
#define configTOTAL_HEAP_SIZE ((size_t)(60*1024))
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif
4.在工程中添加组 FreeRTOS 并加入其源文件,方便修改添加所有头文件的路径。为了方便修改,这里把 FreeRTOSConfig.h 也添加到组内:
5.基本文件已经添加完毕,编译一下。一般会出现SVC_Handler、
SysTick_Handler相关错误,这里没有报,检查了下 n32g45xit.c 里已经修改过:
#if NO_RTOS == 1 void SVC_Handler(void) { } #endif
#if NO_RTOS == 1 void SysTick_Handler(void) { } #endif
6。至此,freertos移植完毕,可自行添加代码测试:
TaskHandle_t StarTaskHandle;
#define starTask_SckDep 60
#define starTask_Prior 3
void SystemStar_Init(void)
{
SetSysClock_HSE_PLL(RCC_PLL_MUL_18);
RCC_ConfigPclk1(RCC_HCLK_DIV4);
ILI9341_Init();
vTaskDelete(StarTaskHandle);
}
TaskHandle_t Task1_TFTColorFill;
#define Task1_SckDep 100
#define Task1_Prior 3
void TFTColorFill()
{
for(;;)
{
lcd_fill(COLOR_YELLOW);
vTaskDelay(1000);
lcd_fill(COLOR_RED);
vTaskDelay(1000);
}
}
int main(void)
{
xTaskCreate((TaskFunction_t)SystemStar_Init,"StarTask",starTask_SckDep,NULL,starTask_Prior,&StarTaskHandle);
xTaskCreate((TaskFunction_t)TFTColorFill,"Task1",Task1_SckDep,NULL,Task1_Prior,&Task1_TFTColorFill);
vTaskStartScheduler();
while(1)
;
}
LVGL移植
首先,下载LVGL源码,
1.在工程中新建LVGL文件夹,从下载文件中找出下列文件并复制到新建文件夹
2.重命名porting下的所有文件,
重命名 lv_conf_template.h 为 lv_conf.h
3.在工程中新建LVGL分组并添加LVGL下所有源文件和配置头文件路径,打开 lv_conf.h,这里把开始几行的if 0改为if 1
#if 1
#ifndef LV_CONF_H
#define LV_CONF_H
#include <stdint.h>
同理,lv_port_disp.c 中改为
#if 1
/*********************
* INCLUDES
*********************/
#include "lv_port_disp.h"
lv_port_disp.h 中改为
#if 1
#ifndef LV_PORT_DISP_H
#define LV_PORT_DISP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "../lvgl/lvgl.h"
4.根据项目需要修改 lv_conf.h,比如分辨率,色深,是否含gpu加速、字体等参数。
5.然后打开 lv_port_disp.c ,这个文件里主要用以实现显示刷新,显存暂时采用方式一:
void lv_port_disp_init(void)
{
disp_init();
static lv_disp_buf_t disp_buf_1;
static lv_color_t buf1_1[LV_HOR_RES_MAX * 40];
lv_disp_buf_init(&disp_buf_1, buf1_1, NULL, LV_HOR_RES_MAX * 40);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
disp_drv.flush_cb = disp_flush;
disp_drv.buffer = &disp_buf_1;
#if LV_USE_GPU
disp_drv.gpu_blend_cb = gpu_blend;
disp_drv.gpu_fill_cb = gpu_fill;
#endif
lv_disp_drv_register(&disp_drv);
}
然后修改 disp_flush 函数:
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
lcd_color_fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)color_p);
lv_disp_flush_ready(disp_drv);
}
最后,把LVGL的心跳绑定到freertos的滴答钩子函数上, 在 FreeRTOSConfig.h 中修改 configUSE_IDLE_HOOK 为 1 ,然后周期调用 lv_task_handler() 函数,代码如下:
void vApplicationTickHook()
{
lv_tick_inc(1);
}
static void MeterDisplay_Init(void)
{
lv_obj_t * scr = lv_scr_act();
static lv_style_t stytle_title;
lv_style_init(&stytle_title);
lv_style_set_text_font(&stytle_title,LV_STATE_DEFAULT,&lv_font_montserrat_14);
lv_obj_t * title = lv_label_create(lv_scr_act(), NULL);
lv_style_list_t * list = lv_obj_get_style_list(title, LV_LABEL_PART_MAIN);
_lv_style_list_add_style(list, &stytle_title);
lv_obj_refresh_style(title, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
lv_label_set_text(title, "testing");
}
TaskHandle_t Task2_LVGLTASK;
#define LVGLTask_Prior (tskIDLE_PRIORITY + 3)
#define LVGLTask_SckDep (512)
void LVGL_TaskHand_Period(void)
{
TickType_t WaitTime;
const TickType_t xPeriod = pdMS_TO_TICKS(5);
WaitTime = xTaskGetTickCount();
lv_init();
lv_port_disp_init();
MeterDisplay_Init();
for( ; ; )
{
vTaskDelayUntil(&WaitTime,xPeriod);
lv_task_handler();
}
}
int Creat_LVGLTask(void)
{
xTaskCreate((TaskFunction_t)LVGL_TaskHand_Period,"LVGLTask",LVGLTask_SckDep,NULL,LVGLTask_Prior,Task2_LVGLTASK);
return 0;
}
main函数调用测试代码:
int main(void)
{
xTaskCreate((TaskFunction_t)SystemStar_Init,"StarTask",starTask_SckDep,NULL,starTask_Prior,&StarTaskHandle);
Creat_LVGLTask();
vTaskStartScheduler();
while(1)
;
}
这里注意下把 StarTask 任务优先级设置最大,ili9431的初始化要先于LVGL初始化运行。
6.现象:
代码:*附件:N32Template.rar