1.下载freeRTOS源码以及HC32L13x工程源码。解压到当前目录
2,新建文件夹命令为HC32L13x_freeRTOS
3.复制HC工程目录下的driver,mcu两个文件夹到HC32L13x_freeRTOS目录下
4.复制HC32L13x_DDL_Rev2.1.0\HC32L13x_DDL_Rev2.1.0\example\gpio\gpio_output目录下的MDK以及source文件夹到HC32L13x_freeRTOS文件夹
5.打开MDK目录,将项目名更改为HC32L13x_freeRTOS,并打开工程,调整到可编译成功。
重新指向目录及头文件目录,编译OK后,开始移植freeRTOS。
6.在HC32L13x_freeRTOS目录下新建文件夹freeRTOS文件夹,用来存放freeRTOS源码,
打开先前下载解码的freeRTOS源码包,进入\FreeRTOSv202212.01\FreeRTOS\Source全部复制到自己工程目录下的HC32L13x_freeRTOS\freeRTOS文件夹下。
7.打开HC32L13x_freeRTOS\freeRTOS\portable目录,将MemMang和RVDS以外的全部删除,
8.打开RVDS目录,将ARM_CM0以外的目录全部删除,只保留ARM_CM0。
9.接下来开始将源码添加到工程。在Groups下新建freeRTOS项,添加将才的freeRTOS源码添加到freeRTOS下。
添加heap_4.c
添加port.c
10.在freeRTOS源码工程demo下随便找个CORTEX_M0的工程,将FreeRTOSConfig.h文件复制到自己工程freeRTOS目录下。、
11,添加头文件引用
12,将ARM Compiler设置为版本5,并编译工程。
13.编译报错提示.\output\release\gpio_output.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by port.o and interrupts_hc32l13x.o).
此时我们将interrupts_hc32l13x.c下的void_sysTick_Handler函数屏蔽。再次编译。
编译提示内存不足
我们修改FreeRTOSConfig.h
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 5*1024 ) )再次编译,
再次报错,提示3个钩子函数没有定义,我们先将宏关闭,
再次编译,没有问题了。
14.接下来创建任务测试
以下是我的FreeRTOSConfig.h配置,main.c里面补充了几个钩子函数:
/*
* FreeRTOS V202212.01
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
//#include "ddl.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* Prevent C code being included by the IAR assembler. */
#ifndef __IASMARM__
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION 1 //抢占式调试开关
#define configUSE_IDLE_HOOK 1 //空闲任务钩子函数
#define configUSE_TICK_HOOK 1 //时间片钩子函数
#define configCPU_CLOCK_HZ (SystemCoreClock ) //CPU主频
#define configTICK_RATE_HZ ((TickType_t ) 1000) //RTOS节拍率 即1秒的中断次数
#define configMAX_PRIORITIES (5) //可使用的最大优先级
#define configMINIMAL_STACK_SIZE ((unsigned short )70) //定义空闲任务使用的堆栈大小
#define configTOTAL_HEAP_SIZE ((size_t ) ( 5*1024 )) //RTOS内核总计可用的有效RAM大小
#define configMAX_TASK_NAME_LEN (12) //任务名最大长度
#define configUSE_TRACE_FACILITY 1 //是否启用可视化跟踪调试
#define configUSE_16_BIT_TICKS 0 //系统节拍计数器的变量类型 0为32位, 1为16位
#define configIDLE_SHOULD_YIELD 1 //空闲任务放弃CPU使用权给其它同优先级的用户任务
#define configUSE_MUTEXES 1 //是否使用互斥信号量
#define configQUEUE_REGISTRY_SIZE 8 //设置可以可以注册的信号量和消息队列个数
#define configCHECK_FOR_STACK_OVERFLOW 2 //堆栈溢出检查 大于0有效
#define configUSE_RECURSIVE_MUTEXES 1 //是否使用递归互斥信号量
#define configUSE_MALLOC_FAILED_HOOK 1 //内存申请失败钩子函数
#define configUSE_APPLICATION_TASK_TAG 0 //为任务分配标签
#define configUSE_COUNTING_SEMAPHORES 1 //是否使用计数信号量
#define configGENERATE_RUN_TIME_STATS 0 //是否启用运行时间统计功能
#define configUSE_QUEUE_SETS 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0 //启用协程,启用协程以后必须添加文件croutine.c
#define configMAX_CO_ROUTINE_PRIORITIES (2) //协程的有效优先级数目
/* Software timer definitions. */
#define configUSE_TIMERS 1 //是否启用软件定时器
#define configTIMER_TASK_PRIORITY ( 2 ) //软件定时器优先级
#define configTIMER_QUEUE_LENGTH 5 //软件定时器队列长度
#define configTIMER_TASK_STACK_DEPTH ( 80 ) //软件定时器任务堆栈大小
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */ //是否启用RTOS API函数
#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
#define INCLUDE_eTaskGetState 1
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
/* Bump up the priority of recmuCONTROLLING_TASK_PRIORITY to prevent false
positive errors being reported considering the priority of other tasks in the
system. */
#define recmuCONTROLLING_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#endif /* FREERTOS_CONFIG_H */
以下为main.c内容
#include "freeRTOS.h"
#include "task.h"
#include "gpio.h"
static TaskHandle_t AppLed_Task = NULL;
static void App_LedInit(void)
{
stc_gpio_cfg_t stcGpioCfg;
///< 打开GPIO外设时钟门控
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
///< 端口方向配置->输出(其它参数与以上(输入)配置参数一致)
stcGpioCfg.enDir = GpioDirOut;
///< 端口上下拉配置->下拉
stcGpioCfg.enPu = GpioPuDisable;
stcGpioCfg.enPd = GpioPdEnable;
///< LED关闭
Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN);
///< GPIO IO LED端口初始化
Gpio_Init(STK_LED_PORT, STK_LED_PIN, &stcGpioCfg);
}
static void led_task(void *param)
{
while(1)
{
///< LED点亮
Gpio_SetIO(STK_LED_PORT, STK_LED_PIN);
vTaskDelay(1000);
///< LED关闭
Gpio_ClrIO(STK_LED_PORT, STK_LED_PIN);
vTaskDelay(1000);
}
}
int32_t main(void)
{
BaseType_t xReturn = pdPASS;
///< LED端口初始化
App_LedInit();
xReturn = xTaskCreate( led_task, "led_task", 128, NULL, 2, &AppLed_Task);
if(xReturn != pdPASS){
return -1;
}
vTaskStartScheduler();
}
//空闲任务钩子函数
void vApplicationIdleHook(void)
{
//空闲时执行这里,在这里做低功耗处理
}
//内存申请失败钩子函数
void vApplicationMallocFailedHook(void)
{
}
//堆栈溢出钩子函数
void vApplicationStackOverflowHook( TaskHandle_t xTask, char * pcTaskName )
{
}
//时间片钩子函数
void vApplicationTickHook(void)
{
}
//守护(daemon)任务启动钩子函数,守护任务也就是定时器服务任务
void vApplicationDaemonTaskStartupHook(void)
{
}