32.6
FreeRTOS+TCP移植实验
32.6.1
硬件设计
野火启明6M5开发板的以太网相关电路如图所示。

点击可查看大图
32.6.2
软件设计
32.6.2.1
新建工程
对于e2 studio开发环境:在e2 studio工作空间中新建工程,工程名为“34_Ethernet_FreeRTOS”。新建工程时要注意选择FreeRTOS。
对于Keil开发环境:首先在指定的路径新建文件夹:“34_Ethernet_FreeRTOS”,用于存放我们即将新建的Keil工程。打开RASC软件来新建工程,工程路径选到“34_Ethernet_FreeRTOS”文件夹下面,工程名为“EBF_RA6M5”。新建工程时要注意选择FreeRTOS。
工程新建好之后,在工程根目录的“src”文件夹下面新建源文件“ether_phy_target_lan8720.c”,该文件是LAN8720的底层驱动文件。再新建源文件和头文件:“net_user_app.c”和“net_user_app.h”。
由于调试需要,可将LED和串口的驱动文件拷贝过来:直接复制前面例程里面的“led”和“debug_uart”文件夹并粘贴到工程根目录的“src”文件夹下面。
工程文件结构如下。
列表1: 文件结构
左右滑动查看完整内容
34_Ethernet_FreeRTOS ├─ ...... └─ src ├─ led │ ├─ bsp_led.c │ └─ bsp_led.h ├─ debug_uart │ ├─ bsp_debug_uart.c │ └─ bsp_debug_uart.h ├─ ether_phy_target_lan8720.c ├─ net_user_app.c ├─ net_user_app.h ├─ net_thread_entry.c └─ hal_entry.c
注
其中net_thread_entry.c该源文件若是不存在则会由软件自动生成,若存在,软件生成代码时该文件不会被覆盖。
32.6.2.2
FSP配置
使用e2 studio环境的用户使用printf注意需要对工程做如图所示的设置:

点击可查看大图
在FSP配置界面的BSP页面,分配主栈大小为0x1000、堆大小为0x2000,如下图所示:

点击可查看大图
32.6.2.2.1
配置RMII引脚和LAN8720复位引脚
根据硬件原理图,我们需要配置连接PHY LAN8720 的RMII引脚,以及LAN8720复位引脚。LAN8720的复位引脚为P802,由于复位引脚是低电平有效,可直接配置为输出高电平模式即可,如下图所示。

点击可查看大图
RMII 引脚配置如下图所示。

点击可查看大图
32.6.2.2.2
配置FreeRTOS和线程
首先新建一个线程:Net Thread(网络线程),该线程用于运行网络协议栈,然后向其中添加:FreeRTOS Heap 4和FreeRTOS+TCP。步骤如下。
在Threads区域点击“New Thread”按钮,新建得到一个默认名为“New Thread”线程。

点击可查看大图
线程名“New Thread”会在后面对线程进行配置时更改为“Net Thread”。现在让我们先在这个线程下面添加:FreeRTOS Heap 4和FreeRTOS+TCP。
添加FreeRTOS Heap 4步骤:“New Stack”→“RTOS”→“FreeRTOS Heap 4”。

点击可查看大图
添加FreeRTOS+TCP步骤:“New Stack”→“Networking”→“FreeRTOS+TCP”。

点击可查看大图
添加完成后的结果如下图所示。

点击可查看大图
接下来继续设置该线程的参数。点击“New Thread”线程,如下图所示。

点击可查看大图
上图中出现两个区域的配置属性,其中①是FreeRTOS全局的配置属性,②是“New Thread”这个线程的配置属性。
首先,按照下表的描述来配置“New Thread”线程。
表3:FreeRTOS配置属性:“Thread”部分

