瑞萨RA8D1 MCU 内部集成了高性能的以太网 MAC 控制器,并且提供了丰富的存储器资源(2MB Flash,1MB RAM)。另外地,CPKCOR-RA8D1核心板上额外集成了一颗32MB的SDRAM,可以轻松地运行各类复杂的嵌入式图形和网络应用。本文我们将使用CPKEXP-EKRA8x1扩展板上的以太网PHY,基于FreeRTOS部署LWIP。
一、软硬件准备硬件部分
CPKCOR-RA8D1 核心板
CPKEXP-EKRA8x1 扩展板
路由器 & 网线
软件部分
e²Studio 2025-12 (25.12.0)
Renesas FSP 6.3.0
J-Link RTT Viewer V8.92

核心板上的RA8D1已经集成了以太网 MAC 控制器,完整的底层硬件链路还需要以太网PHY、隔离变压器、RJ45接口。CPKEXP-EKRA8x1 扩展板提供了这部分外部硬件,我们只需要连接好相应的跳线帽即可,如图:

有个需要注意的点:CPKEXP-EKRA8x1 扩展板上的以太网PHY和摄像头有引脚冲突,不能同时安装。
Pin 设置芯片和PHY之间使用RMII接口连接。为了方便,我们可以从其它配置好网络的例程中引入配置好的引脚。

需要特别注意的是nRST引脚:P510,扩展板把P510外接下拉电阻接地,如果缺失了对它的配置,PHY会一直被复位而无法工作。

我们可以将P510手动设置高电平输出:

首先在创建工程时,我们就可以基于Blinky的FreeRTOS工程模板。在初始化好RTOS工程结构的同时,还可以获得一个可以指示系统状态的LED。

随后在Stack页面,添加Networking -> LwIP tcpip 和 Networking -> LwIP system FreeRTOS port ,并补充底层以太网硬件支持,此时框图会提示有误的配置,我们对照它来调整FreeRTOS各项开关。

配置好后的整体系统框图,如图:

随后,把Common->Infrastructure->Heap and momory pools 和 Threading下的配置修改如下。

我们新建一个lwip线程,堆栈大小配置为20240。我们可以使用DHCP获取配置,也可以使用如下代码直接设置静态地址以加快启动速度。
IP4_ADDR(&ipaddr, 192, 168, 1, 12); IP4_ADDR(&gw, 192, 168, 1, 1); IP4_ADDR(&netmask, 255, 255, 255, 0);
完整代码如下:
#include <lwip_thread.h>
#include "common_utils.h"
#include "usr_app.h"
#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "lwip/tcp.h"
#include "lwip/timeouts.h"
#include "lwip/init.h"
#include "lwip/ip4.h"
#include "lwip/dhcp.h"
#include <lwip/sockets.h>
struct netif gnetif;
ip4_addr_t ipaddr;
ip4_addr_t netmask;
ip4_addr_t gw;
void ethernet_link_status_updated(struct netif *netif)
{
if (netif_is_link_up(netif)) {
APP_PRINT("LINK UP\n\n");
} else {
APP_PRINT("LINK DOWN\n\n");
}
}
void LwIP_Init(void)
{
LWIP_DEBUGF(TCP_DEBUG, ("RTT Debug Enabled\n"));
/* Initialize the LwIP stack with RTOS */
tcpip_init(NULL, NULL);
ipaddr.addr = 0;
netmask.addr = 0;
gw.addr = 0;
// IP4_ADDR(&ipaddr, 192, 168, 1, 12);
// IP4_ADDR(&gw, 192, 168, 1, 1);
// IP4_ADDR(&netmask, 255, 255, 255, 0);
/* add the network interface (IPv4/IPv6) with RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, &g_lwip_ether0_instance, &rm_lwip_ether_init, &tcpip_input);
/* Registers the default network interface */
netif_set_default(&gnetif);
/* When the netif is fully configured this function must be called */
netif_set_up(&gnetif);
netif_set_link_up(&gnetif);
/* Set the link callback function, this function is called on change of link status*/
netif_set_link_callback(&gnetif, ethernet_link_status_updated);
/* Start DHCP negotiation for a network interface (IPv4) */
int err = dhcp_start(&gnetif); // start dhcp
if (err == ERR_OK) {
APP_PRINT("lwip dhcp init success...\n\n");
} else {
APP_PRINT("lwip dhcp init fail...\n\n");
}
while(ip_addr_cmp(&(gnetif.ip_addr),&ipaddr)) // wait for dhcp ip valid
{
vTaskDelay(100);
APP_PRINT("DHCP Status: %d\n", (netif_dhcp_data(&gnetif))->state);
}
APP_PRINT("Local IP : %s\n", ip4addr_ntoa(&gnetif.ip_addr));
APP_PRINT("Local Netmask : %s\n", ip4addr_ntoa(&gnetif.netmask));
APP_PRINT("Local GW : %s\n", ip4addr_ntoa(&gnetif.gw));
}
/*******************************************************************************************************************//**
* @brief This is the User Thread for LWIP.
* @param[in] Thread specific parameters
* @retval None
**********************************************************************************************************************/
void lwip_thread_entry(void *pvParameters)
{
fsp_pack_version_t version = {RESET_VALUE};
FSP_PARAMETER_NOT_USED(pvParameters);
/* version get API for FLEX pack information */
R_FSP_VersionGet (&version);
/* Example Project information printed on the RTT */
APP_PRINT (BANNER_INFO, EP_VERSION, version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch);
LwIP_Init();
/* If this thread is done, you can delete it */
vTaskDelete(NULL);
}五、烧录运行烧录代码,并启动RTT Viewer,可以看到输出如下信息:

插拔一次网线,测试网络接口(netif)链路状态变化回调函数,可以看到打印信息:

LwIP是默认启用ICMP功能的,我们可以在局域网另一条电脑ping一下开发板。效果如下:

至此,我们就在CPKCOR-RA8D1开发板上成功部署了FreeRTOS+LWIP的软件。接下来我将会在此基础上进行UDP、TCP、HTTP、MQTT的一系列实验,敬请期待~
我要赚赏金
