日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

基于ARM Cortex-M和Eclipse的SWO单总线输出

發(fā)布時(shí)間:2024/7/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于ARM Cortex-M和Eclipse的SWO单总线输出 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

????????最近在MCU on Eclipse網(wǎng)站上看到Erich Styger所寫(xiě)的一篇有關(guān)通過(guò)SWD的跟蹤接口SWO獲取ARM Cortex-M相關(guān)信息的文章,文章結(jié)構(gòu)明晰,講解透徹,本人深受啟發(fā),特意將其翻譯過(guò)來(lái)供各位同仁參考。當(dāng)然限于個(gè)人水平,有不當(dāng)之處懇請(qǐng)指正。原文網(wǎng)址:https://mcuoneclipse.com/2016/10/17/tutorial-using-single-wire-output-swo-with-arm-cortex-m-and-eclipse/

?

????????作為一個(gè)標(biāo)準(zhǔn)過(guò)程,我將一些控制臺(tái)功能添加到我的嵌入式應(yīng)用程序中。這樣我就有了一個(gè)命令行接口,可以檢查和修改目標(biāo)系統(tǒng)。ARM Cortex-M的一個(gè)有趣的硬件特性是單線輸出(SWO) ,它允許通過(guò)一根線路將數(shù)據(jù)(例如字符串)發(fā)送到32個(gè)不同的激勵(lì)端口。

?

ARM調(diào)試器接頭上的SWO引腳

調(diào)試跟蹤輸出?SWO

????????我使用普通的UART/SCI作為標(biāo)準(zhǔn)的文本和命令行與目標(biāo)板的接口。然而,在許多板上,UART被應(yīng)用程序使用。

有一個(gè)Semihosting(半托管),但是速度非常慢,而且取決于調(diào)試器和工具鏈/庫(kù),加上需要消耗FLASHRAM,所以我不建議在任何情況下使用Semihosting

【注】Semihosting是針對(duì)ARM目標(biāo)機(jī)的一種機(jī)制,它能夠根據(jù)應(yīng)用程序代碼的輸入/輸出請(qǐng)求,與運(yùn)行有調(diào)試功能的主機(jī)通訊。這種技術(shù)允許主機(jī)為通常沒(méi)有輸入和輸出功能的目標(biāo)硬件提供主機(jī)資源。

????????也有一個(gè)USB CDC,但這需要一個(gè)USB接口,一個(gè)USB棧和一個(gè)具有USB功能的微控制器。不適用于所有情況。

????????還有一個(gè)Segger RTT,它很小,速度快,最好的是不需要任何特殊的引腳。但只能工作于Segger的調(diào)試探測(cè)器。

ARM SWO

????????但還有另一件事:ARM SWO跟蹤端口是由ARMCortexm-M定義的。從技術(shù)上講,SWO是一個(gè)單一的跟蹤引腳,它被用來(lái)以從CPU核心時(shí)鐘中提取一個(gè)特定的時(shí)鐘頻率發(fā)送數(shù)據(jù)包。您可以將SWO看作是一種使用特殊格式發(fā)送數(shù)據(jù)包的UART TX引腳。可以使用多達(dá)32種包類型(或激勵(lì))。發(fā)送什么樣的數(shù)據(jù)取決于應(yīng)用程序,并且只需要很少的CPU處理或代碼。

????????常見(jiàn)SWO用法是:

  • ?按字符串發(fā)送調(diào)試信息
  • ?記錄中斷的進(jìn)入與退出
  • ?記錄函數(shù)的進(jìn)入與退出
  • ?周期性的PC值采樣
  • ?事件提示
  • ?變量或內(nèi)存單元修改超時(shí)

????????最常見(jiàn)的用法之一就是第一種:使用SWOUART樣式打印來(lái)自目標(biāo)的調(diào)試消息。并且這也正是我再這篇文章中將要表達(dá)的。還有另一種編碼(曼徹斯特編碼),這里不做介紹。