点击可查看大图
FreeRTOS 全局的配置如下:
FreeRTOS 配置属性:“Common”部分
| 属性 | 描述 |
|---|---|
| General > Custom FreeRTOSConfig.h |
为自定义 FreeRTOSConfig.h 文件添加路径。 它可用于覆盖此处定义的部分或全部配置,并定义其他配置。 没有自定义文件 FreeRTOSConfig.h 的话留空即可。 |
| General > Use Preemption |
Enabled Enabled:使用抢占式RTOS调度。 Disabled:使用协作式RTOS调度。 |
| General > Use Port Optimised Task Selection |
Disabled 启用端口优化任务选择。 |
| General > Use Tickless Idle | Disabled |
| General > Cpu Clock Hz |
SystemCoreClock CPU时钟频率。 |
| General > Tick Rate Hz |
100 RTOS 滴答中断的频率。 |
| General > Max Priorities |
5 应用程序任务可用的优先级数。任意数量的任务可以共享相同的优先级。 |
| General > Minimal Stack Size |
512 空闲任务使用的堆栈的大小。单位为字,而不是字节。 |
| General > Max Task Name Len |
16 任务名称的最大允许长度。该长度包括 NULL 终止字节。 |
| General > Use 16-bit Ticks |
Disabled 使用16位Ticks将大大提高8位和16位架构的性能, 但是会大大减少任务可以延迟或阻塞的最大时间。 |
| General > Idle Should Yield | Enabled |
| General > Use Task Notifications |
Disabled 使用任务通知。 |
| General > Use Mutexes |
Disabled 使用互斥量。 |
| General > Use Recursive Mutexes |
Disabled 使用递归互斥量。 |
| General > Use Counting Semaphores |
Enabled 使用计数信号量。 |
| General > Queue Registry Size |
10 队列注册表大小。 |
| General > Use Queue Sets |
Disabled 使用队列集。 |
| General > Use Time Slicing |
Disabled 使用时间切片。 |
| General > Use Newlib Reentrant |
Disabled 使用Newlib可重入。 |
| General > Enable Backward Compatibility |
Disabled 使能向后兼容。 |
| General > Num Thread Local Storage Pointers |
5 设置每个任务的线程本地存储数组中的索引数。 |
| General > Stack Depth Type |
uint32_t 栈深度类型。 |
| General > Message Buffer Length Type |
size_t FreeRTOS 消息缓冲区使用消息缓冲区长度类型的变量来存储每条消息的长度。 如果没有定义消息缓冲区长度类型,那么它将默认为 size_t。 |
| General > Library Max Syscall Interrupt Priority | Priority 1 |
| General > Assert | if (!(x)) {__BKPT(0);} |
| General > Include Application Defined Privileged Functions | Disabled |
| Hooks > Use Idle Hook |
Enabled 如果希望使用空闲钩子,则将其设置为“启用”,或者“禁用”以省略空闲钩子。 |
| Hooks > Use Malloc Failed Hook | Disabled |
| Hooks > Use Daemon Task Startup Hook | Disabled |
| Hooks > Use Tick Hook | Disabled |
| Hooks > Check For Stack Overflow | Disabled |
| Stats > Use Trace Facility | Disabled |
| Stats > Use Stats Formatting Functions | Disabled |
| Stats > Generate Run Time Stats | Disabled |
| Memory Allocation > Support Static Allocation |
Enabled 支持静态内存分配。 |
| Memory Allocation > Support Dynamic Allocation |
Enabled 支持动态内存分配。 |
| Memory Allocation > Total Heap Size |
0x8000 FreeRTOS 堆中可用的 RAM 总量。 |
| Memory Allocation > Application Allocated Heap | Disabled |
| Timers > Use Timers |
Enabled 使用软件定时器功能。 |
| Timers > Timer Task Priority |
3 定时器任务优先级。 |
| Timers > Timer Queue Length |
10 定时器队列长度。 |
| Timers > Timer Task Stack Depth |
128 定时器任务栈深度。 设置分配给软件计时器服务/守护进程任务的堆栈深度。 |
| Optional Functions > vTaskPrioritySet() Function |
Enabled 包含 vTaskPrioritySet() 函数。 |
| Optional Functions > uxTaskPriorityGet() Function |
Enabled 包含 uxTaskPriorityGet() 函数。 |
| Optional Functions > vTaskDelete() Function |
Enabled 包含 vTaskDelete() 函数。 |
| Optional Functions > vTaskSuspend() Function |
Enabled 包含 vTaskSuspend() 函数。 |
| Optional Functions > xResumeFromISR() Function | Disabled |
| Optional Functions > vTaskDelayUntil() Function |
Enabled 包含 vTaskDelayUntil() 函数。 |
| Optional Functions > vTaskDelay() Function |
Enabled 包含 vTaskDelay() 函数。 |
| Optional Functions > xTaskGetSchedulerState() Function |
Enabled 包含 xTaskGetSchedulerState() 函数。 |
| Optional Functions > xTaskGetCurrentTaskHandle() Function |
Enabled 包含 xTaskGetCurrentTaskHandle() 函数。 |
| Optional Functions > uxTaskGetStackHighWaterMark() Function | Disabled |
| Optional Functions > xTaskGetIdleTaskHandle() Function | Disabled |
| Optional Functions > eTaskGetState() Function | Disabled |
| Optional Functions > xEventGroupSetBitFromISR() Function |
Enabled 包含 xEventGroupSetBitFromISR() 函数。 |
| Optional Functions > xTimerPendFunctionCall() Function | Disabled |
| Optional Functions > xTaskAbortDelay() Function | Disabled |
| Optional Functions > xTaskGetHandle() Function | Disabled |
| Optional Functions > xTaskResumeFromISR() Function |
Enabled 包含 xTaskResumeFromISR() 函数。 |
| RA > Hardware Stack Monitor | Disabled |
| Logging > Print String Function | printf(x) |
| Logging > Logging Max Message Length | 192 |
| Logging > Logging Include Time and Task Name | Disabled |
35.6.2.2.3. 配置 FreeRTOS+TCP
点击“FreeRTOS+TCP”模块,如下图所示。

