为什么要在stm32 f103上面移植freertos

  stm32 f103 以他的全面的文档,亲民的价格,强大的功能。成为无数微设备的方案首选。在市场上有极大的使用量。市场占有率也是非常的高。freertos作为一个开源的微型操作系统,凭借着它的资源占用小,功能强大,文档齐全,成为各大芯片公司都支持的操作系统,也是程序员操作系统学习的不二首选。所以,把这两者结合起来,除了能给我们的产品提供强大的支撑之外,还积累的很多基础技术。笔者花了不少心思才把这个移植好,在这里做个记录。希望能给你一些启发。

基本介绍

  我这里使用的是freertos的版本是9.0。移动植入之前,先看一下freertos的文件目录:

├── croutine.c
├── event_groups.c
├── include
│   ├── FreeRTOS.h
│   ├── StackMacros.h
│   ├── croutine.h
│   ├── deprecated_definitions.h
│   ├── event_groups.h
│   ├── list.h
│   ├── mpu_prototypes.h
│   ├── mpu_wrappers.h
│   ├── portable.h
│   ├── projdefs.h
│   ├── queue.h
│   ├── semphr.h
│   ├── stdint.readme
│   ├── task.h
│   └── timers.h
├── list.c
├── portable
│   ├── GCC
│   │   └── ARM_CM3
│   │   ├── port.c
│   │   └── portmacro.h
│   ├── MemMang
│   │   ├── heap_1.c
│   │   ├── heap_2.c
│   │   ├── heap_2.lst
│   │   ├── heap_2.o
│   │   ├── heap_3.c
│   │   ├── heap_4.c
│   │   └── heap_5.c
│   └── readme.txt
├── queue.c
├── readme.txt
├── tasks.c
└── timers.c

大致一看,这个操作系统是非常简洁的。从文件名字就可以看出:

queue.c 这个文件是队列,负责线程之间的通信和数据传输的。

task.c 就是线程及任务模块,线程相关的都在这个文件里面。

list.c 就是一个链表,用来实现可变数据的存放和操作。

根目录下的和具体的芯片没关系,和芯片的接口及相关的元素主要在两个函数里面。

一个是portable文件下的port.c 这个里面要注意下,在stm32 f103中,这里最重要的就是这里的中断处理函数的匹配了。在无操作系统的stm32 f103中,systick, SVC 和 PendSV 这三个中断的处理函数 这三个函数一般在start.s文件或中断向量表中vector.c 中。基本额写法如下所示:

void SVC_Handler (void) attribute((weak));

void PendSV_Handler (void) attribute((weak));

void SysTick_Handler (void) attribute((weak));

在freertos中,需要替换成port.c 里面的另外三个中断处理函数:

voidxPortPendSVHandler( void ) attribute (( naked ));

voidxPortSysTickHandler( void );

voidvPortSVCHandler( void ) attribute (( naked ));

另外一个就是heap,heap主要是系统的内存管理单元。heap_1.c, heap_2.c and heap_3.c属于三个基本的样例子,用户也可以根据自己的实际情况做修改。这里的的heap虽然很多,但是每个系统只会使用一个,具体使用哪一个要看你的芯片平台的属性,stm32 f103 使用的是heap_2.c

移植流程

  第一步就是把代码拷贝到目标文件中,编译通过。这里属于一些基本功夫,详细的步骤我就不多说了,谨记中断处理函数的处理,这里非常容易出问题。再者就是FreeRTOSconfig.h文件中的heap_size大小,不能太大,太大了这个芯片的资源不够的。建议一般不要10k左右就行了吧。

  第二步就是FreeRTOSConfig.h文件的配置选择,这里面的是非常关键的,最容易出错。下面是我的这个文件的配置:

#define configUSE_PREEMPTION            1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ / 8 ) /* fix for vTaskDelay() */
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1 /* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 2 /* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1

这里要注意几点: configCPU_CLOCK_HZ 就是CPU的的时钟,系统的时钟和CPU的时钟是不同的,这里做一个8分频:#define configSYSTICK_CLOCK_HZ ( configCPU_CLOCK_HZ / 8 )

还有就是后面的heap大小和stack大小,要根据实际的产品情况进行调整的。这个调整好了,可以让你的小芯片发挥出极大的威力。

  第三点,应用部分:

这里手先看一下主函数:

int main()
{
RCC_Configuration();
GPIO_Configuration();
usart1_init(); printf("start main sdf \n\r");
usart1_puts(" 512k flash, 64k ram ..........\n\r"); xTaskCreate(tadventure,"game",configMINIMAL_STACK_SIZE,NULL,configMAX_PRIORITIES-1,NULL);
xTaskCreate(flasher,"flash",configMINIMAL_STACK_SIZE,NULL,configMAX_PRIORITIES-1,NULL);
xTaskCreate(vT_usart, (const char*) "USART Task", configMINIMAL_STACK_SIZE, NULL, 1, NULL); vTaskStartScheduler(); while (1); return 0;
}

三个task的处理函数:

static void flasher(void *arg __attribute__((unused))) {

    for (;;) {
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
vTaskDelay(pdMS_TO_TICKS(400));
GPIO_SetBits(GPIOA, GPIO_Pin_1);
vTaskDelay(pdMS_TO_TICKS(400));
}
} static void tadventure(void *arg __attribute__((unused))) {
{
for (;;) {
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
vTaskDelay(pdMS_TO_TICKS(1000));
GPIO_SetBits(GPIOA, GPIO_Pin_0);
vTaskDelay(pdMS_TO_TICKS(1000));
}
} static void vT_usart(void *p)
{
// Block for 500ms.
const portTickType xDelay = 500 / portTICK_RATE_MS; for(;;) {
usart1_puts("FreeRTOS V9.0.0 demo on STM32F103c8t6\r\n");
usart1_puts(" 64k flash, 20k ram ..........\r\n");
vTaskDelay(xDelay);
}
}

这里的结果如下所示:

问题备忘

  最大的问题就是一个是FreertosConfig.h文件设置错误导致的系统timer不对。

另外就是中断的服务处理函数了,一定要换成自己的。

移植freertos到stm32 f103 的基本流程和总结的更多相关文章

  1. FreeRTOS学习及移植笔记之二:在IAR和STM32F103VET上移植FreeRTOS

    上一次,我们简单的测试了FreeRTOS的基于IAR EWARM v6.4和STM32F103VET6平台的Demo,对其有了一个基本认识.接下来我们开始自己移植FreeRTOS的过程. 1.创建一个 ...

  2. Bootloader 跳转到 RT-Thread 或 FreeRTOS(基于 STM32)

    Bootloader 跳转到 RT-Thread 或 FreeRTOS(基于 STM32) 作者:猾蚁 QQ:7376220一.Bootloader 程序1. 准备好升级程序项目,可以使用 STM32 ...

  3. STM32移植FreeRTOS(1)

    "STM32F103VET6<_>FreeRTOS" 1.项目功能实现 1)LED灯定时闪烁 2)KEY按键检测 3)FreeRTOS任务创建 4)串口输出程序运行状态 ...

  4. 移植FreeModbus+ModbusMaster+STM32至RT-Thread(3、4阶段)

    一.简介及进展 经过一个多月的努力,目前项目开发已进入最后阶段.虽然比预期时间有些延迟,但也收获不少,边工作边开源的效率确实还有待提高. 简单说下目前的进展吧 1.目前项目已经在Github中开源,大 ...

  5. 基于keil平台下STM32L系列移植FreeRTOS操作系统

    1,下载FreeRTOS https://www.freertos.org/a00104.html 点击下载后,会进入如下界面 之后会弹出下载界面,格式为.EXE,不用怀疑.不是木马. 等待下载完成, ...

  6. LWIP network interface 即 LWIP 的 硬件 数据 接口 移植 详解 STM32 以太网数据 到达 的第二站: void ethernetif_input( void * pvParameters )

    根据 上一篇 文章 , ETH  DMA 数据中断 会 发送 一个信号量 ,我使用 全局 搜索 这个信号量 s_xSemaphore 得到 一下 几个 值 根据 这个 分析  我们找到了   数据 的 ...

  7. 移植mavlink到stm32详细教程,后面附快速移植方法

    一:准备材料: mavlink源码 stm32串口程序    1.mavlink源码:        a.进入mavlink官网(http://qgroundcontrol.org/mavlink/s ...

  8. 移植FreeModbus+ModbusMaster+STM32至RT-Thread(初步)

    一.项目描述 目前操作系统在嵌入式软件行业非常流行,在工控组网方面,以后可能会经常使用到Modbus主机+操作系统.Modbus从机+操作系统甚至Modbus主机+Modbus从机+操作系统.但是操作 ...

  9. 学习使用Free RTOS ,移植最新的STM32 v3.5固件库

    最近拿到了一块万利的EK-STM32F的学习板,打算先用它来熟悉下STM32的编程环境,不过在这过程中和一个同事聊的时候觉得如果只调用STM32的库写程序,可能在芯片资源的利用上面可能就会差一点,在这 ...

随机推荐

  1. 2018湘潭邀请赛 AFK题解 其他待补...

    A.HDU6276:Easy h-index Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  2. 【Springboot】注解@ConfigurationProperties让配置整齐而简单

    1 简介 前面我们用一篇文章<[Spring]只想用一篇文章记录@Value的使用,不想再找其它了(附思维导图)> 详细讲解了在Spring中如何使用@Value来实现我们对配置的需求,它 ...

  3. 2019版Idea如何激活

    1.下载jar包 链接: https://pan.baidu.com/s/1w4B4_hmiiueNDJMjYKaFyQ 提取码: fkpx 2.修改·vmoptions 1.Help" - ...

  4. vim添加多行注释的几种方式

    最近需要在阿里云上部署项目,不可避免地会遇到vim这个工具,查了一些资料,总结了一下使用vim多行注释的方法 块操作 多行注释: 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块) ...

  5. 机器学习——Java调用sklearn生成好的Logistic模型进行鸢尾花的预测

    机器学习是python语言的长处,而Java在web开发方面更具有优势,如何通过java来调用python中训练好的模型进行在线的预测呢?在java语言中去调用python构建好的模型主要有三种方法: ...

  6. Java 项目热部署,节省构建时间的正确姿势

    上周末,帮杨小邪(我的大学室友)远程调试项目.SpringBoot 构建,没有热部署,改一下就得重启相关模块.小小的 bug ,搞了我一个多小时,大部分时间都还在构建上(特么,下次得收钱才行).我跟他 ...

  7. 区间dp - codeforces

    题意 : 给你 n 个数字,相邻的数字如果相同,则代表他们是一个块的,每次操作可以将一个块的数字变成任意一种数字,求最小操作次数,将整个区间的所有数字变成相同的 思路分析 : 定义 dp[i][j][ ...

  8. 换装WIN10(windows)那点儿事,换装操作系统一文通,玩转安装操作系统

    目录 1. 按 2. win10对电脑配置的要求 3. 原版镜像下载 4. 制作U盘系统盘 5. 硬盘分区调整 6. 设置开机时从U盘启动 7. 安装win10 8. 如何激活WIN10 9. 如何给 ...

  9. LeetCode 第26题--数组中重复元素

    1. 题目 2.题目分析与思路 3.代码 1. 题目 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2. 你不需要考虑数组中超 ...

  10. java 类初识

    一.定义 成员变量 成员方法 注意: 1.成员变量有默认值,是全局变量 2.成员方法,不需要使用static 3.成员变量的默认值 整型 0 浮点型 0.0 引用数据类型 null 二.使用 1.导包 ...