ARM CoreSight

????????SWOARM CoreSight調(diào)試功能塊的一部分,而ARM CoreSight則通常是Cortex-M3M4M7的一部分:

?

CoreSight功能塊(來(lái)自:http://www.arm.com/files/pdf/AT_-_Advanced_Debug_of_Cortex-M_Systems.pdf

如上圖所示,通過(guò)SWO(SWV)ITMDWT跟蹤消息可以發(fā)送。對(duì)于指令跟蹤需要4個(gè)額外的跟蹤引腳

SWO引腳

????????使用SWO的前提條件是這個(gè)引腳可以在調(diào)試頭中使用。這是我的TWR-K64F120M板的情況:

?

trace swo引腳(來(lái)自:TWR-K64F120M原理圖)

????????如上圖所示,SWO跟蹤引腳是與JTAG TDO引腳共享的。所以這就意味著SWO不能在JTAG中使用,而只能在SWD中使用。

所以仔細(xì)檢查你板子的原理圖確定他是否支持SWO。例如FRDM-K64F(是TWR-K64F120M上一個(gè)版本),它的SWO是沒(méi)有被引到調(diào)試頭的:

?

FRDM-K64F上沒(méi)有SWO

調(diào)試探針與SWO

????????為了能夠使用SWO,我需要一個(gè)能夠讀取SWO引腳的調(diào)試探測(cè)器。例如,Freescale/NXP OpenSDAFreedomTower模塊板載調(diào)試接口硬件就不支持SWO

????????然而,外部的Segger J-Link卻支持SWO引腳。下面我有一個(gè)J-Link EDU連接到TWR-K64F120M板的調(diào)試和跟蹤端口:

?

j-link edu連接到跟蹤端口

通過(guò)SWO引腳發(fā)送調(diào)試信息的源碼

????????為了通過(guò)SWO寫(xiě)調(diào)試消息到主機(jī),需要一小段代碼。在Github上有一個(gè)可用的完整代碼的例子項(xiàng)目:

https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/TWR-K64F120M/TWR-K64F120M_Demo/Sources

????????外部工具(比如Segger RTT查看器)可以在硬件中設(shè)置SWO。我的建議是從應(yīng)用程序初始化它。因?yàn)?/span>SWO跟蹤輸出時(shí)鐘是從CPU時(shí)鐘派生而來(lái)的,所以初始化函數(shù)需要這個(gè)時(shí)鐘加上SWO端口號(hào)來(lái)初始化。下面是我用來(lái)初始化SWO輸出的代碼,默認(rèn)為64k波特率:

/*!

?* \brief Initialize the SWO trace port for debug message printing

?* \param portBits Port bit mask to be configured

?* \param cpuCoreFreqHz CPU core clock frequency in Hz

?*/

void SWO_Init(uint32_t portBits, uint32_t cpuCoreFreqHz) {

??uint32_t SWOSpeed = 64000; /* default 64k baud rate */

??uint32_t SWOPrescaler = (cpuCoreFreqHz / SWOSpeed) - 1; /* SWOSpeed in Hz, note that cpuCoreFreqHz is expected to be match the CPU core clock */

?

??CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; /* enable trace in core debug */

??*((volatile unsigned *)(ITM_BASE + 0x400F0)) = 0x00000002; /* "Selected PIN Protocol Register": Select which protocol to use for trace output (2: SWO NRZ, 1: SWO Manchester encoding) */

??*((volatile unsigned *)(ITM_BASE + 0x40010)) = SWOPrescaler; /* "Async Clock Prescaler Register". Scale the baud rate of the asynchronous output */

??*((volatile unsigned *)(ITM_BASE + 0x00FB0)) = 0xC5ACCE55; /* ITM Lock Access Register, C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC */

??ITM->TCR = ITM_TCR_TraceBusID_Msk | ITM_TCR_SWOENA_Msk | ITM_TCR_SYNCENA_Msk | ITM_TCR_ITMENA_Msk; /* ITM Trace Control Register */

??ITM->TPR = ITM_TPR_PRIVMASK_Msk; /* ITM Trace Privilege Register */

??ITM->TER = portBits; /* ITM Trace Enable Register. Enabled tracing on stimulus ports. One bit per stimulus port. */

??*((volatile unsigned *)(ITM_BASE + 0x01000)) = 0x400003FE; /* DWT_CTRL */

??*((volatile unsigned *)(ITM_BASE + 0x40304)) = 0x00000100; /* Formatter and Flush Control Register */

}