FreeRTOS+TCP 的属性配置如下:
FreeRTOS+TCP 的配置属性
| 属性 | 描述 |
|---|---|
| Print debug messages |
Disabled 打印调试信息。 |
| Print info messages |
Disabled 打印 info 信息。 |
| Byte order of the target MCU | pdFREERTOS_LITTLE_ENDIAN |
| IP/TCP/UDP checksums |
Enabled 计算 IP/TCP/UDP 校验和。 |
| Receive Block Time |
2000 FreeRTOS_recv() 阻塞的时间量。可以使用 setsockopt() 设置每个套接字的超时。 |
| Send Block Time |
2000 FreeRTOS_send() 阻塞的时间量。可以使用 setsockopt() 设置每个套接字的超时。 |
| DNS caching |
Disabled DNS 缓存。 |
| DNS Request Attempts |
5 DNS 请求尝试。 |
| IP stack task priority |
configMAX_PRIORITIES - 1 设置执行IP栈任务的优先级。 |
| Stack size in words (not bytes) |
configMINIMAL_STACK_SIZE * 10 为 FreeRTOS+TCP 设置栈大小,单位为字。 |
| Network Events call vApplicationIPNetworkEventHook |
Disabled 当网络连接或断开时,vApplicationIPNetworkEventHook 会被调用。 |
| Max UDP send block time |
15000 / portTICK_PERIOD_MS 最大 UDP 发送块时间。 |
| Use DHCP |
Enabled 使用 DHCP。 |
| DHCP Register Hostname |
Enabled 使用 DHCP 时注册主机名。 |
| DHCP Uses Unicast |
Enabled DHCP 使用单播。 |
| DHCP Send Discover After Auto IP | Enabled |
| DHCP callback function |
Enabled 需提供 DHCP 回调函数:xApplicationDHCPHook。 |
| Interval between transmissions | 120000 / portTICK_PERIOD_MS |
| ARP Cache Entries |
6 ARP 缓存条目。 |
| ARP Request Retransmissions |
5 ARP 请求重传次数。 |
| Maximum time before ARP table entry becomes stale |
150 创建或刷新 ARP 表中的条目与删除该条目之间的最长时间。 |
| Use string for IP Address |
Enabled 使用字符串表示IP地址。 |
| Total number of available network buffers |
16 网络数据包缓冲的总数 |
| Set the maximum number of events | ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 |
| Enable FreeRTOS_sendto() without calling Bind | Disabled |
| TTL values for UDP packets | 128 |
| TTL values for TCP packets | 128 |
| Use TCP and all its features |
Enabled 使用 TCP 及其所有特性。 |
| Let TCP use windowing mechanism |
Disabled 让 TCP 使用滑动窗口机制。 |
| Maximum number of bytes the payload of a network frame can contain |
1500 MTU 大小。 |
| Basic DNS client or resolver |
Enabled 基本的 DNS 客户端/解析器。 |
| Reply to incoming ICMP echo (ping) requests |
Enabled 应答 ICMP echo (ping) 请求。 |
| FreeRTOS_SendPingRequest() is available |
Enabled 允许使用 FreeRTOS_SendPingRequest()。 对应 ipconfigREPLY_TO_INCOMING_PINGS 宏配置。 |
| FreeRTOS_select() (and associated) API function is available | Disabled |
| Filter out non Ethernet II frames. |
Enabled 过滤掉非以太网 II 格式的以太网帧。 |
| Responsibility of the Ethernet interface to filter out packets | Disabled |
| Send RST packets, when receive unknown packets. | Enabled |
| Access 32-bit fields in the IP packets | 2 |
| Size of the pool of TCP window descriptors | 240 |
| Size of Rx buffer for TCP sockets | 3000 |
| Size of Tx buffer for TCP sockets | 3000 |
| TCP keep-alive | Enabled |
| TCP keep-alive interval | 120 |
| The socket semaphore to unblock the MQTT task (USER_SEMAPHORE) | Disabled |
| The socket semaphore to unblock the MQTT task (WAKE_CALLBACK) | Enabled |
| The socket semaphore to unblock the MQTT task (USE_CALLBACKS) | Disabled |
| The socket semaphore to unblock the MQTT task (TX_DRIVER) | Disabled |
| The socket semaphore to unblock the MQTT task (RX_DRIVER) | Disabled |
| Possible optimisation for expert users | Disabled |
35.6.2.2.4. 配置 ETHERC 和 PHY
点击“g_ether0”模块,如下图所示。

