文章目录

  • 移植过程
    • 移植FreeRTOS
      • 源码拷贝
      • FreeRTOSConfig.h
      • 注意事项
    • 移植LWIP
      • 源码拷贝与编译
    • 初始化

移植过程

freeRTOS V10.4.5 下载 https://github.com/FreeRTOS/FreeRTOS

Lwip V2.1.3 http://download.savannah.nongnu.org/releases/lwip/

GD32F407VET6

keil5

移植FreeRTOS

源码拷贝

下载源码,解压。源码在FreeRTOS文件夹中Source文件夹中。

在我们的工程文件中创建文件夹FreeRTOS。将Source中下图中的内容拷贝到我们创建的FreeRTOS文件夹中。这些是各平台通用的头文件和C文件。

接下来移植平台相关的接口文件,在portable文件夹中。我用的是keil。打开portable中的keil文件夹。里面是各txt文本。不需要打开了,里面啥都没有。看txt文件名字,其实就是让你去看RVDS文件夹中的内容。打开portable中的RVDS文件夹。我用的是CM4的平台,因此在我们自己创建的FreeRTOS文件家中创建一个portable,将RVDS文件夹中ARM_CM4F的内容拷贝到我们自己创建的portable中。接下来将源码protable文件夹中的MemMang拷贝到我们自己创建的protable文件中。

MemMang其实就是Memory management的缩写,就是内存管理的意思。这里面右5个C文件,代表了5中内存管理的方式。其实我们在使用的时候只需要使用其中一种即可,最终我们往工程中添加哪个,就使用哪个。我添加的是heap_4这个C文件。

以上这些是FreeRTOS的基本文件,我们不需要进行修改。

FreeRTOSConfig.h

FreeRTOSConfig.h 是freeRTOS工程的配置文件。里面通过各种宏定义来使能FreeRTOS的各种功能,这个过程就叫做裁剪。这里我直接在demo里的FreeRTOSConfig.h 来使用,后续再根据自己的需要进行修改。下载的FreeRTOS文件夹下的demo包含了各种平台的完整的demo工程。我选择了比较接近我用的平台的demo中的FreeRTOSConfig.h(在CORTEX_M4F_STM32F407ZG-SK文件夹下)。

至此,所有必须文件都拷贝完成,接下来加入到工程中。

注意事项

1、我用的是keil 编译器应该为__CC_ARM 而demo的FreeRTOSConfig.h中是 __ICCARM__ 这个是IAR的,需要改掉。

2、中断映射

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

上面这些宏定义是FreeRTOSConfig.h中的。

SVC_Handler是系统调用异常的中断入口,将vPortSVCHandler映射到SVC_Handler,产生SVC系统调用异常的时候就会执行vPortSVCHandler,在vPortSVCHandler主要做的就是启动第一个任务,切换堆栈指针从MSP到PSP。这个中断只在任务开始的时候使用一次。

PendSV_Handler是用来做任务切换,是可挂起的异常,SVC异常是必须立即得到响应的(若因优先级不比当前正处理的高,或是其它原因使之无法立即响应,将会产生Hardfault)。,PendSV 它是可以像普通的中断一样被悬起的。OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。xPortPendSVHandler中主要用来作为任务切换。当需要进行任务切换的时候就手动产生一个PendSV异常,进入xPortPendSVHandler完成任务切换。

SysTick_Handler是系统时钟定时器的中断入口。xPortSysTickHandler主要用来对系统运行时间进行加1.判断任务列表是否有延时到期的,将延时到期的任务转换为就绪态。然后就是触发PendSV异常,这就是心跳节拍的由来,每一次心跳节拍进入一次xPortSysTickHandler,然后触发一次PendSV异常,在异常中看是否右更高优先级的程序需要切换。

系统时钟定时器的初始化问题:freeRTOS已经写好了一个系统时钟初始化的函数vPortSetupTimerInterrupt。这个函数根据我们在FreeRTOSConfig.h中配置的configTICK_RATE_HZ和configSYSTICK_CLOCK_HZ来设置中断产生的时间。配置系统时钟的寄存器已经在port.c里面映射了,这个和平台关系比较大。在任务启动的函数里面调用了vPortSetupTimerInterrupt。

freeRTOS移植主要就是上面这三个中断。我的理解是这三个中断可以使用其他中断去代替,但是向SVC,penSV都是专门针对操作系统设计的,相较于其他中断来说更合适一些。

资料记录:

http://33h.co/khysn

移植LWIP

