这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 【MCXN947】实现http发送数据

共1条 1/1 1 跳转至

【MCXN947】实现http发送数据

高工
2025-10-18 10:36:10     打赏

【项目目标】

MCXN947创建lwip,实现动态获取IP,并连接http服务器,实现定时向服务器发送数据。

【硬件】

1、FRDM-MCXN947开发板

2、网线

【软件】

1、MCUXpressoIDE

2、网络数据调器

【实现步骤】

1、使用MCUXpressoIDE导入freertos_dhcp工程示例:

image.png

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

image.png

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

image.png

【程序编写】

编写远程服务器的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链接任任务创建程序

image.png

【效果】

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

image.png

【总结】

通过官方的示例,再添加一个freertos任务,可以快速的实现http的数据交互。





关键词: MCXN947     LWIP     HTTP_POsT    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]