在實作 UART DMA TX 時發生怪異現象就是有時候無法正常輸出字串到終端機
以下是無法正常運作的程式
#include "ti_msp_dl_config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
volatile bool gCheckUART = false;
volatile bool gDMADone = false;
#define LOG_MAX_LENGTH 128
void UART_Console_Write(const char *data, ...)
{
char log_buf[LOG_MAX_LENGTH] = { 0 };
va_list args;
va_start(args, data);
vsnprintf(log_buf, LOG_MAX_LENGTH, data, args);
va_end(args);
DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(log_buf));
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA));
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, strlen(log_buf));
DL_SYSCTL_disableSleepOnExit();
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
DL_UART_Main_enableDMATransmitEvent(UART_0_INST);
while (false == gDMADone) {
__WFE();
}
DL_UART_Main_disableDMATransmitEvent(UART_0_INST);
while (false == gCheckUART) {
__WFE();
}
gCheckUART = false;
gDMADone = false;
}
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
DL_SYSCTL_disableSleepOnExit();
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
while (1) {
;
}
}
void UART_0_INST_IRQHandler(void)
{
switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
case DL_UART_MAIN_IIDX_EOT_DONE:
gCheckUART = true;
break;
case DL_UART_MAIN_IIDX_DMA_DONE_TX:
gDMADone = true;
break;
default:
break;
}
}
可是如果在 main() 裡多加輸出一串字串又可正常運作。如下紅字所示:
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
DL_SYSCTL_disableSleepOnExit();
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
UART_Console_Write("%s: %s %s\r\n", __FUNCTION__, __DATE__, __TIME__);
while (1) {
;
}
}
可正常運作及無法常運作的案例有很多情況。例如以下寫法也實無法輸出字串
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
DL_SYSCTL_disableSleepOnExit();
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
while (1) {
;
}
}
但變成以下寫法又可正常輸出:
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
DL_SYSCTL_disableSleepOnExit();
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
UART_Console_Write("%s: %s %s\r\n", __FUNCTION__, __DATE__, __TIME__);
while (1) {
;
}
}
觀察發現正常時候的 .map 檔裡的 SEGMENT ALLOCATION MAP:如下:

而無法正常輸出的都會變成配置:

請協助解決這個問題,謝謝!