移植freertos到stm32 f103 的基本流程和总结
为什么要在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 的基本流程和总结的更多相关文章
- FreeRTOS学习及移植笔记之二:在IAR和STM32F103VET上移植FreeRTOS
		
上一次,我们简单的测试了FreeRTOS的基于IAR EWARM v6.4和STM32F103VET6平台的Demo,对其有了一个基本认识.接下来我们开始自己移植FreeRTOS的过程. 1.创建一个 ...
 - Bootloader 跳转到 RT-Thread 或 FreeRTOS(基于 STM32)
		
Bootloader 跳转到 RT-Thread 或 FreeRTOS(基于 STM32) 作者:猾蚁 QQ:7376220一.Bootloader 程序1. 准备好升级程序项目,可以使用 STM32 ...
 - STM32移植FreeRTOS(1)
		
"STM32F103VET6<_>FreeRTOS" 1.项目功能实现 1)LED灯定时闪烁 2)KEY按键检测 3)FreeRTOS任务创建 4)串口输出程序运行状态 ...
 - 移植FreeModbus+ModbusMaster+STM32至RT-Thread(3、4阶段)
		
一.简介及进展 经过一个多月的努力,目前项目开发已进入最后阶段.虽然比预期时间有些延迟,但也收获不少,边工作边开源的效率确实还有待提高. 简单说下目前的进展吧 1.目前项目已经在Github中开源,大 ...
 - 基于keil平台下STM32L系列移植FreeRTOS操作系统
		
1,下载FreeRTOS https://www.freertos.org/a00104.html 点击下载后,会进入如下界面 之后会弹出下载界面,格式为.EXE,不用怀疑.不是木马. 等待下载完成, ...
 - LWIP   network interface    即  LWIP  的 硬件 数据 接口 移植   详解 STM32 以太网数据 到达 的第二站:  void ethernetif_input( void * pvParameters )
		
根据 上一篇 文章 , ETH DMA 数据中断 会 发送 一个信号量 ,我使用 全局 搜索 这个信号量 s_xSemaphore 得到 一下 几个 值 根据 这个 分析 我们找到了 数据 的 ...
 - 移植mavlink到stm32详细教程,后面附快速移植方法
		
一:准备材料: mavlink源码 stm32串口程序 1.mavlink源码: a.进入mavlink官网(http://qgroundcontrol.org/mavlink/s ...
 - 移植FreeModbus+ModbusMaster+STM32至RT-Thread(初步)
		
一.项目描述 目前操作系统在嵌入式软件行业非常流行,在工控组网方面,以后可能会经常使用到Modbus主机+操作系统.Modbus从机+操作系统甚至Modbus主机+Modbus从机+操作系统.但是操作 ...
 - 学习使用Free RTOS ,移植最新的STM32 v3.5固件库
		
最近拿到了一块万利的EK-STM32F的学习板,打算先用它来熟悉下STM32的编程环境,不过在这过程中和一个同事聊的时候觉得如果只调用STM32的库写程序,可能在芯片资源的利用上面可能就会差一点,在这 ...
 
随机推荐
- 基于JGraphT实现的路径探寻
			
基于JGraphT实现的路径探寻 业务中提出基于内存,探寻的两点间的有向以及无向路径,多点间的最小子图等需求,以下记录使用JGraphT的实现过程. GraphT是免费的Java类库,提供数学图论对象 ...
 - MySQL 基础 SQL 操作
			
MySQL 用户 --登录 mysql -u<用户名> -p[密码] --修改密码 mysqladmin -u<用户名> -p[密码] password <new_pas ...
 - linux修改环境变量的三种方法【转】
			
[环境变量配置的三个方法] 如想将一个路径加入到$PATH中,可以像下面这样做: 1. 控制台中,不赞成使用这种方法,因为换个shell,你的设置就无效了,因此这种方法仅仅是临时使用,以后要使用的时 ...
 - vue状态管理vuex从浅入深详细讲解
			
1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...
 - 2018 Multi-University Training Contest 10
			
Recently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you. As ...
 - Splash简单应用
			
jd->iphone import requests from lxml import etree # search_key = 'iphone' jd_url = "https:// ...
 - VSCode前端 插件
			
https://www.cnblogs.com/karthuslorin/p/8577224.html
 - 8.Java的特性和优势
			
简单性:可以说Java是C++语法的纯净版,没有头文件,没有指针运算,也不用分配内存. 面向对象:是一种程序设计技术,它将重点放在对象以及对象的接口上,模拟人的思维写程序,所以人去学习非常快.因此,J ...
 - Unity3d游戏角色描边
			
本文发布于游戏程序员刘宇的个人博客,欢迎转载,请注明来源https://www.cnblogs.com/xiaohutu/p/10834491.html 游戏里经常需要在角色上做描边,这里总结一下平时 ...
 - Android的学习之路一
			
在Android的道路上越走越远==,本着一颗童心去学习,没想到最后会成为自己的职业.看到过知乎上写的,并不是兴趣使比尔盖茨以及乔布斯他们成就斐然,而是他们真正的牛逼使得即使买大饼也能成为世界首富.然 ...