请问一下这个该怎么办
stm32H723运行lwip正常,只要加上ADC使用dma就连不上网络了,通过抓包软件也看不到有SYN码,LWIP报错Assertion "pbuf_free: p->ref > 0" failed at line 753 in ../Middlewares/Third_Party/LwIP/src/core/pbuf.c
![](https://profile-avatar.csdnimg.cn/default.jpg!4)
STM32+LWIP+ADC+DMA
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
关注
引自免费微信小程序:皆我百晓生
在您的情况下,STM32H723使用LWIP网络库时,加入ADC DMA后导致网络连接失败,并且出现了内存管理错误。这可能是由于ADC DMA操作与LWIP中的任务调度、内存池管理之间存在冲突。为了解决这个问题,您可以尝试以下几个步骤:
- 检查ADC DMA配置: 确保ADC的DMA配置正确无误,包括触发源、通道选择、传输大小等。
// 在这里配置ADC DMA ADC_HandleTypeDef hadc; DMA_HandleTypeDef hdma_adc; hadc.Instance = ADC1; // 根据实际使用的ADC选择实例 hdma_adc.Instance = DMA1_Channel2; // 根据实际使用的DMA选择通道 // 配置ADC // ... // 配置DMA hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc.Init.MemInc = DMA_MINC_ENABLE; hdma_adc.Init.PeriphDataAlignment = DMA_DATAALIGN_WORD; hdma_adc.Init.MemDataAlignment = DMA_DATAALIGN_WORD; hdma_adc.Init.Mode = DMA_CIRCULAR; hdma_adc.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_Init(&hdma_adc); // 连接ADC到DMA __HAL_LINKDMA(hadc, HDMA_Handle, hdma_adc);
- 调整中断优先级: 确保ADC DMA中断的优先级低于LWIP相关的任务(例如TCP/IP中断)。这可以通过修改NVIC中断优先级寄存器设置实现。
// 获取当前ADC DMA中断优先级 uint32_t priority = NVIC_GetPriority(ADC_IRQn); // 设置一个较低的优先级,比如抢占优先级为4,响应优先级为0 priority = __NVIC_SET_PRIORITY(ADC_IRQn, 4, 0); NVIC_SetPriority(ADC_IRQn, priority); // 同样地,可能还需要调整其他相关中断
- 使用互斥锁保护LWIP内存池: 当ADC DMA读取ADC数据时,它可能会访问LWIP的内存池。为了避免并发访问引发的问题,可以使用互斥锁来保护内存池。
首先,在头文件中包含
semphr.h
,然后创建一个互斥锁变量。#include "semphr.h" SemaphoreHandle_t adc_dma_semaphore = NULL;
在ADC DMA完成回调函数中获取和释放互斥锁。
void HAL_ADCExConversionCompleteCallback(ADC_HandleTypeDef* hadc) { SemaphoreGiveFromISR(adc_dma_semaphore, NULL); } void adc_dma_start() { SemaphoreCreateBinary(adc_dma_semaphore); // ... 其他ADC DMA初始化代码 HAL_NVIC_EnableIRQ(ADC_IRQn); // 开启ADC中断 }
在ADC DMA中断处理程序中,使用
SemaphoreTakeFromISR()
获取锁,然后在处理完ADC数据后调用SemaphoreGiveFromISR()
释放锁。void ADC_IRQHandler(void) { if (HAL_ADC_GetITStatus(hadc, ADC_IT_EOC) != RESET) { HAL_ADC_IRQHandler(hadc); SemaphoreTakeFromISR(adc_dma_semaphore, NULL); // 处理ADC数据 SemaphoreGiveFromISR(adc_dma_semaphore, NULL); HAL_NVIC_ClearPendingIRQ(ADC_IRQn); } }
- 检查LWIP堆栈配置: 确保LWIP的内存池足够大,可以容纳所有预期的数据包。如果内存池太小,可能会导致上述的内存管理错误。
#define MEMP_POOL_SIZE 800 // 增加内存池大小,根据需求调整 #define MEMP_NUM_TCP_PCB 10 // 根据需求调整 #define MEMP_NUM_UDP_PCB 10 // 根据需求调整 #define MEMP_NUM_RAW_PCB 10 // 根据需求调整 #define MEMP_NUM_FRAG 10 // 根据需求调整 #define MEMP_NUM_SYSMOB 20 // 根据需求调整 struct memp上下文{ struct list { struct list *next; } list; }; extern struct memp上下文 MempFree[memp上下文总共];
执行以上步骤后,应该能解决LWIP与ADC DMA之间的冲突。然而,如果问题依然存在,请考虑使用调试工具进一步分析,例如使用RTOS调试工具查看任务切换情况,或者使用硬件断点检查ADC DMA和LWIP任务之间的交互。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 三分类机器学习模型可视化分析
- ¥15 本地测试网站127.0.0.1 已拒绝连接,如何解决?(标签-ubuntu)
- ¥50 Qt在release捕获异常并跟踪堆栈(有Demo,跑一下环境再回答)
- ¥30 python,LLM 文本提炼
- ¥15 关于将inet引入的相关问题
- ¥15 关于一个倒计时的操作和显示设计
- ¥15 提问STK的问题,哪位航天领域的同学会啊
- ¥15 苹果系统的mac m1芯片的笔记本使用ce修改器使用不了
- ¥15 单相逆变的电压电流双闭环中进行低通滤波PID算法改进
- ¥15 关于#java#的问题,请各位专家解答!