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
相关推荐
小程序设计7 小时前
基于STM32的智慧厨房多参数安全监测与预警系统设计
stm32·嵌入式硬件·安全
新晨单片机设计8 小时前
S008C-基于STM32单片机无线抢答器【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·无线抢答器
Zw-awa8 小时前
Delay_us 与 Delay_ms:用 SysTick 做一把可靠的时间尺
stm32
小程序设计10 小时前
基于STM32森林火灾远程监测模块设计
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi12 小时前
基于STM32单片机汽车充电桩控制模块设计(论文+源码)
stm32·单片机·汽车·毕业设计
逐梦之程12 小时前
嵌入式固件升级IAP及调试软件
stm32·单片机
ebiobiz13 小时前
STM32F4 Unity 单元测试与多次测试失败率统计详细步骤
stm32·unity·单元测试
Brilliantwxx14 小时前
【STM32】 I2C 中断模式收发数据实战:从阻塞到中断的架构改造(AT24C02)
stm32·单片机·嵌入式硬件
星河单片机15 小时前
单片机成品方案:基于STM32单片机智能门禁系统
stm32·单片机·嵌入式硬件
en.en..17 小时前
STM 与 ARM
stm32