場景:
RTT打印僅占用JLINK的帶寬,比串口傳輸更快更簡潔,同時RTT可以使用jscope對代碼里面的變量實時繪圖顯示波形,而采用串口打印波形無法實時打印。同時可以保存原始數據到本地進行分析,RTT在各方面完勝串口。
問題描述
正常使用RTT沒有太大的問題,而對FLASH進行分區后,跳轉不同的分區需要重新連接RTT才可以輸出,造成極大的不便。
原因分析:
RTT跳轉后,都會重新初始化RTT的block地址,就會導致RTT VIEWER不能及時識別新的blcik地址,從對應的地址取數據顯示了。那么通過固定RTT的block地址是不是就可以了,打開SEGGER_RTT.c在290行的位置,注銷_SEGGER_RTT
_acDownBuffer
_acUpBuffer
的初始化,將其固定在0x2000000的地址,如下:
// #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
// #if ((defined __GNUC__) || (defined __clang__))
// SEGGER_RTT_CB _SEGGER_RTT __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
// static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
// static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
// #elif (defined __ICCARM__)
// #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
// SEGGER_RTT_CB _SEGGER_RTT;
// #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
// static char _acUpBuffer [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)];
// #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
// static char _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)];
// #else
// #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned"
// #endif
// #else
// SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
// SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP]));
// SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
// #endif__attribute__((section(".ARM.__at_0x20000000"))) SEGGER_RTT_CB _SEGGER_RTT;
__attribute__((section(".ARM.__at_0x200000B0"))) static char _acDownBuffer[BUFFER_SIZE_DOWN];
__attribute__((section(".ARM.__at_0x200000C0"))) static char _acUpBuffer[BUFFER_SIZE_UP];
但是發現還是不行,每次燒錄完芯片都要重新連接RTT,而且要很久,RTT每次都要搜索地址很費時間,搜索block后,分區都已經跳轉完畢,跳轉前的信息無法查看。最后需要RTT VIEWER中的地址為固定地址后就實時打印跳轉的信息了。
結果:
測試后發現分區跳轉后可以打印,但是還是存在偶爾打印缺失的情況,查找后發現block中還有內容未被RTT VIEWER讀取就執行了跳轉,block里面的內容被重置,也就無法讀取了,在跳轉前判斷一下block是否還有內容就Ok了,跳轉的內容如下:
uint32_t *inputAddr; // !聲明為全局變量,防止執行__set_MSP后,變量被釋放
uint32_t jumpAddr; // !設置MSP后改變了棧底地址,導致原來的局部變量范圍出了新棧的空間,被系統釋放void JumpToCode(uint32_t addr) {inputAddr = (uint32_t *)addr;jumpAddr = *(uint32_t *)(addr + 4);if ((*inputAddr & 0x2FFE0000) == 0x20000000) {// 等待rtt打印完畢 超時退出, rtt viewer中需要指定block地址,避免搜索地址耗費太長時間uint32_t start = HAL_GetTick();while (SEGGER_RTT_GetBytesInBuffer(0) > 0) {if (HAL_GetTick() - start > 100)break;}HAL_RCC_DeInit();HAL_DeInit();__set_FAULTMASK(1);__set_CONTROL(0);__set_MSP(*inputAddr);((void (*)(void))jumpAddr)();}
}