STM32F1 移植 FreeRTOS

--- title: STM32F1 移植 FreeRTOS date: 2020-06-19 07:11:15 categories: tags: - 不做整理的片段(从博文中抽出来的) ---

移植步骤

1、下载FreeRTOS

2、在项目中建立目录freeRTOS

3、将FreeRTOS/Source文件夹转移到项目中的freeRTOS

4、根据平台的不同复制portable文件,拷贝到freeRTOS

  • 源文件port.c拷贝到freeRTOS
  • 头文件portmacro.h拷贝到freeRTOS/include

STM32F103(Cortex-M3)对应的是在portable/RVDS/ARM_CM3

5、工程中添加头文件对应的路径、添加源文件

6、编译,报错说:不能打开FreeRTOSConfig.h头文件。

我们需要到Demo文件夹处找到与我们单片机型号相同或相似的Demo,这里在FreeRTOS/Demo/CORTEX_STM32F103_Keil文件夹内可找到FreeRTOSConfig.h文件

7、编译,提示:

Error: L6218E: Undefined symbol xTaskGetCurrentTaskHandle (referred from stream_buffer.o).

实际上TaskHandle_t xTaskGetCurrentTaskHandle是用于获取当前任务句柄。

在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必须设置为1,此函数才有效。

扫描二维码关注公众号,回复: 11319230 查看本文章

所以只要在FreeRTOSConfig.h中加入这句话即可:

#define INCLUDE_xTaskGetCurrentTaskHandle 1

8、重新编译,提示:

Error: L6218E: Undefined symbol pvPortMalloc (referred from event_groups.o).
Error: L6218E: Undefined symbol vPortFree (referred from event_groups.o).

这是因为我们没有选择堆内存管理方式,portable/MemMang中的每一个文件对应一种方式,拷贝出来,这里选择heap_4.c

9、仿真在线运行,发现调用vTaskStartScheduler进入了HardFault_Handler

需要:修改中断向量指向RTOS-port.c文件中定义函数入口

打开startup_stm32f10x_hd.s文件

__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit
				;添加这3行
                IMPORT xPortPendSVHandler
                IMPORT xPortSysTickHandler
                IMPORT vPortSVCHandler
                ; 结束
                PRESERVE8
                THUMB
                
; 将 SVC_Handler 改为 vPortSVHandler
				;DCD     SVC_Handler                ; SVCall Handler
				DCD     vPortSVCHandler                ; SVCall Handler

; 将 PendSV_Handler 改为 xPortPendSVHandler
				;DCD     PendSV_Handler                ; PendSV Handler
				DCD     xPortPendSVHandler                ; PendSV Handler

; 将 SysTick_Handler 改为 xPortSysTickHandler
				;DCD     SysTick_Handler                ; SysTick Handler
				DCD     xPortSysTickHandler                ; SysTick Handler

简单的例程

下面的代码实现了创建一个任务,并定期打印。

添加下列代码

#if 1 // 使用printf
#include "stdio.h"

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/* 重定向printf*/
PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart2, (uint8_t*)&ch,1,HAL_MAX_DELAY);
    return ch;
}
/* 重定向scanf */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart2, &ch, 1, 0xffff);
  return ch;
}
#endif

#include "FreeRTOS.h"
#include "task.h"

//任务优先级
#define START_TASK_PRIO     1
//任务堆栈大小    
#define START_STK_SIZE      128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters)
{
    while(1)
    {
        vTaskDelay(200);
        printf("start_task\r\n");
    }
}

int main(void)
{
    // HAL_Init(); // 如果Systick没有改为其他时钟源,则运行异常。需要注释掉。
    SystemClock_Config();
    MX_USART2_UART_Init();
    
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

猜你喜欢

转载自www.cnblogs.com/schips/p/13166079.html