为什么要在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. 基于JGraphT实现的路径探寻

    基于JGraphT实现的路径探寻 业务中提出基于内存,探寻的两点间的有向以及无向路径,多点间的最小子图等需求,以下记录使用JGraphT的实现过程. GraphT是免费的Java类库,提供数学图论对象 ...

  2. MySQL 基础 SQL 操作

    MySQL 用户 --登录 mysql -u<用户名> -p[密码] --修改密码 mysqladmin -u<用户名> -p[密码] password <new_pas ...

  3. linux修改环境变量的三种方法【转】

    [环境变量配置的三个方法] 如想将一个路径加入到$PATH中,可以像下面这样做:  1. 控制台中,不赞成使用这种方法,因为换个shell,你的设置就无效了,因此这种方法仅仅是临时使用,以后要使用的时 ...

  4. vue状态管理vuex从浅入深详细讲解

    1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...

  5. 2018 Multi-University Training Contest 10

      Recently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you. As ...

  6. Splash简单应用

    jd->iphone import requests from lxml import etree # search_key = 'iphone' jd_url = "https:// ...

  7. VSCode前端 插件

    https://www.cnblogs.com/karthuslorin/p/8577224.html

  8. 8.Java的特性和优势

    简单性:可以说Java是C++语法的纯净版,没有头文件,没有指针运算,也不用分配内存. 面向对象:是一种程序设计技术,它将重点放在对象以及对象的接口上,模拟人的思维写程序,所以人去学习非常快.因此,J ...

  9. Unity3d游戏角色描边

    本文发布于游戏程序员刘宇的个人博客,欢迎转载,请注明来源https://www.cnblogs.com/xiaohutu/p/10834491.html 游戏里经常需要在角色上做描边,这里总结一下平时 ...

  10. Android的学习之路一

    在Android的道路上越走越远==,本着一颗童心去学习,没想到最后会成为自己的职业.看到过知乎上写的,并不是兴趣使比尔盖茨以及乔布斯他们成就斐然,而是他们真正的牛逼使得即使买大饼也能成为世界首富.然 ...