• 兆易创新GD32 (四)FreeRTOS 移植 与 CMSIS OS2


    可以完全参考STM32系列的方法
    FreeRTOS 逛网下载 FreeRTOS源码
    https://www.freertos.org/a00104.html
    GitHub地址
    https://github.com/FreeRTOS/FreeRTOS-Kernel
    下载后的FreeRTOS-Kernel复制到LIB文件夹下
    在这里插入图片描述
    在KEIL中添加文件,首先是公共部分
    在这里插入图片描述
    添加MDK移植文件CM4F ,F代表浮点运算单元 。R在这里插入图片描述

    然后添加heep4

    在这里插入图片描述

    编译后提示错误
    在这里插入图片描述
    .\Objects\gd32_prj.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).

    Hook是钩子文件是在一定的流程下空出一个位置,用户可以加入代码去增加调试信息。
    正常情况下是不需要的在FreeRTOSConfig.h 中搜索HOOK,把对应的define关掉
    #define configUSE_IDLE_HOOK 0
    #define configUSE_TICK_HOOK 0
    #define configUSE_MALLOC_FAILED_HOOK 0
    还有一个堆栈溢出检测的HOOK
    #define configCHECK_FOR_STACK_OVERFLOW 0
    在这里插入图片描述
    到此编译成功
    文件目录如下,LIB全是GD32标准库和S启动文件
    在这里插入图片描述

    从新编辑一下main.c
    使用FreeRTOS延时来闪烁LED灯

    #include "gd32f4xx.h"
    #include "FreeRTOS.h"
    #include "task.h"
    
    void AppLedinit(void)
    {
    	rcu_periph_clock_enable(RCU_GPIOC);
    	
    	gpio_mode_set(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_PIN_0);
    	
    	gpio_output_options_set(GPIOC,GPIO_OTYPE_PP,GPIO_OSPEED_25MHZ,GPIO_PIN_0);
    }
    void testTask( void *pvParameters )
    {
    	while(1)
    	{
    		gpio_bit_toggle(GPIOC,GPIO_PIN_0);
    		vTaskDelay(1000);
    	}
    }
    int main(void)
    {
       
    	
    	AppLedinit();
    	/* Start the tasks defined within this file/specific to this demo. */
    	xTaskCreate( testTask, "testTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL );
    
    
    	/* Start the scheduler. */
    	vTaskStartScheduler();
    
    	/* Will only get here if there was not enough heap space to create the
    	idle task. */
    	return 0;
    }
    
    	
    	
    	
    
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    ARM Cortex™ 微控制器软件接口标准(CMSIS:Cortex Microcontroller Software Interface Standard) 是 Cortex-M 处理器系列的与供应商无关的硬件抽象层(英文原文为:a vendor-independent hardware abstraction layer for the Cortex-M processor series and defines generic tool interfaces–来自ARM官方定义)。 使用CMSIS,可以为处理器和外设实现一致且简单的软件接口,从而简化软件的重用、缩短微控制器新开发人员的学习过程,并缩短新设备的上市时间。软件的创建被嵌入式行业公认为主要成本系数。通过在所有Cortex-M 芯片供应商产品中标准化软件接口,这一成本会明显降低,尤其是在创建新项目或将现有软件迁移到新设备时

    RTOS系统现在的种类可以说是五花八门,国内就有很多加,国外就不用说了,每家都有自己的API,所以ARM对RTOS的API做了一个统一的命名规则,在各家的RTOS上包了一层,统一了访问接口

    Github 文件地址
    https://github.com/ARM-software/CMSIS-FreeRTOS
    在这里插入图片描述
    复制include和Source到工程目录
    打开,Example 工程,其主要的C文件如下红框所示
    在这里插入图片描述
    在我们的工程目录下,添加这两个C文件,并且包含相应的头文件目录
    在这里插入图片描述
    编译工程,报错。我们回到官方例程中查找一下h文件的目录,复制到本项目中

    在这里插入图片描述
    其目录位于ARM CMSIS Packs 复制到工程目录
    在这里插入图片描述
    再次编译,还是会报错找不到h文件按照这个方法补全h文件

    直到RTE_Components.h
    我当前用的是F450是属于ARMCM4_FP
    #define CMSIS_device_header “ARMCM4_FP.h”
    并且注释调最后的EVENTRECODER

    编译后报错
    …\LIB\CMSIS_OS\Include\freertos_os2.h(126): error: #35: #error directive: “Definition INCLUDE_xSemaphoreGetMutexHolder must equal 1 to implement Mutex Management API.”

    FreeRTOSConfig.h中按照官方CMSIS例程FreeRTOSConfig.h中的配置更改

    #define configCPU_CLOCK_HZ                      (SystemCoreClock)
    #define configSUPPORT_STATIC_ALLOCATION         1
    #define configSUPPORT_DYNAMIC_ALLOCATION        1
    #define configUSE_PREEMPTION                    1
    #define configUSE_TIMERS                        1
    #define configUSE_MUTEXES                       1
    #define configUSE_RECURSIVE_MUTEXES             1
    #define configUSE_COUNTING_SEMAPHORES           1
    #define configUSE_TASK_NOTIFICATIONS            1
    #define configUSE_TRACE_FACILITY                1
    #define configUSE_16_BIT_TICKS                  0
    #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
    #define configMAX_PRIORITIES                    56
    #define configKERNEL_INTERRUPT_PRIORITY         255
    
    
    
    #define INCLUDE_xEventGroupSetBitsFromISR       1
    #define INCLUDE_xSemaphoreGetMutexHolder        1
    #define INCLUDE_vTaskDelay                      1
    #define INCLUDE_xTaskDelayUntil                 1
    #define INCLUDE_vTaskDelete                     1
    #define INCLUDE_xTaskGetCurrentTaskHandle       1
    #define INCLUDE_xTaskGetSchedulerState          1
    #define INCLUDE_uxTaskGetStackHighWaterMark     1
    #define INCLUDE_uxTaskPriorityGet               1
    #define INCLUDE_vTaskPrioritySet                1
    #define INCLUDE_eTaskGetState                   1
    #define INCLUDE_vTaskSuspend                    1
    #define INCLUDE_xTimerPendFunctionCall          1
    
    • 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

    __WEAK 报错改为__weak

    FreertosConfig.h注释掉 //#define xPortSysTickHandler SysTick_Handler

    修改一下main.c

    #include "gd32f4xx.h"
    #include "FreeRTOS.h"
    #include "task.h"
    #include "cmsis_os2.h"
    void AppLedinit(void)
    {
    	rcu_periph_clock_enable(RCU_GPIOC);
    	
    	gpio_mode_set(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_PIN_0);
    	
    	gpio_output_options_set(GPIOC,GPIO_OTYPE_PP,GPIO_OSPEED_25MHZ,GPIO_PIN_0);
    }
    void testTask( void *pvParameters )
    {
    	while(1)
    	{
    		gpio_bit_toggle(GPIOC,GPIO_PIN_0);
    		vTaskDelay(1000);
    	}
    }
    int main(void)
    {
       
    	
    	AppLedinit();
    	osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */
    	
    	/* Start the tasks defined within this file/specific to this demo. */
    	xTaskCreate( testTask, "testTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL );
    
    
    	/* Start the scheduler. */
    	//vTaskStartScheduler();
        osKernelStart();
    	/* Will only get here if there was not enough heap space to create the
    	idle task. */
    	return 0;
    }
    
    	
    	
    	
    
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
  • 相关阅读:
    TorchScript 解读(三):jit 中的 subgraph rewriter
    几个Web自动化测试框架的比较:Cypress、Selenium和Playwright
    IDEA PermGen space内存溢出
    企业为什么要上OA?
    合合TextIn - 大模型加速器
    MySQL的事务
    白银实时价格应该在最适合的地方下注
    vue多种实现动画效果分享【推荐学习】
    Java Dalesbred库访问数据库
    Redis实战篇一 (短信登录)
  • 原文地址:https://blog.csdn.net/denghuajing/article/details/128049475