在左下角属性配置窗口进行配置,g_ether0 的属性配置如下:
g_ether0 的配置属性
| 属性 | 描述 |
|---|---|
| Common > Parameter Checking | Default (BSP) |
| Common > ET0_LINKSTA Pin Status Flag |
Fall -> Rise 设置 LINKSTA 状态变化。 |
| Common > Link Signal Change Flag |
Unused 使用 LINKSTA 信号检测链路状态变化。 |
| General > Name | g_ether0 |
| General > Channel | 0 |
| General > MAC address | 00:11:22:33:44:55 |
| General > Zero-copy Mode | Disabled |
| General > Flow control functionality | Disabled |
| Filters > Multicast Mode | Enabled |
| Filters > Promiscuous Mode | Disabled |
| Filters > Broadcast filter | 0 |
| Buffers > Number of TX buffer | 4 |
| Buffers > Number of RX buffer | 4 |
| Buffers > Allocate RX buffer | Enabled |
| Buffers > Buffer size | 1514 |
| Buffers > Padding size |
Disabled 自动插入到接收数据包中的填充大小。 |
| Buffers > Padding offset |
1 在接收缓冲区中插入填充字节的偏移量。 |
| Interrupts > Interrupt priority |
Priority 12 选择 EDMAC 中断优先级。 |
| Interrupts > Callback |
vEtherISRCallback 该中断回调函数是固定的,无法变更。 |
点击“g_ether_phy0”模块,如下图所示。

