查询以太网配置过程
文件路径: /drivers/board.h
/*-------------------------- ETH CONFIG BEGIN --------------------------*/
/** if you want to use eth you can use the following instructions.
*
* STEP 1, define macro related to the eth
* such as BSP_USING_ETH
*
* STEP 2, copy your eth init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end if board.c file
* such as void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
*
* STEP 3, modify your stm32xxxx_hal_config.h file to support eth peripherals. define macro related to the peripherals
* such as #define HAL_ETH_MODULE_ENABLED
*
* STEP 4, config your phy type
* such as #define PHY_USING_LAN8720A
* #define PHY_USING_DM9161CEP
* #define PHY_USING_DP83848C
* STEP 5, implement your phy reset function in the end of board.c file
* void phy_reset(void)
*
* STEP 6, config your lwip or other network stack
*
*/
注释中详细描述了以太网配置过程,
-
使能rtt以太网驱动
打开 /drivers/board.h 启用BSP_USING_ETH宏定义,根据芯片启用相应的phy,我的是lan8720,这启用PHY_USING_LAN8720A宏定义。 -
初始化RMII接口硬件
通过 stm32cubemx工具使能RMII硬件,在一下路径
\Core\Src\stm32f7xx_hal_msp.c中将HAL_ETH_MspInit拷贝到 /drivers/board.c中并根据硬件添加phy复位函数phy_reset
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(ethHandle->Instance==ETH) { /* ETH clock enable */ __HAL_RCC_ETH_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**ETH GPIO Configuration PC1 ------> ETH_MDC PA1 ------> ETH_REF_CLK PA2 ------> ETH_MDIO PA7 ------> ETH_CRS_DV PC4 ------> ETH_RXD0 PC5 ------> ETH_RXD1 PB11 ------> ETH_TX_EN PB12 ------> ETH_TXD0 PB13 ------> ETH_TXD1 */ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } } #define RESET_IO GET_PIN(D, 0) void phy_reset(void) { rt_pin_mode(RESET_IO, PIN_MODE_OUTPUT); rt_pin_write(RESET_IO, PIN_HIGH); rt_thread_mdelay(50); rt_pin_write(RESET_IO, PIN_LOW); rt_thread_mdelay(50); rt_pin_write(RESET_IO, PIN_HIGH); }
-
打开相应的HAL库
打开 /drivers/ stm32f7xx_hal_conf.h
使能 #define HAL_ETH_MODULE_ENABLED -
添加lwip协议栈
打开 RT-Thread Settings->选择lwip使能rtt lwip协议栈 打开 RT-Thread Settings-->跟多配置 |组件 |---->RT-Thrad组件 | |---->网络 | |---->轻量级TCP/IP协议栈 | |---->使能LWIP堆栈 √
-
验证
msh />list_device device type ref count -------- -------------------- ---------- W25Q256 Block Device 1 qspi10 SPI Device 0 spi40 SPI Device 0 e0 Network Interface 0 msh />ping 192.168.1.100 60 bytes from 192.168.1.100 icmp_seq=0 ttl=64 time=1 ms 60 bytes from 192.168.1.100 icmp_seq=1 ttl=64 time=0 ms 60 bytes from 192.168.1.100 icmp_seq=2 ttl=64 time=1 ms 60 bytes from 192.168.1.100 icmp_seq=3 ttl=64 time=1 ms
添加网络接口设备
打开 RT-Thread Settings->选择lwip
使能rtt lwip协议栈
打开 RT-Thread Settings-->跟多配置
|组件
|---->RT-Thrad组件
| |---->网络
| |---->网络接口设备
| |---->使能网络接口设备 √
添加套接字抽象层
打开 RT-Thread Settings->选择lwip
使能rtt lwip协议栈
打开 RT-Thread Settings-->跟多配置
|组件
|---->RT-Thrad组件
| |---->网络
| |---->套接字抽象层
| |---->使能套接字抽象层 √
测试代码
#include <rtthread.h>
#include <arpa/inet.h>
#include <netdev.h>
#include <sal_socket.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <rtthread.h>
#include <sys/socket.h>
#include <netdb.h>
/* RT-Thread 官网,支持 TLS 功能 */
//#define SAL_TLS_HOST "www.rt-thread.org"
//#define SAL_TLS_PORT 443
#define SAL_TLS_HOST "192.168.1.100"
#define SAL_TLS_PORT 8088
#define SAL_TLS_BUFSZ 1024
static const char *send_data = "GET /download/rt-thread.txt HTTP/1.1\r\n"
"Host: www.rt-thread.org\r\n"
"User-Agent: rtthread/4.0.1 rtt\r\n\r\n";
void sal_tls_test(void)
{
int ret, i;
char *recv_data;
struct hostent *host;
int sock = -1, bytes_received;
struct sockaddr_in server_addr;
/* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
host = gethostbyname(SAL_TLS_HOST);
recv_data = rt_calloc(1, SAL_TLS_BUFSZ);
if (recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return;
}
/* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */
// if ((sock = socket(AF_INET, SOCK_STREAM, PROTOCOL_TLS)) < 0)
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
rt_kprintf("Socket error\n");
goto __exit;
}
/* 初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SAL_TLS_PORT);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
{
rt_kprintf("Connect fail!\n");
goto __exit;
}
/* 发送数据到 socket 连接 */
ret = send(sock, send_data, strlen(send_data), 0);
if (ret <= 0)
{
rt_kprintf("send error,close the socket.\n");
goto __exit;
}
/* 接收并打印响应的数据,使用加密数据传输 */
bytes_received = recv(sock, recv_data, SAL_TLS_BUFSZ - 1, 0);
if (bytes_received <= 0)
{
rt_kprintf("received error,close the socket.\n");
goto __exit;
}
rt_kprintf("recv data:\n");
for (i = 0; i < bytes_received; i++)
{
rt_kprintf("%c", recv_data[i]);
}
__exit:
if (recv_data)
rt_free(recv_data);
if (sock >= 0)
closesocket(sock);
}
#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT(sal_tls_test, SAL TLS function test);
#endif /* FINSH_USING_MSH */
服务器侧操作:
设置服务器pc IP地址位 192.168.1.100
打开网络调试助手,选择tcpserver,监听端口填写8088,打开端口
验证:
串口调试助手
msh />sal_tls_test
服务器
[2020-11-25 11:06:32.407]# RECV ASCII FROM 192.168.1.101 :49153>
GET /download/rt-thread.txt HTTP/1.1
Host: www.rt-thread.org
User-Agent: rtthread/4.0.1 rtt
串口调试助手
recv data:
http://www.cmsoft.cn