PIC32MX + FreeRTOS + ENC28J60 + LwIP 构建通讯管理机(通信网关)程序

一、典型通讯管理机功能定义

常见需求:

  • 多串口(RS232/485)采集(Modbus RTU / 自定义协议)
  • 以太网通信(Modbus TCP / MQTT / HTTP)
  • 协议转换(RTU ↔ TCP)
  • 数据缓存、断点续传
  • 远程配置与维护

二、整体软件架构

复制代码
┌────────────────────────────┐
│     应用层(业务协议)       │
│ ModbusTCP / MQTT / HTTP    │
└─────────────▲──────────────┘
              │
┌─────────────┴──────────────┐
│        LwIP 协议栈          │
│   TCP / UDP / DHCP / DNS   │
└─────────────▲──────────────┘
              │
┌─────────────┴──────────────┐
│   ENC28J60 网卡驱动         │
│   SPI + INT + CS           │
└─────────────▲──────────────┘
              │
┌─────────────┴──────────────┐
│     FreeRTOS 内核           │
│  Task / Queue / Semaphore  │
└─────────────▲──────────────┘
              │
┌─────────────┴──────────────┐
│   PIC32MX 外设驱动          │
│ UART / SPI / Timer / GPIO  │
└────────────────────────────┘

三、FreeRTOS 任务划分

任务 优先级 说明
ETH_IF_TASK ENC28J60 数据包接收
LWIP_TCPIP_TASK LwIP 核心线程
MODBUS_TCP_TASK Modbus TCP 处理
UART_POLL_TASK 串口数据采集
PROTOCOL_CONV_TASK 协议转换
SYS_MONITOR_TASK 心跳、看门狗
c 复制代码
#define ETH_IF_TASK_PRIO      (tskIDLE_PRIORITY + 4)
#define LWIP_TASK_PRIO        (tskIDLE_PRIORITY + 5)
#define MODBUS_TCP_PRIO       (tskIDLE_PRIORITY + 3)

四、ENC28J60 + LwIP 移植要点(PIC32MX)

1、SPI 驱动(关键)

ENC28J60 仅支持 SPI 模式 0,0:

c 复制代码
uint8_t enc28j60_read_op(uint8_t op, uint8_t addr)
{
    uint8_t tx[2], rx[2];
    tx[0] = (op << 5) | (addr & 0x1F);
    tx[1] = 0xFF;
    SPI_Transfer(tx, rx, 2);
    return rx[1];
}

注意:

  • SPI 时钟 ≤ 20MHz(PIC32MX 建议 10MHz)
  • CS 必须软件控制
  • ISR 中只置位信号量,不要在中断里调用 LwIP API

2、LwIP 配置(lwipopts.h)

c 复制代码
#define NO_SYS                          0
#define SYS_LIGHTWEIGHT_PROT            1

#define MEM_SIZE                        8192
#define PBUF_POOL_SIZE                  16
#define TCP_MSS                         1460
#define TCP_SND_BUF                     4096
#define TCP_WND                         4096

#define LWIP_NETCONN                    1
#define LWIP_SOCKET                     1

3、网卡接口注册

c 复制代码
struct netif enc28j60_netif;

netif_add(&enc28j60_netif,
          &ipaddr,
          &netmask,
          &gw,
          NULL,
          ethernetif_init,
          ethernet_input);
netif_set_default(&enc28j60_netif);
netif_set_up(&enc28j60_netif);

五、通讯管理机核心逻辑示例

1、串口采集任务

c 复制代码
void UART_Poll_Task(void *arg)
{
    while(1)
    {
        if(UART_Receive(buf, &len))
        {
            xQueueSend(g_uart_queue, buf, portMAX_DELAY);
        }
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

2、Modbus TCP 服务

c 复制代码
static void modbus_tcp_server(void *arg)
{
    struct netconn *conn = netconn_new(NETCONN_TCP);
    netconn_bind(conn, IP_ADDR_ANY, 502);
    netconn_listen(conn);

    while(1)
    {
        struct netconn *newconn;
        if(netconn_accept(conn, &newconn) == ERR_OK)
        {
            modbus_process(newconn);
        }
    }
}

3、协议转换(RTU → TCP)

复制代码
UART_RTU → Queue → ProtocolConvert → TCP Send

Queue + Buffer 解耦

不在线程中做阻塞操作


参考代码 基于pic32MX、FREERTOS、ENC28J60、LWIP编写的通讯管理机程序 www.youwenfan.com/contentcsv/72502.html

六、关键稳定性设计

ENC28J60 常见问题

问题 对策
丢包 增大 PBUF_POOL_SIZE
死机 独立看门狗 + SPI 超时
中断风暴 ISR 只给信号量

FreeRTOS 建议

  • 使用 heap_4.c
  • 所有 LwIP API 必须在 TCPIP 线程或 netconn 线程
  • 禁止在 ISR 中 malloc / free

七、工程目录建议

复制代码
/Project
 ├── App/
 │    ├── modbus_tcp.c
 │    ├── protocol_convert.c
 │    └── uart_task.c
 ├── Drivers/
 │    ├── enc28j60.c
 │    ├── spi.c
 │    └── uart.c
 ├── LwIP/
 ├── FreeRTOS/
 └── main.c
相关推荐
feifeigo1231 小时前
基于 STM32F103C8T6 的恒定水温控制系统
stm32·单片机·嵌入式硬件
SmartRadio1 小时前
STM32WLE5 Smart TDMA 完整工程(STOP2 低功耗终极版)-【10】
stm32·单片机·lora·tdma·低功耗自组网·smart tdma
sxstj2 小时前
stm32最小板和uno I2C能直接连接吗?
stm32·单片机·嵌入式硬件
sxstj2 小时前
5伏的传感器能直接在stm32上使用吗?
stm32·单片机·嵌入式硬件
SmartRadio2 小时前
STM32WLE5 LoRa Smart TDMA 完整协议栈工程实现 -【3】
stm32·单片机·嵌入式硬件·lora·tdma·自组网·smart tdma
SmartRadio3 小时前
STM32WLE5 LoRa Smart TDMA 完整协议栈工程实现 -【4】
stm32·单片机·嵌入式硬件·lora·tdma·低功耗自组网·smart tdma
小麦嵌入式3 小时前
PCB设计笔记(一):51核心板原理图(电源、晶振、复位)
stm32·单片机·嵌入式硬件·mcu·51单片机·硬件工程·pcb设计
嵌入式小站4 小时前
STM32 零基础可移植教程 09:串口收一行命令,用 led on 控制 LED
stm32·单片机·嵌入式硬件
星夜夏空9913 小时前
STM32单片机学习(32) —— ADC
stm32·单片机·学习