在左下角属性配置窗口进行配置,PHY 的属性配置如下:
Common 部分
| 属性 | 描述 |
|---|---|
| Parameter Checking | Default |
| Select PHY(DEPRECATED) | Default |
| KSZ8091RNZ Target | Disabled |
| KSZ8041 Target | Disabled |
| DP83620 Target | Disabled |
| ICS1894 Target | Disabled |
| Reference Clock | Default |
Ethernet PHY 的配置属性
| 属性 | 描述 |
|---|---|
| Name | g_ether_phy0 |
| Channel | 0 |
| PHY-LSI Address | 0 |
| PHY-LSI Reset Completion Timeout | 0x00020000 |
| Select MII type | RMII |
| Phy LSI type | Kit Component |
| MII/RMII Register Access Wait-time | 8 |
| Flow Control | Disabled |
35.6.2.3. PHY底层驱动函数
代码清单34-1:PHY底层驱动函数
/* Access to peripherals and board defines. */
#include "bsp_api.h"
#include "r_ether_phy.h"
#include "hal_data.h"
#include "stdio.h"
/***********************************************************************************************************************
* Macro definitions
***********************************************************************************************************************/
/***********************************************************************************************************************
* Typedef definitions
***********************************************************************************************************************/
/* LAN8720 */
#define ETHER_PHY_REG_SPECIAL_CONTROL_INDICATION 27
#define ETHER_PHY_AMDIXCTRL_DISABLE (1u<<15)
#define ETHER_PHY_CH_SELECT (0u<<13)
/* Standard PHY Registers */
#define ETHER_PHY_REG_CONTROL (0)
#define ETHER_PHY_REG_STATUS (1)
#define ETHER_PHY_REG_IDENTIFIER1 (2)
#define ETHER_PHY_REG_IDENTIFIER2 (3)
#define ETHER_PHY_REG_AN_ADVERTISEMENT (4)
#define ETHER_PHY_REG_AN_LINK_PARTNER (5)
#define ETHER_PHY_REG_AN_EXPANSION (6)
/***********************************************************************************************************************
* Exported global variables (to be accessed by other files)
***********************************************************************************************************************/
/***********************************************************************************************************************
* Exported global function
***********************************************************************************************************************/
void ether_phy_targets_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
bool ether_phy_targets_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
uint32_t line_speed_duplex);
extern uint32_t ether_phy_read(ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t reg_addr);
extern void ether_phy_write(ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t reg_addr, uint32_t data);
/***********************************************************************************************************************
* Private global variables and functions
***********************************************************************************************************************/
/***********************************************************************************************************************
* Functions
**********************************************************************************************************************/
/***********************************************************************************************************************
* Function Name: ether_phy_targets_initialize
* Description : PHY-LSI specific initialization processing
* Arguments : p_api_ctrl -
* Ethernet channel number
* Return Value : none
***********************************************************************************************************************/
void ether_phy_targets_initialize (ether_phy_instance_ctrl_t * p_instance_ctrl)
{
uint32_t reg;
/* HP Auto-MDIX */
/* Read the special control/status indications register (Register Index: 27) */
reg = ether_phy_read(p_instance_ctrl, ETHER_PHY_REG_SPECIAL_CONTROL_INDICATION);
/* Disable Auto-MDIX and set MDI (TX=transmits, RX=receives) */
reg |= (uint16_t) (ETHER_PHY_AMDIXCTRL_DISABLE | ETHER_PHY_CH_SELECT);
/* Write the settings back to the special control/status indications register (Register Index: 27) */
ether_phy_write(p_instance_ctrl, ETHER_PHY_REG_SPECIAL_CONTROL_INDICATION, reg);
#ifdef ETHERNET_PHY_DEBUG
//Dump PHY registers for debugging purpose
lan8720DumpPhyReg(p_instance_ctrl);
#endif
}
/***********************************************************************************************************************
* Function Name: ether_phy_targets_is_support_link_partner_ability
* Description : Check if the PHY-LSI connected Ethernet controller supports link ability
* Arguments : p_instance_ctrl -
* Ethernet control block
* line_speed_duplex -
* Line speed duplex of link partner PHY-LSI
* Return Value : bool
***********************************************************************************************************************/
bool ether_phy_targets_is_support_link_partner_ability (ether_phy_instance_ctrl_t * p_instance_ctrl,
uint32_t line_speed_duplex)
{
FSP_PARAMETER_NOT_USED(p_instance_ctrl);
FSP_PARAMETER_NOT_USED(line_speed_duplex);
/* This PHY-LSI supports half and full duplex mode. */
return true;
} /* End of function ether_phy_targets_is_support_link_partner_ability() */
35.6.2.4. 用户需要实现的函数
用户需要实现的以下函数:
用户需要实现的函数
void updateDhcpResponseToUsr(void)
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
uint32_t ulIPAddress )
const char *pcApplicationHostnameHook(void)
uint32_t ulRand();
uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort );
uint32_t isNetworkUp(void);
BaseType_t vSendPing( const char *pcIPAddress);
void print_ipconfig(void);
void print_pingResult(void);
void dnsQuerryFunc(char *domain_name);
限于篇幅,暂不对这些函数进行详细地讲解,读者可参考例程源代码。
35.7.2.5. net_thread_entry入口函数
在使用 RTOS 并新建了一个线程的情况下,hal_entry 已经不再需要,并且网络线程的入口函数被设置为 net_thread_entry。 net_thread_entry 入口函数如下所示。
代码清单34-3:net_thread_entry入口函数
#include "net_thread.h"
#include "net_user_app.h"
extern char *domain_name;
extern char *remote_ip_address;
extern uint8_t ucMACAddress[ 6 ];
extern uint8_t ucIPAddress[ 4 ];
extern uint8_t ucNetMask[ 4 ];
extern uint8_t ucGatewayAddress[ 4 ];
extern uint8_t ucDNSServerAddress[ 4 ];
extern ping_data_t ping_data;
uint32_t usrPingCount = RESET_VALUE;
static uint32_t usr_print_ability = RESET_VALUE;
/* Net Thread entry function */
/* pvParameters contains TaskHandle_t */
void net_thread_entry(void * pvParameters)
{
FSP_PARAMETER_NOT_USED(pvParameters);
BaseType_t status = pdFALSE;
fsp_pack_version_t version = {RESET_VALUE};
/* 调试串口初始化 */
Debug_UART4_Init();
printf("Hello! FreeRTOS-Plus-TCP\r\n"
"这是一个以太网 DNS & Ping 示例,请把网线接到开发板和路由器进行联网\r\n");
/* 获取 FSP 库版本 */
R_FSP_VersionGet(&version);
/* 打印 FSP 库版本 */
printf("Flex Software Pack Version %d.%d.%d\r\n",
version.version_id_b.major, version.version_id_b.minor, version.version_id_b.patch);
printf("\r\n预置ipconfig:");
print_ipconfig();
/* FreeRTOS IP Initialization: This init initializes the IP stack */
status = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress);
if(pdFALSE == status)
{
printf("FreeRTOS_IPInit Failed\r\n"
"Returned Error Code: 0x%x\r\n", status);
__asm("BKPT #0\n"); /* trap upon the error */
}
/* TODO: add your own code here */
while(1)
{
/* Check if Both the Ethernet Link and IP link are UP */
if(SUCCESS == isNetworkUp())
{
/* usr_print_ability is added to avoid multiple UP messages or Down Messages repeating*/
if(!(PRINT_UP_MSG_DISABLE & usr_print_ability))
{
printf("\r\nNetwork is Up\r\n");
usr_print_ability |= PRINT_UP_MSG_DISABLE;
}
if(!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
#if( ipconfigUSE_DHCP != 0 )
/* Display the New IP credentials obtained from the DHCP server */
updateDhcpResponseToUsr();
#endif
/* Updated IP credentials on to the RTT console */
printf("更新ipconfig:");
print_ipconfig();
/* DNS lookup for the Domain name requested. This is Synchronous Activity */
dnsQuerryFunc(domain_name);
}
if(!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
printf("\r\nPinging %s:\r\n\r\n",(char *)remote_ip_address);
}
while (usrPingCount < USR_PING_COUNT)
{
/* Send a ICMP Ping request to the requested IP address
* USR_PING_COUNT (100) is used in this Example Project
* For Continuous testing the count can be increased to bigger number
*/
status = vSendPing((char *)remote_ip_address);
if(status != pdFALSE)
{
ping_data.sent++;
printf("!"); // Ping请求发送成功
}
else
{
ping_data.lost++;
printf(".");
}
usrPingCount++;
/* Add some delay between Pings */
vTaskDelay(10);
}
if(!(PRINT_NWK_USR_MSG_DISABLE & usr_print_ability))
{
print_pingResult();
usr_print_ability |= PRINT_NWK_USR_MSG_DISABLE;
}
}
else
{
if(!(PRINT_DOWN_MSG_DISABLE & usr_print_ability))
{
printf("\r\nNetwork is Down");
usr_print_ability |= PRINT_DOWN_MSG_DISABLE;
}
else
{
printf(".");
}
}
vTaskDelay(100);
}
}
35.6.3. 下载验证
注解
运行此以太网例程需要先切换芯片DLM状态:从出厂的 “CM” 切换到 “SSD” 状态, 然后重要的是要设置 IDAU 边界。否则,Ethernet 和 EDMAC 将无法使用。
NOTE : On RA MCUs with TrustZone, IDAU boundaries are programmed by this project due to the use of Ethernet and EDMAC peripherals. Consequentially, it is necessary to connect the serial programming interface to meet this requirement.
可按照以下两种方法当中的其中任意一种进行操作后,即可正常使用本实验的以太网例程:
使用 Renesas Flash Programmer 软件手动切换RA6M5芯片的DLM状态,并且设置 IDAU 边界, 具体方法步骤请参考本教程第3章内容。
使用 J-Link 和 e2 studio 的用户可实现自动切换。 需要注意,这里的 J-Link 需要 J-Link V10 及后续的硬件版本,以前的版本以及 JLink EDU mini 不支持该功能。 J-Link 需要通过 JTag 接口连接到启明6M5开发板,SWD接口无法操作, 因为该操作必须在控制 P109(TDO / TXD9)和 P110(TDI / RXD9)、MD 引脚以及复位(RESET)的情况下完成。 然后在启动调试之前还需将 J17 排针上的跳线帽拔出,并插到 J23 排针上短接 SCK 和 MD 引脚, 然后使用 J-Link 在 e2 studio 环境下启动一次调试即可。
首先编译程序,并按照上述方法设置 IDAU 边界,确保能正常使用 Ethernet 和 EDMAC 外设。
将程序下载到开发板后,连接串口并打开串口助手,复位板子让程序运行。
如下图所示,可以看到程序会首先打印提示信息:

当连接网线到路由器上之后,稍等片刻,可以看到正常的程序运行结果如下图所示:

全部0条评论
快来发表一下你的评论吧 !