源码拷贝与编译

我下载的是lwip-2.1.3和contrib-2.1.0。源码放在了lwip-2.1.3下的src文件夹。在移植好的freeRTOS工程下新建一个文件夹LWIP。将src文件夹下面的文件拷贝到我们创建的LWIP文件夹下面

这个是lwip的基本代码,不需要我们进行修改。需要我们自己来实现的有三个:操作系统相关的接口、底层网卡的操作接口、配置文件。如果是裸机的话,那么我们需要实现的是裸机相关的接口(lwip的时基,类似于操作系统的心跳)、底层网卡的操作接口、配置文件。

//在带操作系统的移植中,时基,也就是sys_now函数如下
#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
u32_t
sys_now(void)
{return xTaskGetTickCount() * portTICK_PERIOD_MS;
}
#endif

操作系统相关接口移植,我使用的是freeRTOS,这个contrib-2.1.0里面有相应的文件,contrib-2.1.0\ports\freertos,在LWIP文件夹下面新建一个port文件夹,contrib-2.1.0\ports\freertos下面的C文件和H文件拷贝到port。

底层网卡操作文件先将contrib-2.1.0\examples\ethernetif下面的C文件拷贝过来,在这个上面根据我们网卡的驱动程序自己修改。

配置文件先将contrib-2.1.0\examples\example_app下面的lwipopts.h拷贝过来,在这个上面根据我们的需要进行配置,就像FreeRTOSConfig.h一样。

编译显示缺少cc.h文件,cc.h 文件中包含处理器相关的变量类型、数据结构及字节对齐的相关宏。LwIP 中使用的基本变量类型均以位数进行命名,为抽象的变量类型定义,开发者需要根据所用处理器及编译器特性进行定义,一般我们直接将变量直接定义为 C 语言的基本类型,如 unsignedchar、int 等,这样子可以保证 LwIP 协议栈就与平台无关了。我这里使用的是GD32已经编写好的cc.h文件。在LWIP文件夹下面新建一个arch文件夹,将cc.h拷贝进来。

编译显示cc.h里面缺少cpu.h,我看GD的工程里cpu.h里面没啥内容,野火的教程里也没有引用这个,所以我把这这行代码屏蔽了。

编译显示找不到“arch/sys_arch.h”这个文件,我的sys_arch.h文件是放在port文件夹下面,我又拷贝了一分到arch文件夹中。

Error: L6218E: Undefined symbol errno (referred from if_api.o). 在if_api.c文件中加入了int errno;

移植的时候报了很多错误,大部分是lwipopts.h配置文件引起的,最终我重新将GD工程里的lwipopts.h拿来了,错误就不见了,后面在去研究这些配置文件的意义。

另外不是所有源码里所有的C文件都需要添加到工程里的,下面的是我工程里添加的。

初始化

首先是硬件的初始化,包括了GPIO、时钟、MAC,这个每个平台初始化内容不一样。

接下来是LWIP协议栈的初始化

void lwip_stack_init(void)
{ip_addr_t ipaddr;ip_addr_t netmask;ip_addr_t gw;/* 创建一个tcpip进程 */tcpip_init( NULL, NULL );IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);netif_add(&g_mynetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);/* 设置默认网卡,因为可能一个系统里包含了多个 */netif_set_default(&g_mynetif);/* 该函数设置NETIF_FLAG_UP标记 */netif_set_up(&g_mynetif);/* 该函数设置NETIF_FLAG_LINK_UP标记 */netif_set_link_up(&g_mynetif);
}

协议栈初始化,首先调用 tcpip_init( NULL, NULL );

void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{lwip_init();tcpip_init_done = initfunc;tcpip_init_done_arg = arg;if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {LWIP_ASSERT("failed to create tcpip_thread mbox", 0);}
#if LWIP_TCPIP_CORE_LOCKINGif (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {LWIP_ASSERT("failed to create lock_tcpip_core", 0);}
#endif /* LWIP_TCPIP_CORE_LOCKING */sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
}

tcpip_init中调用lwip_init初始化了lwip协议栈内核然后创建邮箱、根据配置文件创建互斥信号量、启动一个TCPIP的线程。邮箱用于接收从底层或者上层传递过来的消息,消息传递给 tcpip_thread 线程,用这个线程来处理数据。简单理解就是freeRTOS中专门给网络数据接收起了一个任务,任务接收邮箱消息,根据对应的消息对数据做对应的处理,处理完后给到我们用户任务。

问题点:

调试过程中可以ping通,但是起了TCP任务之后就ping不通,最后发现在创建socket的时候会创建邮箱(freeRTOS中的队列),因为我没有定义DEFAULT_TCP_RECVMBOX_SIZE,导致创建队列的时候size默认为0,最后增加定义#define DEFAULT_TCP_RECVMBOX_SIZE 10,问题解决。

移植工程 :https://github.com/IJustLoveMyself/csdn-example/tree/main/example1

GD32F407 移植FreeRTOS+Lwip相关推荐

  1. STM32F407+FreeRTOS+LwIP移植问题汇总

    1.移植环境为STM32F407标准库+FreeRTOS v9.00+LwIP1.4.1.LwIP移植可分为带操作系统和不带操作系统两种移植方式.本次移植采用了带操作系统,但是只移植了LwIP的内核( ...

  2. GG32F450XX上移植RT-Thread+LWIP协议栈

    GD官方提供的例程ENET例程是FreeRtos+LWIP协议的,所以本人自己又重新做了一下移植(RT-Thread nano + LWIP1.4.1). 总结以下几点: 1,第一步是ENET的初始化 ...

  3. GD32F407移植SR8201F

    从GD32F450移植SR8201F网络驱动到GD32F407VE笔记 一. 从网络上下载GD32F450对SR8201F的驱动,MII接法原理图,SR8201F芯片资料等. 二.解压驱动 驱动分为l ...

  4. rt_thread nano GD32F407移植

    rt_thread nano GD32F407移植 文章目录 rt_thread nano GD32F407移植 1.简介 2.RT-Thread Nano移植 移植目结构 移植步骤 添加文件 屏蔽中 ...

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

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

  6. 2.STM32F407ZGT6 学习笔记-移植 FreeRTOS

    程序移植的代码: https://gitee.com/chejia12/free-rtos_-f407.git 1. 在工程下建议FreeRTOS文件夹 2. 在FreeRTOS文件夹下建立 src ...

  7. STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级) STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级) ...

  8. 英飞凌TC397移植FreeRTOS

    英飞凌TC397移植FreeRTOS 一.准备工作 1.FreeRTOS源码 2.STM驱动代码 3.中断相关配置文件 4.AURIX Developement Studio初始工程(包含SDK) 二 ...

  9. 【FreeRTOS】在Cortex-M4开发板上移植FreeRTOS并且实现LED灯闪烁(保姆级教程)

    相信有不少小伙伴手上只有M4的开发板,想要移植FreeRTOS:但是,网上大部分都是M3移植教程.因此,陷入深深的迷茫中,难不成只能使用仿真了???

最新文章

  1. 黑客常用的远程控制命令
  2. 微软提供支持Windows 10预览版和EdgeHTML 14的预配置虚拟主机
  3. C++容器(三):pair类型
  4. 谈谈mysql优化_浅谈MySQL SQL优化
  5. leetcode_add_two_numbers
  6. 开启php soap,php soap 开发文档
  7. 宝塔mysql data修改_宝塔一键修改mysql数据库存放路径,更改默认数据目录…
  8. Web API 设计摘要
  9. 妙用Python集合求解啤酒问题(携程2016笔试题)
  10. mysql是否需要设置外键_数据库到底需不需要设置外键?
  11. 走近汇编理解与内核编程
  12. linux libyuv 编译,编译libyuv
  13. 今天要学习的技术点,Python 筛选数字,模块导入,特殊变量__all__ 实战博客
  14. 软件工程领域国际会议列表
  15. excel中复制时不要计算机,电脑excel表格中无法将复制的内容粘贴进去如何解决...
  16. 【CF487E】 Tourists 简易题解
  17. 对数据驱动运营的理解
  18. 第21章,DNS服务
  19. 给中国学生的第七封信:21世纪最需要的7种人才(李开复)
  20. [极客大挑战 2020]Roamphp 1、2、4

热门文章

  1. float和double取值范围和精度问题
  2. Kymeta宣布可实现同步多轨道连接的多波束功能新获美国专利
  3. Linux 线程创建
  4. 奇怪!为什么全网都在说Python很好学?
  5. 计算三位数的水仙花数(个,十,百位数的立方和等于该数本身)
  6. 长春人行OA系统双机热备及Veritas备份及相关软硬件实施文档
  7. stemwin 19264单色屏移植
  8. 夜天之书 #23 Merge GitHub Repositories
  9. js readOnly 属性设置
  10. web应用防火墙与防火墙的差别