本帖最后由 shipeng 于 2023-12-23 17:14 编辑
不知道我用的是不是最新版,总之用了互斥量就一堆的问题,各种报Assert错误,我也不知道是不是因为谁上锁谁解锁的原因导致的。总之如果遵循谁上锁谁解锁的原则使用互斥量就可以运行。否则就会报各种ASSERT错误。如果把互斥量换成二值信号量就没有这个问题。
下面是我的源码,说一下我的软件逻辑:每次DMA传输完成后启动一个10毫秒定时器,在定时器回调函数中Give互斥量。从而保证帧最小间隔为10毫秒,以防止发送帧粘连。
- SemaphoreHandle_t DMA2C5MuxSem_Handle = NULL;
-
- TimerHandle_t xHandleTimerU4Tx = NULL;
-
- TaskHandle_t xHandleTaskU4TX = NULL;
-
- static void U4TxTimerCallback(void);
- static void CreateU4TxFrameDelay(TickType_t xTimerPeriodInTicks );
- static void vTaskU4TX_Handler(void *pvParameters);
- void UART4_DMA_Init(void);
- void BSP_UART4_Init(void);
-
- void BSP_USART_Config(void)
- {
- BSP_UART4_Init();
- UART4_DMA_Init();
- NVIC_EnableIRQRequest(UART4_IRQn, 2, 0);
- USART_EnableInterrupt(UART4, USART_INT_IDLE);
-
- USART_EnableDMA(UART4, USART_DMA_TX_RX);
- U4RxQueue = xQueueCreate(U4RX_QUE_DEPTH, U4RX_QUE_SIZE);
- if (NULL==U4RxQueue)printf("U4RxQueue Creating Failed!\r\n");
- U4TxQueue = xQueueCreate(4, 4);
- if (NULL==U4TxQueue)printf("U4TxQueue Creating Failed!\r\n");
- #ifndef USE_DMA_WITH_MUTEX
- DMA2C5MuxSem_Handle = xSemaphoreCreateBinary();
- #else
- DMA2C5MuxSem_Handle = xSemaphoreCreateMutex();
- #endif
- if (NULL==DMA2C5MuxSem_Handle)printf("DMA2C5MuxSem Creating Failed!\r\n");
- #ifndef USE_DMA_WITH_MUTEX
- else if (0==uxSemaphoreGetCount(DMA2C5MuxSem_Handle) && pdPASS!=xSemaphoreGive(DMA2C5MuxSem_Handle))printf("DMA2C5MuxSem Giving Failed!\r\n");
- #endif
- CreateU4TxFrameDelay(10);
- xTaskCreate((TaskFunction_t )vTaskU4TX_Handler,
- (const char* )"UART4 TX Task",
- (uint16_t )256,
- (void* )NULL,
- (UBaseType_t )5,
- (TaskHandle_t* )&xHandleTaskU4TX);
-
- }
-
- static void U4TxTimerCallback(void)
- {
- #ifndef USE_DMA_WITH_MUTEX
- if (0==uxSemaphoreGetCount(DMA2C5MuxSem_Handle) && pdPASS != xSemaphoreGive( DMA2C5MuxSem_Handle))printf("DMA2C5MuxSem Giving failed!");
- #else
- if (NULL!=xSemaphoreGetMutexHolder(DMA2C5MuxSem_Handle) && pdPASS != xSemaphoreGive( DMA2C5MuxSem_Handle))printf("DMA2C5MuxSem Giving failed!");
- #endif
- else if (0!=uxQueueMessagesWaiting(U4TxQueue))portYIELD();
- }
-
- static void CreateU4TxFrameDelay(TickType_t xTimerPeriodInTicks )
- {
- xHandleTimerU4Tx = xTimerCreate("U4TxTimer",xTimerPeriodInTicks,pdFALSE,(void*)3,(TimerCallbackFunction_t)U4TxTimerCallback);
- if (NULL==xHandleTimerU4Tx)printf("U4TxTimer Creating failed!");
- }
-
- static void vTaskU4TX_Handler(void *pvParameters)
- {
- UsartTxRxBuffer_t *tx_buffer;
- while(1)
- {
- if (pdPASS==xQueueReceive(U4TxQueue, (uint8_t*)&tx_buffer, portMAX_DELAY))
- {
- xSemaphoreTake(DMA2C5MuxSem_Handle, 5689U);
- if (0!=tx_buffer->length)
- {
-
- DMA_Disable(DMA2_Channel5);
- memcpy(DMA_UART4_TxBuf,tx_buffer->DatArea,tx_buffer->length);
- DMA2_Channel5->CHNDATA_B.NDATA = tx_buffer->length;
-
- DMA_Enable(DMA2_Channel5);
- }
- if (NULL!=tx_buffer)vPortFree((uint8_t*)tx_buffer);
- }
- }
- }
-
- void DMA2_Channel5_IRQHandler(void)
- {
- if (RESET != DMA_ReadIntFlag(DMA2_INT_FLAG_TC5))
- {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- DMA_ClearIntFlag(DMA2_INT_FLAG_TC5);
- if (NULL!=xHandleTimerU4Tx)
- {
- xTimerResetFromISR(xHandleTimerU4Tx,&xHigherPriorityTaskWoken);
- }
- }
- }
-
- void UART4_DMA_Init(void)
- {
- DMA_Config_T dmaConfig;
-
-
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA2);
-
-
- dmaConfig.peripheralBaseAddr = UART4_DR_ADDRESS;
- dmaConfig.memoryBaseAddr = (uint32_t)DMA_UART4_TxBuf;
- dmaConfig.dir = DMA_DIR_PERIPHERAL_DST;
- dmaConfig.bufferSize = 0;
- dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
- dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;
- dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_BYTE;
- dmaConfig.memoryDataSize = DMA_MEMORY_DATA_SIZE_BYTE;
- dmaConfig.loopMode = DMA_MODE_NORMAL;
- dmaConfig.priority = DMA_PRIORITY_HIGH;
- dmaConfig.M2M = DMA_M2MEN_DISABLE;
-
-
- DMA_Config(DMA2_Channel5, &dmaConfig);
-
-
- DMA_Enable(DMA2_Channel5);
-
- NVIC_EnableIRQRequest(DMA2_Channel5_IRQn, 3, 0);
- DMA_EnableInterrupt(DMA2_Channel5, DMA_INT_TC);
-
-
- dmaConfig.dir = DMA_DIR_PERIPHERAL_SRC;
- dmaConfig.loopMode = DMA_MODE_CIRCULAR;
- dmaConfig.bufferSize = sizeof(DMA_UART4_RxBuf);
- dmaConfig.memoryBaseAddr = (uint32_t)DMA_UART4_RxBuf;
-
- DMA_Config(DMA2_Channel3, &dmaConfig);
-
-
- DMA_Enable(DMA2_Channel3);
-
-
-
- }
-
- void BSP_UART4_Init(void)
- {
- GPIO_Config_T GPIO_ConfigStructure;
- USART_Config_T USART_ConfigStruct;
-
- RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOC));
- RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_UART4));
-
-
- GPIO_ConfigStructure.pin = GPIO_PIN_10;
- GPIO_ConfigStructure.speed = GPIO_SPEED_50MHz;
- GPIO_ConfigStructure.mode = GPIO_MODE_AF_PP;
- GPIO_Config(GPIOC, &GPIO_ConfigStructure);
-
-
- GPIO_ConfigStructure.pin = GPIO_PIN_11;
- GPIO_ConfigStructure.mode = GPIO_MODE_IN_FLOATING;
- GPIO_Config(GPIOC, &GPIO_ConfigStructure);
-
- USART_ConfigStruct.baudRate = 115200;
- USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
- USART_ConfigStruct.mode = USART_MODE_TX_RX;
- USART_ConfigStruct.parity = USART_PARITY_NONE;
- USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
- USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
- USART_Config(UART4, &USART_ConfigStruct);
-
- USART_Enable(UART4);
-
- }
-
|