????????在我的主應(yīng)用程序中,我像這樣初始化它(對(duì)于一個(gè)有24MHz核心時(shí)鐘的系統(tǒng))

#define CPU_CORE_FREQUENCY_HZ 120000000 /* CPU core frequency in Hz */

?SWO_Init(0x1, CPU_CORE_FREQUENCY_HZ);

SWO_PrintChar()函數(shù)中完成打印:

/*!

?* \brief Sends a character over the SWO channel

?* \param c Character to be sent

?* \param portNo SWO channel number, value in the range of 0 to 31

?*/

void SWO_PrintChar(char c, uint8_t portNo) {

??volatile int timeout;

?

??/* Check if Trace Control Register (ITM->TCR at 0xE0000E80) is set */

??if ((ITM->TCR&ITM_TCR_ITMENA_Msk) == 0) { /* check Trace Control Register if ITM trace is enabled*/

????return; /* not enabled? */

??}

??/* Check if the requested channel stimulus port (ITM->TER at 0xE0000E00) is enabled */

??if ((ITM->TER & (1ul<<portNo))==0) { /* check Trace Enable Register if requested port is enabled */

????return; /* requested port not enabled? */

??}

??timeout = 5000; /* arbitrary timeout value */

??while (ITM->PORT[0].u32 == 0) {

????/* Wait until STIMx is ready, then send data */

????timeout--;

????if (timeout==0) {

??????return; /* not able to send */

????}

??}

??ITM->PORT[0].u16 = 0x08 | (c<<8);

}

????????上面的代碼使用了一個(gè)非常簡(jiǎn)單的超時(shí)機(jī)制:重要的一點(diǎn)是,如果SWO沒(méi)有啟用或者SWO端口沒(méi)有準(zhǔn)備好,那么應(yīng)用程序就會(huì)被阻塞。

????????為了更方便地打印字符串,我使用以下函數(shù):

/*!

?* \brief Sends a string over SWO to the host

?* \param s String to send

?* \param portNumber Port number, 0-31, use 0 for normal debug strings

?*/

void SWO_PrintString(const char *s, uint8_t portNumber) {

??while (*s!='\0') {

????SWO_PrintChar(*s++, portNumber);

??}

}

????????要通過(guò)SWO發(fā)送一個(gè)“hello”,它就像這樣簡(jiǎn)單:

SWO_PrintString("hello world with SWO\r\n", 0);

????????第一個(gè)參數(shù)是要發(fā)送的字符串,第二個(gè)是SWO跟蹤通道號(hào)。

GNU ARM Eclipse查看器

????????要接收主機(jī)上的SWO跟蹤輸出,GNU ARM Eclipse插件內(nèi)置了Segger J-Link探測(cè)器的SWO支持。

????????SWO僅支持SWD(單線調(diào)試)模式,不支持JTAG模式。所以確保SWD被選為調(diào)試協(xié)議:

?

SWD調(diào)試

