You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F7与Telit GL865间LWIP PPPoS的LCP协商无法启动问题排查

STM32F7 Nucleo + Telit GL865 GSM PPPoS 问题排查

问题背景

我正在用STM32F7 Nucleo开发板搭配Telit GL865 GSM模块,通过USART1进行通信。原本的流程是先通过AT命令配置模块,之后模块会发送LCP包,但目前模块最终返回NO CARRIER提示,看起来无法处理PPP协商流程。现在有两个核心问题困扰我:

  1. 不确定当前使用的AT命令是否正确(和我参考的ESP-IDF示例中的命令不一样);
  2. 调用pppos_create(&ppp_netif, output_cb, status_cb, 0)之后,status_cb回调函数完全没有被触发。

相关代码(部分截断)

/////////////////////////// Includes
#include "main.h"
#include "stm32f7xx_hal.h"
#include "lwip.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "string.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/api.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/dns.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h"
#include "lwip/apps/netbiosns.h"
#include "lwip/apps/httpd.h"
#include "netif/ppp/pppos.h"
#include "ppp/ppp.h"
#include "lwip/sio.h"
#include "netif/ppp/pppapi.h"
#include "netif/ppp/pppos.h"
#include "netif/ppp/pppoe.h"
#include "netif/ppp/ppp_opts.h"
/////////////////////////////////////////////End of Includes
void SystemClock_Config(void);
#define RX_SIZE 64
///////////////////////////////////////////////////////Variables
uint32_t sysTickCounter = 0;
uint8_t sendData[50] = " \n";
uint8_t recData;
uint8_t receivedValue, connected = 0;
uint32_t recIndex = 0;
uint8_t recBuffer[RX_SIZE];
uint8_t pppLinkStatusCallbackArray[RX_SIZE];
uint8_t sent,sendMeToPPPoS = 0;
ppp_pcb *ppp;
struct netif ppp_netif;
u8_t sio_idx = 0;
sio_fd_t ppp_sio;
uint8_t ATconnected,lcpCame,length = 0;
uint8_t lcpStartIndex, lcpStopIndex,lcpStartOld,lcpStart,lcpStop = 0;
////////////////////////////////////////////////////////////End of Variables
////////////////////////////////////////////////////////////PPP Functions
static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
//this function is never called; however, it must have been called in the main with ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);
struct netif *pppif = ppp_netif(pcb);
LWIP_UNUSED_ARG(ctx);
switch(err_code) {
case PPPERR_NONE: {
printf("status_cb: Connected\n");
printf(" our_ipaddr = %s\r\n", ipaddr_ntoa(&pppif->ip_addr));
printf(" his_ipaddr = %s\r\n", ipaddr_ntoa(&pppif->gw));
printf(" netmask = %s\r\n", ipaddr_ntoa(&pppif->netmask));
connected = 1;
// break;
}
case PPPERR_PARAM: {
printf("status_cb: Invalid parameter\r\n");
break;
}
case PPPERR_OPEN: {
printf("status_cb: Unable to open PPP session\r\n");
break;
}
case PPPERR_DEVICE: {
printf("status_cb: Invalid I/O device for PPP\r\n");
break;
}
case PPPERR_ALLOC: {
printf("status_cb: Unable to allocate resources\r\n");
break;
}
case PPPERR_USER: {
ppp_free();
printf("status_cb: User interrupt\r\n");
break;
}
case PPPERR_CONNECT: {
printf("status_cb: Connection lost\r\n");
break;
}
case PPPERR_AUTHFAIL: {
printf("status_cb: Failed authentication challenge\r\n");
break;
}
case PPPERR_PROTOCOL: {
printf("status_cb: Failed to meet protocol\r\n");
break;
}
case PPPERR_PEERDEAD: {
printf("status_cb: Connection timeout\r\n");
break;
}
case PPPERR_IDLETIMEOUT: {
printf("status_cb: Idle Timeout\r\n");
break;
}
case PPPERR_CONNECTTIME: {
printf("status_cb: Max connect time reached\r\n");
break;
}
case PPPERR_LOOPBACK: {
printf("status_cb: Loopback detected\r\n");
break;
}
default: {
printf("status_cb: Unknown error code %d\r\n", err_code);
break;
}
}
ppp_connect(pcb, 30);//Try to reconnect in 30 seconds
}
static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
//UART output callback for PPPoS
return HAL_UART_Transmit_IT(&huart1, data, sizeof(data));
}
/////////////////////////////////////////////////////////End of PPP Functions
/////////////////////////////////////////////////////////////////////////Main
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_LWIP_Init();
HAL_UART_Receive_IT(&huart1, &recData, 1);
SysTick_Config(SystemCoreClock/1000);
HAL_Delay(300);//delay 300ms
memset(recBuffer, 0, sizeof(recBuffer));//UART receive buffer
HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT\r\n", strlen("AT\r\n"));//send this AT command over UART to GSM module
HAL_Delay(300);
HAL_Delay(300);
memset(rec

排查与解决建议

1. 先搞定AT命令配置的正确性

Telit GL865的PPP配置逻辑和ESP-IDF里的模块差异很大,别直接照搬ESP的命令,得严格参考GL865的 datasheet:

  • 先确认网络注册状态:发送AT+CREG?,如果返回+CREG: 0,1(本地注册)或+CREG: 0,5(漫游注册)才说明模块连上网了,这是PPP协商的前提;
  • 启动PPP会话的正确命令:GL865用AT#PPP=1来开启PPP模式,而不是ESP里可能用到的AT+CGDCONT之后直接触发的逻辑,发送这个命令后模块才会开始发送LCP包;
  • 串口参数必须匹配:GL865默认是115200波特率、8位数据位、无校验、1停止位,你得确保MX_USART1_UART_Init()里的配置和这个完全一致;
  • 别用HAL_Delay等响应:用HAL_Delay()来等模块响应太不靠谱,应该在串口接收中断里判断模块返回的OK或其他响应,确认上一条AT命令执行成功后,再发送下一条,避免命令发送时机错误导致配置失败。

2. 修复PPPoS回调未触发的核心问题

status_cb没触发,本质是PPP栈根本没进入协商流程,先查这几个关键点:

  • output_cb的致命错误:你现在返回HAL_UART_Transmit_IT(&huart1, data, sizeof(data)),sizeof(data)是指针的大小(32位机是4字节),不是实际要发送的len!这会导致PPP发送的帧被截断,模块收不到完整的PPP数据,自然不会响应。改成:
    static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
        //UART output callback for PPPoS
        return HAL_UART_Transmit_IT(&huart1, data, len);
    }
    
  • 必须把串口接收的数据喂给PPP栈:你现在用HAL_UART_Receive_IT接收单个字节,但收到后要调用pppos_input(&ppp_netif, &recData, 1)把数据传给PPP栈,否则PPP栈收不到模块发来的LCP包,根本不会启动协商,status_cb当然不会触发;
  • 检查LWIP配置宏:在lwipopts.h里必须开启:
    #define PPP_SUPPORT 1
    #define PPPOS_SUPPORT 1
    #define PPP_DEBUG 1 // 开启调试方便看日志
    
    如果这些宏没开,PPP功能是禁用的,调用pppos_create也不会有效果;
  • 检查pppos_create的返回值:代码里要判断ppp是否为NULL,如果创建失败,后续流程都不会执行:
    ppp = pppos_create(&ppp_netif, output_cb, status_cb, 0);
    if (ppp == NULL) {
        printf("Failed to create PPPoS PCB!\r\n");
        // 处理错误
    }
    
  • 确认tcpip线程正常运行:MX_LWIP_Init()应该已经启动了tcpip线程,你可以加个日志或者断点确认线程是否在运行。

3. 解决LCP包无法处理和NO CARRIER的问题

模块发送LCP包后返回NO CARRIER,本质是PPP栈没收到或者没回复LCP帧,解决上面的串口数据喂入和output_cb的问题后,PPP栈就能正常和模块进行LCP协商了,这个问题应该会随之解决。

内容的提问来源于stack exchange,提问作者Sarp Engin Daltaban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:03:32