【项目目标】
MCXN947创建lwip,实现动态获取IP,并连接http服务器,实现定时向服务器发送数据。
【硬件】
1、FRDM-MCXN947开发板
2、网线
【软件】
1、MCUXpressoIDE
2、网络数据调器
【实现步骤】
1、使用MCUXpressoIDE导入freertos_dhcp工程示例:

2、导入示例后,编译下载到开发板,接上网线,打开串口终端,确定可以动态获取到IP

3、使用网络调试助手创建一个TCPServer 端口为777

【程序编写】
编写远程服务器的IP地址为电192.168.3.231,远程端口为777,当连上服务器后每5秒发送一次数据:
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/api.h"
#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/sockets.h"
#include <string.h>
#include <stdio.h>
// Server configuration
#define SERVER_IP "192.168.3.231"
#define SERVER_PORT 777
#define SEND_INTERVAL_MS 5000 // Send interval: 5 seconds
#define SOCKET_TIMEOUT_MS 3000 // Socket operation timeout: 3 seconds
// POST data (modify as needed)
static const char *post_data = "temperature=25.5&humidity=60.2&device=mcxn947";
/**
* Set socket timeout for connect/send/recv operations
*/
static void set_socket_timeout(int sockfd)
{
struct timeval timeout;
timeout.tv_sec = SOCKET_TIMEOUT_MS / 1000;
timeout.tv_usec = (SOCKET_TIMEOUT_MS % 1000) * 1000;
// Set send timeout
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
PRINTF("Failed to set send timeout\n");
}
// Set receive timeout
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
PRINTF("Failed to set receive timeout\n");
}
}
/**
* Send HTTP POST request with error handling
*/
static int http_post_request(void)
{
int sockfd = -1;
int ret = -1;
struct sockaddr_in server_addr;
char http_request[512];
int request_len;
// 1. Create TCP socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
PRINTF("[POST] Failed to create socket (err: %d)\n", errno);
return -1;
}
// 2. Set socket timeout to prevent permanent blocking
set_socket_timeout(sockfd);
// 3. Configure server address
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
PRINTF("[POST] Invalid server IP: %s (err: %d)\n", SERVER_IP, errno);
close(sockfd);
return -1;
}
// 4. Connect to server
PRINTF("[POST] Connecting to %s:%d...\n", SERVER_IP, SERVER_PORT);
ret = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret < 0) {
PRINTF("[POST] Connect failed (err: %d)\n", errno);
close(sockfd);
return -1;
}
PRINTF("[POST] Connected successfully\n");
// 5. Build HTTP POST request
request_len = snprintf(http_request, sizeof(http_request),
"POST / HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n"
"Connection: close\r\n"
"\r\n"
"%s",
SERVER_IP, SERVER_PORT,
strlen(post_data),
post_data);
if (request_len >= sizeof(http_request)) {
PRINTF("[POST] Request too long (need %d bytes, buffer: %d)\n", request_len, sizeof(http_request));
close(sockfd);
return -1;
}
// 6. Send request
ret = send(sockfd, http_request, request_len, 0);
if (ret < 0) {
PRINTF("[POST] Send failed (err: %d)\n", errno);
close(sockfd);
return -1;
}
PRINTF("[POST] Sent %d bytes of data\n", ret);
// 7. Receive response (optional, but helpful for debugging)
char recv_buf[1024] = {0};
ret = recv(sockfd, recv_buf, sizeof(recv_buf)-1, 0);
if (ret > 0) {
PRINTF("[POST] Received %d bytes response:\n%s\n", ret, recv_buf);
} else if (ret == 0) {
PRINTF("[POST] Server closed connection after send\n");
} else {
PRINTF("[POST] No response received (err: %d)\n", errno);
}
// 8. Cleanup
close(sockfd);
return 0;
}
/**
* Test task: Cyclically send POST requests with error recovery
*/
static void http_post_test_task(void *arg)
{
(void)arg;
// Wait for network initialization (DHCP ready)
while (1) {
if (netif_default != NULL && (netif_default->flags & NETIF_FLAG_UP)) {
PRINTF("[TASK] Network ready. IP: %s\n", inet_ntoa(netif_default->ip_addr));
break;
}
vTaskDelay(pdMS_TO_TICKS(1000));
PRINTF("[TASK] Waiting for network...\n");
}
// Cyclic send loop with error tolerance
while (1) {
PRINTF("\n[TASK] --- Sending POST request --- \n");
int result = http_post_request();
if (result != 0) {
PRINTF("[TASK] Request failed. Will retry after interval.\n");
} else {
PRINTF("[TASK] Request completed successfully.\n");
}
// Wait for next interval
vTaskDelay(pdMS_TO_TICKS(SEND_INTERVAL_MS));
}
}
/**
* Initialize test task
*/
void http_post_test_init(void)
{
// Create task with sufficient stack size
sys_thread_new("http_post_task", http_post_test_task, NULL, 2048, 3);
PRINTF("[INIT] HTTP POST test task started\n");
}【测试】
在main中添加http链接任任务创建程序

【效果】
打开串口助手,可以看到服务器成功的接收到了MCXN947周期发送的数据:

【总结】
通过官方的示例,再添加一个freertos任务,可以快速的实现http的数据交互。
我要赚赏金