????????在GNU ARM Eclipse調(diào)試配置中,啟用SWO并指定CPU頻率和SWO頻率(請(qǐng)參見(jiàn)http://gnuarmeclipse.github.io/debug/jlink/上的有關(guān)頻率的文檔)。我必須提供CPU頻率(在我的情況下為120 MHz),并且可以將SWO頻率設(shè)置為0,以便J-Link自動(dòng)確定速度)。在端口掩碼中指定使用的端口(作為位掩碼),因此0x1用于使用端口0

?

SWO的設(shè)置

????????這樣,在目標(biāo)板上運(yùn)行應(yīng)用程序就會(huì)在Eclipse控制臺(tái)視圖中顯示輸出:

?

Eclipse控制臺(tái)視圖

Segger SWO Viewer

????????Segger有一個(gè)特殊的SWO Viewer(命令行和GUI版本)。

????????在GUI版本中,我指定使用的設(shè)備,它可以感測(cè)跟蹤時(shí)鐘:

?

segger gui swo viewer

????????在查看器中,我可以打開(kāi)/關(guān)閉端口,并查看收到的數(shù)據(jù):

?

segger j-link swo viewer

Telnet: Putty

????????但是,沒(méi)有需要查看SWO數(shù)據(jù)的花哨的查看器或EclipseSegger默認(rèn)使用端口2332

?

SEGGER SWO端口

????????我可以配置任何telnet客戶端(例如PuTTY)在端口2332上打開(kāi)會(huì)話:

?

putty telnet會(huì)話設(shè)置

????????我在PuTTY中得到的輸出:

?

SWOPuTTY中的輸出

綜述

????????ARM SWO跟蹤引腳允許向主機(jī)發(fā)送跟蹤消息。一個(gè)常見(jiàn)的用法是向主機(jī)發(fā)送調(diào)試或其他消息。SWO只需要一個(gè)引腳,僅適用于SWD(而不是JTAG),并且在目標(biāo)上需要很少的代碼和資源。不幸的是,許多電路板沒(méi)有將SWO跟蹤引腳路由到調(diào)試頭,因此如果您正在進(jìn)行自己的設(shè)計(jì),則至少應(yīng)考慮將SWO路由到調(diào)試頭。

????????雖然SWO跟蹤輸出很大,但是限于高端Cortex-M,我沒(méi)有在Cortex-M0+)中找到它,它只是輸出,需要一個(gè)支持它的調(diào)試探針/接口。至少與EclipseGNU ARM Eclipse插件結(jié)合Segger J-Link探針SWO輸出對(duì)我來(lái)說(shuō)非常棒。

????????另一方面,Segger RTT的功能更加多樣化,也非常快。它適用于所有ARM Cortex,最重要的是不需要額外的引腳。然而,它在目標(biāo)系統(tǒng)上需要更多的開(kāi)銷和RAM資源。此外,它允許發(fā)送和接收數(shù)據(jù)。所以對(duì)于串行調(diào)試消息打印,Segger RTT對(duì)我來(lái)說(shuō)聽(tīng)起來(lái)更好的解決方案。

????????接下來(lái)就是快樂(lè)SWO中了!

相關(guān)鏈接

  • ?SWO on Kinetishttps//community.nxp.com/thread/318058
  • ?SWOGNU ARM Eclipse插件:http : //gnuarmeclipse.github.io/debug/jlink/
  • ?Segger SWO Viewerhttps : //www.segger.com/j-link-swo-viewer.html
  • ?GNU ARM Eclipse插件:http : //gnuarmeclipse.github.io/debug/
  • ?Eclipse RxTx插件,用于解析SWO數(shù)據(jù):http : //forum.segger.com/index.php? page=Thread&threadID=1010
  • ?ARM CoreSight概述:http : //www.arm.com/files/pdf/AT_-_Advanced_Debug_of_Cortex-M_Systems.pdf
  • ?GitHub上的示例代碼:https//github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/TWR-K64F120M/TWR-K64F120M_Demo/Sources

歡迎關(guān)注:


總結(jié)

以上是生活随笔為你收集整理的基于ARM Cortex-M和Eclipse的SWO单总线输出的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。