大家好,我正在使用 S32DS3.5 和 RTD4.0.0 在 S32G274A 的 M7_0 内核上开发软件,并使用 FreeRTOS、Linflexd_Uart 和 Lwip 作为元器件。在调试过程中,我发现 GMAC0 和 Linflexd UART0 不能同时稳定工作。我使用 Linflexd_Uart 输出 printf 的内容。日志显示初始化完成,应用程序启动后,可以循环打印每个 FreeRTOS 任务的状态。但是我无法 ping 通主板的 IP 地址。如果我注释掉 printf 调用或禁用 _write 中的 UART 传输,则上电或复位后,板就可以 ping 通了。这里的问题可能是什么?printf 函数是否会导致 GMAC0 无法接收数据?我应该如何解决这个问题?感谢您提出的任何建议。
可以分享一下错误日志吗?
正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg正常.jpg
exception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpgexception.jpg例外.jpg
左侧的图表显示了程序正常运行的情况,而右侧的图表显示了发生异常后的行为:无法 ping 通电路板,并且日志输出卡在固定位置。
你好, @williams_ww
感谢分享。
据我了解,printf() 本身不应该导致 S32G274A GMAC0 硬件停止接收帧。更可能的问题是,你的 printf > _write > Linflexd_Uart 路径干扰了 FreeRTOS/lwIP/GMAC 软件的时序。
由于我对你的详细实现不太确定,我建议检查一下 `_write()` 函数内部是否存在代码块,将 UART 输出移到一个低优先级的日志记录任务中等等,以缩小可能的范围。
BR
陈银
IP地址192.168.7.200是什么?这是您GMAC设置的一部分吗?
当 GMAC 相关连接不稳定时,您还可以查看 AN14063 S32G2 硬件设计指南。
以下哪种工作模式适合您的设计?
db16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.pngdb16122_0-1788253582320.png
db16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.pngdb16122_1-1788253600524.png
“应用建议的更改后,问题仍然存在。”
根据支持团队的建议,我修改了原有的打印逻辑,将数据写入缓冲区,如下所示:
静态字符缓冲区[64*1024+1];
volatile char buffer_to_print = 0;
void my_printf(const char *format , ...)
{
va_list 参数;
如果(1 == buffer_to_print)
{
返回 ;
}
va_start(args,format);
vsnprintf(buffer,sizeof(buffer),format,args);
va_end(args);
buffer_to_print = 1;
}
我创建了一个优先级为 0 的任务,它的优先级低于所有其他任务:
void my_printf_flush()
{
如果(buffer_to_print)
{
Linflexd_Uart_Ip_AbortSendingData(0);
Linflexd_Uart_Ip_SyncSend(0,(uint8*)buffer,strlen(buffer),3000000);
buffer_to_print = 0;
}
}
void PrintfTaskDemo(void *pvParameters)
{
(void)pvParameters;
为了(;;)
{
my_printf_flush();
vTaskDelay(pdMS_TO_TICKS(10));
}
}
// 这里是打印的内容,但为什么每次只打印 PRINT_HEAP_INFO,而 taskInfo 却不打印呢?
为了(;;)
{
ZRSleep(1000);// 休眠 1 秒
PRINT_HEAP_INFO; // 打印剩余堆大小
vTaskList(taskInfo); // 获取 FreeRTOS 所有任务状态
ZRLOG(ZRLOG_USER_INFO,taskInfo); // 调用 my_printf 函数写入缓冲区
ZRSleep(1000); //睡眠 1 秒
}
当前行为是:任务 PrintfTaskDemo 可以正常打印内容(未启用 DMA),但 GMAC0 上的 IP 地址有时仍然无法访问,网络功能不稳定。
我的 linker_ram.ld 中的 SRAM 大小为 3MB(在 S32G274A M7_0 上),编译设置和 FreeRTOS 堆大小似乎都是正常的。
如果您需要进一步的说明或技术建议来解决问题,请告诉我。
你好, @williams_ww
感谢您的回复。
您似乎使用了阻塞式方法( Linflexd_Uart_Ip_SyncSend ),请问您是否尝试过非阻塞式 API(Linflexd_Uart_Ip_AsyncSend)?
BR
陈银
你好, @williams_ww
感谢您的回复。
我有一些建议:
1. 首先确认一下您的 UART 驱动程序使用的是哪种设置,是轮询模式还是中断模式?
2. 如果当前是轮询模式,请将其更改为中断模式。此外,请检查 UART 和 GMAC 中断的优先级,并将 UART 中断的优先级设置为低于 GMAC 中断,然后再试一次。
BR
陈银
GMAC配置基本按照官方示例程序进行。 ip.jpgip.jpgip.jpgip.jpgip.jpg
code.jpgcode.jpgcode.jpgcode.jpgcode.jpg
dev.jpgdev.jpgdev.jpgdev.jpgdev.jpg
使用中断模式会使情况更糟。
可能出现了硬件错误。我检查了UART同步发送接口的内部实现。我注释掉了相关代码。 暂停所有中断 我修改了相关代码,并在调用同步发送接口前添加了锁定保护,但问题仍然存在。因此,我认为这与UART同步发送逻辑关系不大。我怀疑是硬件故障导致lwip和UART都崩溃了。
你好, @williams_ww
感谢您的回复。
从软件角度来看,您遇到的问题可能是由于频繁的 UART TX/RX 中断抢占了以太网中断处理,从而增加了 RX 处理延迟并导致丢包。
除了我们讨论过的技巧之外,UART/网络中断的优先级也会产生影响,所以我建议尝试将UART中断的优先级设置得比网络中断的优先级低一些,看看效果如何。
BR
陈银