今天,准备在Linux子系统下将FreeRTOS移植到STM32F103ZET6的板子上。初步需求为,在FreeRTOS下创建两个任务,分别控制LED1、LED2交替闪烁。
首先,创建项目根目录TestFreeos文件夹,在TestFreeos目录下创建其他子目录,具体结构如下:
将Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c文件复制到TestFreeos/Drv/Bsp/Core/src目录下。
将Libraries/STM32F10x_StdPeriph_Driver/src/misc.c文件复制到TestFreeos/Drv/Bsp/Core /src目录下。再将STM32F10x_StdPeriph_Lib_V3.5.0中的相关头文件core_cm3.h、misc.h、srm32f10x.h、stm32f10x_conf.h、system_stm32f10x.h复制到TestFreeos/Drv/Bsp/Core/inc目录下。
在这里,使用的FreeRTOS版本为10.3.1。从FreeRTOS官方网站上将FreeRTOSv10.3.1下载到本地并解压。
将FreeRTOSv10.3.1文件夹中的FreeRTOS/Source/portable/GCC/ARM_CM3/port.c文件复制到TestFreeos/Drv/Rtos/Portable/src目录下。
将FreeRTOSv10.3.1文件夹中的FreeRTOS/Source/portable/MemMang/heap_4.c文件复制到TestFreeos/Drv/Rtos/Portable/src目录下。
将FreeRTOSv10.3.1文件夹中的FreeRTOS/Source目录下的croutine.c、event_groups.c、list.c、queue.c、tasks.c、timers.c文件复制到TestFreeos/Drv/Rtos/Core/src目录下。
将FreeRTOSv10.3.1文件夹中的FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h文件复制到TestFreeos/Drv/Rtos/Portable/inc目录下。
将FreeRTOSv10.3.1文件夹中的FreeRTOS/Source/include目录下的croutine.h、queue.h、deprecated_definitions.h、event_groups.h、FreeRTOS.h、list.h、mpu_wrappers.h、task.h、portable.h、projdefs.h、stack_macros.h、timers.h头文件复制到TestFreeos/Drv/Rtos/Core/inc目录下。
同时将FreeRTOSv10.3.1/FreeRTOS/Demo/CORTEX_STM32F103_Primer_GCC目录下的FreeRTOSConfig.h文件复制到TestFreeos/Drv/Rtos/Core/inc目录下。
在TestFreeos/Drv/Bsp/User/src目录下创建系统时钟驱动drv_sys_clock.c、外设时钟驱动drv_peripheral_clock.c、NVIC驱动drv_nvic.c、GPIO驱动drv_gpio.c以及LED驱动drv_led.c,在TestFreeos/Drv/Bsp/User/inc目录下创建系统时钟驱动头文件drv_sys_clock.h、外设时钟驱动头文件drv_peripheral_clock.h、NVIC驱动头文件drv_nvic.h、GPIO驱动头文件drv_gpio.h、以及LED驱动头文件drv_led.h。
drv_sys_clock.c文件内容如下:
/******************************************************************************
*
* @FileName : drv_sys_clock.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv File of the System Clock for TestFreeos
*
*
******************************************************************************/
#include "drv_sys_clock.h"
#include "stm32f10x.h"
#include "misc.h"
#include "FreeRTOS.h"
#include "task.h"
static uint8_t fac_us=0;
static uint16_t fac_ms=0;
extern void xPortSysTickHandler(void);
/*******************************************************
*
* Function name : SysTick_Handler
* Description : The Handler of SysTick
* Parameter : NULL
* Return : NULL
**********************************************************/
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
}
/*******************************************************
*
* Function name : drv_sys_tick_init
* Description : init the SysTick
* Parameter : NULL
* Return : NULL
**********************************************************/
void drv_sys_tick_init(void)
{
uint32_t reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
fac_us=SystemCoreClock/1000000;
reload=SystemCoreClock/1000000;
reload*=1000000/configTICK_RATE_HZ;
fac_ms=1000/configTICK_RATE_HZ;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
}
/*******************************************************
*
* Function name : drv_delay_us
* Description : Delay the timer with us
* Parameter : @nus Microsecond
* Return : NULL
**********************************************************/
void drv_delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told,tnow,tcnt=0;
uint32_t reload=SysTick->LOAD;
ticks=nus*fac_us;
told=SysTick->VAL;
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)
{
tcnt+=told-tnow;
}
else
{
tcnt+=reload-tnow+told;
}
told=tnow;
if(tcnt>=ticks)
{
break;
}
}
}
}
/*******************************************************
*
* Function name : drv_delay_ms
* Description : Delay the timer with ms By FreeRtos
* Parameter : @nms Msec
* Return : NULL
**********************************************************/
void drv_delay_ms(uint32_t nms)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
if(nms>=fac_ms)
{
vTaskDelay(nms/fac_ms);
}
nms%=fac_ms;
}
drv_delay_us((uint32_t)(nms*1000));
}
/*******************************************************
*
* Function name : drv_delay_xms
* Description : Delay the timer with ms
* Parameter : @nms Msec
* Return : NULL
**********************************************************/
void drv_delay_xms(uint32_t nms)
{
uint32_t i;
for(i=0;i<nms;i++)
{
drv_delay_us(1000);
}
}
drv_sys_clock.h文件内容如下:
/******************************************************************************
*
* @FileName : drv_sys_clock.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv Header File of the System Clock for TestFreeos
*
*
******************************************************************************/
#ifndef __DRV_SYS_CLOCK_H__
#define __DRV_SYS_CLOCK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void drv_sys_tick_init(void);
void drv_delay_us(uint32_t nus);
void drv_delay_ms(uint32_t nms);
void drv_delay_xms(uint32_t nms);
#ifdef __cplusplus
}
#endif
#endif
drv_peripheral_clock.c文件内容如下:
******************************************************************************
*
* @FileName : drv_peripheral_clock.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv File of the Peripheral clock for TestFreeos
*
*
******************************************************************************/
#include "drv_peripheral_clock.h"
#include "stm32f10x.h"
/*******************************************************
*
* Function name : drv_peripheral_clock_config_gpio
* Description : Config the peripheral clock of gpio
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_peripheral_clock_config_gpio(void)
{
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPFEN;
RCC->APB2ENR |= RCC_APB2ENR_IOPGEN;
}
drv_peripheral_clock.h文件内容如下:
/******************************************************************************
*
* @FileName : drv_peripheral_clock.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv Header File of the Peripheral clock for TestFreeos
*
*
******************************************************************************/
#ifndef __DRV_PERIPHERAL_CLOCK_H__
#define __DRV_PERIPHERAL_CLOCK_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void drv_peripheral_clock_config_gpio(void);
#ifdef __cplusplus
}
#endif
#endif
drv_nvic.c文件内容如下:
/******************************************************************************
*
* @FileName : drv_nvic.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv File of the NVIC for TestFreeos
*
*
******************************************************************************/
#include "drv_nvic.h"
#include "misc.h"
/*******************************************************
*
* Function name : drv_nvic_config_group
* Description : Config the PriorityGroup is 16
* Parameter : NULL
* Return : NULL
**********************************************************/
void drv_nvic_config_group(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
}
drv_nvic.h文件内容如下:
/******************************************************************************
*
* @FileName : drv_nvic.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv Header File of the NVIC for TestFreeos
*
*
******************************************************************************/
#ifndef __DRV_NVIC_H__
#define __DRV_NVIC_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void drv_nvic_config_group(void);
#ifdef __cplusplus
}
#endif
#endif
drv_gpio.c文件内容如下:
******************************************************************************
*
* @FileName : drv_gpio.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv File of the Gpio for TestFreeos
*
*
******************************************************************************/
#include "drv_gpio.h"
#include "stm32f10x.h"
/*******************************************************
*
* Function name : drv_gpio_config_led
* Description : Config the gpio of led
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_gpio_config_led(void)
{
GPIOE->CRL &= ~(GPIO_CRL_CNF2 | GPIO_CRL_MODE2 | GPIO_CRL_CNF3 | GPIO_CRL_MODE3) ;
GPIOE->CRL |= (GPIO_CRL_MODE2 | GPIO_CRL_MODE3);
}
/*******************************************************
*
* Function name : drv_gpio_set_led1_low
* Description : set the gpio of led1 to low
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_gpio_set_led1_low(void)
{
GPIOE->BSRR |= GPIO_BSRR_BR2;
}
/*******************************************************
*
* Function name : drv_gpio_set_led1_high
* Description : set the gpio of led1 to high
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_gpio_set_led1_high(void)
{
GPIOE->BSRR |= GPIO_BSRR_BS2;
}
/*******************************************************
*
* Function name : drv_gpio_get_led1
* Description : get the gpio level state of led1
* Parameter :NULL
* Return :the led1 level value
**********************************************************/
uint8_t drv_gpio_get_led1(void)
{
return (GPIOE->ODR & GPIO_ODR_ODR2);
}
/*******************************************************
*
* Function name : drv_gpio_set_led2_low
* Description : set the gpio of led2 to low
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_gpio_set_led2_low(void)
{
GPIOE->BSRR |= GPIO_BSRR_BR3;
}
/*******************************************************
*
* Function name : drv_gpio_set_led2_high
* Description : set the gpio of led2 to high
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_gpio_set_led2_high(void)
{
GPIOE->BSRR |= GPIO_BSRR_BS3;
}
/*******************************************************
*
* Function name : drv_gpio_get_led2
* Description : get the gpio level state of led2
* Parameter :NULL
* Return :the led2 level value
**********************************************************/
uint8_t drv_gpio_get_led2(void)
{
return (GPIOE->ODR & GPIO_ODR_ODR3);
}
drv_gpio.h文件内容如下:
/******************************************************************************
*
* @FileName : drv_gpio.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv Header File of the Gpio for TestFreeos
*
*
******************************************************************************/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// GPIO Operation of LED
void drv_gpio_config_led(void);
void drv_gpio_set_led1_low(void);
void drv_gpio_set_led1_high(void);
uint8_t drv_gpio_get_led1(void);
void drv_gpio_set_led2_low(void);
void drv_gpio_set_led2_high(void);
uint8_t drv_gpio_get_led2(void);
#ifdef __cplusplus
}
#endif
#endif
drv_led.c文件内容如下:
/******************************************************************************
*
* @FileName : drv_led.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv File of the LED for TestFreeos
*
*
******************************************************************************/
#include "drv_led.h"
#include "drv_gpio.h"
/*******************************************************
*
* Function name : drv_led_init
* Description : Init the led
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led_init(void)
{
drv_gpio_config_led();
}
/*******************************************************
*
* Function name : drv_led1_off
* Description : Power off the led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led1_off(void)
{
drv_gpio_set_led1_high();
}
/*******************************************************
*
* Function name : drv_led1_on
* Description : Power on the led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led1_on(void)
{
drv_gpio_set_led1_low();
}
/*******************************************************
*
* Function name : drv_led1_changed
* Description : Changed the state of led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led1_changed(void)
{
if(drv_gpio_get_led1() != 0x00)
{
drv_gpio_set_led1_low();
}
else
{
drv_gpio_set_led1_high();
}
}
/*******************************************************
*
* Function name : drv_led2_off
* Description : Power off the led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led2_off(void)
{
drv_gpio_set_led2_high();
}
/*******************************************************
*
* Function name : drv_led2_on
* Description : Power on the led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led2_on(void)
{
drv_gpio_set_led2_low();
}
/*******************************************************
*
* Function name : drv_led2_changed
* Description : Changed the state of led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void drv_led2_changed(void)
{
if(drv_gpio_get_led2() != 0x00)
{
drv_gpio_set_led2_low();
}
else
{
drv_gpio_set_led2_high();
}
}
drv_led.h文件内容如下:
/******************************************************************************
*
* @FileName : drv_led.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Drv Header File of the LED for RoboticArm
*
*
******************************************************************************/
#ifndef __DRV_LED_H__
#define __DRV_LED_H__
#ifdef __cplusplus
extern "C" {
#endif
void drv_led_init(void);
void drv_led1_off(void);
void drv_led1_on(void);
void drv_led1_changed(void);
void drv_led2_off(void);
void drv_led2_on(void);
void drv_led2_changed(void);
#ifdef __cplusplus
}
#endif
#endif
在TestFreeos/Hal/src目录下创建bsp中间层文件hal_bsp.c、LED中间层文件hal_led.c,在TestFreeos/Hal/inc目录下创建bsp中间层头文件hal_bsp.h、LED中间层头文件hal_led.h。
hal_bsp.c文件内容如下:
/******************************************************************************
*
* @FileName : hal_bsp.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-19
*
* @Description : The Hal Header File of the BSP for RoboticArm
*
*
******************************************************************************/
#include "hal_bsp.h"
#include "hal_led.h"
#include "drv_nvic.h"
#include "drv_peripheral_clock.h"
#include "drv_sys_clock.h"
void bsp_init(void)
{
drv_sys_tick_init();
drv_nvic_config_group();
drv_peripheral_clock_config_gpio();
led_init();
}
hal_bsp.h文件内容如下:
/******************************************************************************
*
* @FileName : hal_bsp.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-19
*
* @Description : The Hal Header File of the BSP for TestFreeos
*
*
******************************************************************************/
#ifndef __HAL_BSP_H__
#define __HAL_BSP_H__
#ifdef __cplusplus
extern "C" {
#endif
void bsp_init();
#ifdef __cplusplus
}
#endif
#endif
hal_led.c文件内容如下:
/******************************************************************************
*
* @FileName : hal_led.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Hal File of the LED for RoboticArm
*
*
******************************************************************************/
#include "hal_led.h"
#include "drv_led.h"
/*******************************************************
*
* Function name : led_init
* Description : Config the gpio of led
* Parameter :NULL
* Return :NULL
**********************************************************/
void led_init(void)
{
drv_led_init();
}
/*******************************************************
*
* Function name : led1_off
* Description : Power off the led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void led1_off(void)
{
drv_led1_off();
}
/*******************************************************
*
* Function name : led1_on
* Description : Power on the led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void led1_on(void)
{
drv_led1_on();
}
/*******************************************************
*
* Function name : led1_changed
* Description : Changed the state of led1
* Parameter :NULL
* Return :NULL
**********************************************************/
void led1_changed(void)
{
drv_led1_changed();
}
/*******************************************************
*
* Function name : led2_off
* Description : Power off the led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void led2_off(void)
{
drv_led2_off();
}
/*******************************************************
*
* Function name : led2_on
* Description : Power on the led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void led2_on(void)
{
drv_led2_on();
}
/*******************************************************
*
* Function name : led2_changed
* Description : Changed the state of led2
* Parameter :NULL
* Return :NULL
**********************************************************/
void led2_changed(void)
{
drv_led2_changed();
}
hal_led.h文件内容如下:
/******************************************************************************
*
* @FileName : hal_led.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The Hal Header File of the LED for TestFreeos
*
*
******************************************************************************/
#ifndef __HAL_LED_H__
#define __HAL_LED_H__
#ifdef __cplusplus
extern "C" {
#endif
void led_init(void);
void led1_off(void);
void led1_on(void);
void led1_changed(void);
void led2_off(void);
void led2_on(void);
void led2_changed(void);
#ifdef __cplusplus
}
#endif
#endif
在TestFreeos/App/src目录下创建低任务应用文件app_task_low.c、中任务应用文件app_task_mid.c、任务启动文件app_task_start.c文件以及MAIN函数文件app_main.c。
在TestFreeos/App/inc目录下创建低任务应用头文件app_task_low.h、中任务应用头文件app_task_mid.h、任务启动头文件app_task_start.h文件。
app_task_low.c文件内容如下:
/******************************************************************************
*
* @FileName : app_task_low.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App File of the Task by Low for TestFreeos
*
*
******************************************************************************/
#include "app_task_low.h"
#include "hal_led.h"
#include "FreeRTOS.h"
#include "task.h"
#define LOW_TASK_PRIO 2
#define LOW_STK_SIZE 128
TaskHandle_t app_low_task_handler;
/*******************************************************
*
* Function name : app_low_task
* Description : low task of app
* Parameter : NULL
* Return : NULL
**********************************************************/
void app_low_task(void *pvParameters)
{
while(1)
{
led1_changed();
vTaskDelay(500);
}
}
/*******************************************************
*
* Function name : app_create_low_task
* Description : create the app task of low
* Parameter : NULL
* Return : NULL
**********************************************************/
void app_create_low_task(void)
{
xTaskCreate((TaskFunction_t ) app_low_task,
(const char* )"low task",
(uint16_t )LOW_STK_SIZE,
(void* )NULL,
(UBaseType_t )LOW_TASK_PRIO,
(TaskHandle_t* )&app_low_task_handler);
}
app_task_low.h文件内容如下:
/******************************************************************************
*
* @FileName : app_task_low.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App Header File of the Task by Low for TestFreeos
*
*
******************************************************************************/
#ifndef __APP_TASK_LOW_H__
#define __APP_TASK_LOW_H__
#ifdef __cplusplus
extern "C" {
#endif
void app_create_low_task(void);
#ifdef __cplusplus
}
#endif
#endif
app_task_mid.c文件内容如下:
/******************************************************************************
*
* @FileName : app_task_mid.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App File of the Task by Mid for TestFreeos
*
*
******************************************************************************/
#include "app_task_mid.h"
#include "hal_led.h"
#include "FreeRTOS.h"
#include "task.h"
#define MID_TASK_PRIO 3
#define MID_STK_SIZE 128
TaskHandle_t app_mid_task_handler;
/*******************************************************
*
* Function name : app_mid_task
* Description : mid task of app
* Parameter : NULL
* Return : NULL
**********************************************************/
void app_mid_task(void *pvParameters)
{
while(1)
{
led2_changed();
vTaskDelay(500);
}
}
/*******************************************************
*
* Function name : app_create_mid_task
* Description : create the app task of mid
* Parameter : NULL
* Return : NULL
**********************************************************/
void app_create_mid_task(void)
{
xTaskCreate((TaskFunction_t ) app_mid_task,
(const char* )"low task",
(uint16_t )MID_STK_SIZE,
(void* )NULL,
(UBaseType_t )MID_TASK_PRIO,
(TaskHandle_t* )&app_mid_task_handler);
}
app_task_mid.h文件内容如下:
******************************************************************************
*
* @FileName : app_task_mid.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App Header File of the Task by Mid for TestFreeos
*
*
******************************************************************************/
#ifndef __APP_TASK_MID_H__
#define __APP_TASK_MID_H__
#ifdef __cplusplus
extern "C" {
#endif
void app_create_task_mid(void);
#ifdef __cplusplus
}
#endif
#endif
app_task_start.c文件内容如下:
/******************************************************************************
*
* @FileName : app_task_start.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App File of the Start Task for RoboticArm
*
*
******************************************************************************/
#include "app_task_start.h"
#include "app_task_low.h"
#include "app_task_mid.h"
#include "FreeRTOS.h"
#include "task.h"
#define START_TASK_PRIO 1
#define START_STK_SIZE 512
TaskHandle_t start_task_handler;
/*******************************************************
*
* Function name : start_task
* Description : the the task of start
* Parameter :NULL
* Return :NULL
**********************************************************/
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
app_create_low_task();
app_create_mid_task();
vTaskDelete(start_task_handler);
taskEXIT_CRITICAL();
}
/*******************************************************
*
* Function name : app_create_start_task
* Description : create the task of start
* Parameter :NULL
* Return :NULL
**********************************************************/
void app_create_start_task(void)
{
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t* )&start_task_handler);
vTaskStartScheduler();
}
app_task_start.h文件内容如下:
/******************************************************************************
*
* @FileName : app_task_start.h
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-18
*
* @Description : The App Header File of the Start Task for RoboticArm
*
*
******************************************************************************/
#ifndef __APP_TASK_START_H__
#define __APP_TASK_START_H__
#ifdef __cplusplus
extern "C" {
#endif
void app_create_start_task(void);
#ifdef __cplusplus
}
#endif
#endif
app_main.c文件内容如下:
/******************************************************************************
*
* @FileName : app_main.c
*
* @Author : WeiShuangbo
*
* @Version : 1.0
*
* @Date : 2020-04-12
*
* @Description : The main file for RoboticArm
*
******************************************************************************/
#include "hal_bsp.h"
#include "app_task_start.h"
/*******************************************************
*
* Function name : main
* Description : Entry main of app
* Parameter :NULL
* Return :NULL
**********************************************************/
int main(void)
{
bsp_init();
app_create_start_task();
return 0;
}
最后,我们还需要在根目录下编写ld文件stm32_flash.ld和makefile文件。
stm32_flash.ld:
/*
*****************************************************************************
**
** File : stm32_flash.ld
**
** Abstract : Linker script for STM32F103ZE Device with
** 512KByte FLASH, 64KByte RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Environment : Atollic TrueSTUDIO(R)
**
** Distribution: The file is distributed “as is,” without any warranty
** of any kind.
**
** (c)Copyright Atollic AB.
** You may use this file as-is or modify it according to the needs of your
** project. Distribution of this file (unmodified or modified) is not
** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
** rights to distribute the assembled, compiled & linked contents of this
** file as part of an application binary file, provided that it is built
** using the Atollic TrueSTUDIO(R) toolchain.
**
*****************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20010000; /* end of 64K RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x200; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
/* Define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
.ARM.attributes : { *(.ARM.attributes) } > FLASH
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(.fini_array*))
KEEP (*(SORT(.fini_array.*)))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /*
define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(4);
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(4);
} >RAM
/* MEMORY_bank1 section, code must be located here explicitly */
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
.memory_b1_text :
{
*(.mb1text) /* .mb1text sections (code) */
*(.mb1text*) /* .mb1text* sections (code) */
*(.mb1rodata) /* read-only data (constants) */
*(.mb1rodata*)
} >MEMORY_B1
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}
makefile:
#project name is SpunSugar_nos
PROJECT := TestFreeos
TOP_DIR = .
OUT_DIR := $(TOP_DIR)/output/
TARGET := $(PROJECT)
TARGET_ELF := $(OUT_DIR)$(TARGET).elf
TARGET_BIN := $(OUT_DIR)$(TARGET).bin
TARGET_HEX := $(OUT_DIR)$(TARGET).hex
TARGET_SREC := $(OUT_DIR)$(TARGET).srec
OBJCPFLAG_ELF2BIN = -Obinary
OBJCPFLAG_ELF2HEX = -Oihex
OBJCPFLAG_ELF2SREC = -Osrec
INC_DIR := -I $(TOP_DIR)/Drv/Bsp/Core/inc \
-I $(TOP_DIR)/Drv/Bsp/User/inc \
-I $(TOP_DIR)/Drv/Rtos/Core/inc \
-I $(TOP_DIR)/Drv/Rtos/Portable/inc \
-I $(TOP_DIR)/Hal/inc \
-I $(TOP_DIR)/App/inc
LDSCRIPT := $(TOP_DIR)/stm32_flash.ld
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
AR = arm-none-eabi-ar
OBJCP = arm-none-eabi-objcopy
CCFLAGS += -W -Wall -g -mcpu=cortex-m3 -mthumb -O0 -std=gnu11
CCFLAGS += $(INC_DIR)
CCFLAGS += -D STM32F10X_HD -D USE_STDPERIPH_DRIVER
ASFLAGS += -c -mthumb -mcpu=cortex-m3 -g -Wa,--warn
LDFLAGS += -mthumb -mcpu=cortex-m3 -Wl,--start-group -lc -lm -Wl,--end-group \
-specs=nano.specs -specs=nosys.specs -static -Wl,-cref,-u,Reset_Handler \
-Wl,-Map=./project.map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 \
-T $(LDSCRIPT)
SOURCE_C = $(shell find ./ -name '*.c')
SOURCE_ASM = $(shell find ./ -name '*.s')
C_OBJS := $(SOURCE_C:%.c=%.o)
ASM_BOJS := $(SOURCE_ASM:%.s=%.o)
COMPILE = $(CC) $(CCFLAGS) -c $< -o $@
ASSEMBLE = $(CC) $(ASFLAGS) -c $< -o $@
LINK = $(CC) $(C_OBJS) $(ASM_BOJS) $(LDFLAGS) -o $@
ELF_TO_BIN = $(OBJCP) $(OBJCPFLAG_ELF2BIN) $< $@
ELF_TO_HEX = $(OBJCP) $(OBJCPFLAG_ELF2HEX) $< $@
ELF_TO_SREC = $(OBJCP) $(OBJCPFLAG_ELF2SREC) $< $@
.PHONY: hex srec bin clean dir
hex: $(TARGET_HEX)
@echo "build .hex done"
$(TARGET_HEX):$(TARGET_ELF)
$(ELF_TO_HEX)
$(TARGET_ELF):$(C_OBJS) $(ASM_BOJS)
$(LINK)
$(ASM_BOJS):$(SOURCE_ASM)
$(ASSEMBLE)
$(C_OBJS):%.o:%.c
$(COMPILE)
srec: $(TARGET_SREC)
@echo "build .srec done"
$(TARGET_SREC):$(TARGET_ELF)
$(ELF_TO_SREC)
$(TARGET_ELF):$(C_OBJS) $(ASM_BOJS)
$(LINK)
$(ASM_BOJS):$(SOURCE_ASM)
$(ASSEMBLE)
$(C_OBJS):%.o:%.c
$(COMPILE)
bin: $(TARGET_BIN)
@echo "build .bin done"
$(TARGET_BIN):$(TARGET_ELF)
$(ELF_TO_BIN)
$(TARGET_ELF):$(C_OBJS) $(ASM_BOJS)
$(LINK)
$(ASM_BOJS):$(SOURCE_ASM)
$(ASSEMBLE)
$(C_OBJS):%.o:%.c
$(COMPILE)
dir:
mkdir $(OUT_DIR)
clean:
rm -f $(shell find ./ -name '*.o')
rm -f $(shell find ./ -name '*.d')
rm -f $(shell find ./ -name '*.map')
rm -f $(shell find ./ -name '*.elf')
rm -f $(shell find ./ -name '*.bin')
rm -f $(shell find ./ -name '*.hex')
rm -f $(shell find ./ -name '*.srec')
至此,FreeRTOS移植实例完成。通过在Linux子终端中进行编译,生成TestFreeos.hex文件,并烧录到板子上,运行结果如下: