मैं GDB, OpenOCD और आर्म-नो-एग्बी-जीसीसी का उपयोग करके STM32 डिस्कवरी बोर्ड के साथ gdb कंसोल पर डिबग संदेश कैसे प्रिंट करूं?


15

मैं OpenOCD, arm-none-eabi-gcc और gdb का उपयोग करके STM32 Cortex M0 डिस्कवरी बोर्ड (32F0308DISCOVERY) की प्रोग्रामिंग कर रहा हूँ। मैं सोच रहा था कि क्या SWD पर डिबग संदेश लॉग करने का कोई सीधा रास्ता है। मैंने सेमीहोस्टिंग विकल्प के बारे में पढ़ा है, लेकिन ऐसा लगता है कि न्यूलिब या अन्य बड़े पुस्तकालयों में खींचने की आवश्यकता है। (वहाँ केवल 64k फ्लैश उपलब्ध है।) क्या SWD पर पाठ लॉग करने के लिए कोई और अधिक हल्का तरीका है, या UART एकमात्र व्यावहारिक विकल्प का उपयोग कर रहा है?


1
मेरा सुझाव है कि आप सेमीहोस्टिंग विकल्प का प्रयास करें। संकेत के माध्यम से, M3 / 4 के लिए CooCox (एक मुफ्त विंडोज कॉर्टेक्स-एम पर्यावरण) द्वारा पेश किए गए पुस्तकालय बहुत कम से कम हैं, उनका एकल-बाइट हस्तांतरण 17 विधानसभा निर्देश हैं। एक पुराने (STM32F4) प्रोजेक्ट का पुनर्निर्माण उनके सेमीहोस्टिंग के साथ और -0 ने कोड आकार में 48 बाइट्स जोड़े।
चिह्न

आपके पास आपका लिंकर अप्रयुक्त कोड नहीं हो सकता है। विकल्प के रूप में, स्टिंक उपकरण चलाने के लिए टेक्साने के जीथब रेपो में एक साधारण मेलबॉक्सिंग योजना है, हालांकि मैंने अभी तक इसकी कोशिश नहीं की है।
क्रिस स्ट्रैटन

जवाबों:


15

संकेत के लिए धन्यवाद, निशान और क्रिस-स्ट्रैटन। सेमीहोस्टिंग विकल्प काफी सीधा था। मैं सरल लॉगिंग दिनचर्या के एक जोड़े के लिए स्रोत खोजने में कामयाब रहा, जो ओपनओसीडी कंसोल को संदेश भेज सकता है। मैं उन्हें यहाँ पोस्ट करूँगा क्योंकि (i) उन्हें काम करने के लिए कुछ संशोधन की आवश्यकता थी और (ii) मुझे लगता है कि यह जानकारी उन लोगों के लिए खोजना आसान नहीं है जो अभी शुरू कर रहे हैं।

सबसे पहले, यहाँ डी कोड आसानी से निम्नलिखित सी फ़ंक्शन प्रदान करने के लिए अनुकूलित है:

void send_command(int command, void *message)
{
   asm("mov r0, %[cmd];"
       "mov r1, %[msg];"
       "bkpt #0xAB"
         :
         : [cmd] "r" (command), [msg] "r" (message)
         : "r0", "r1", "memory");
}

OpenOCD कंसोल को स्ट्रिंग लिखने के लिए send_command पर कॉल करने का उदाहरण:

const char s[] = "Hello world\n";
uint32_t m[] = { 2/*stderr*/, (uint32_t)s, sizeof(s)/sizeof(char) - 1 };
send_command(0x05/* some interrupt ID */, m);

दूसरा, यहाँ टिप्पणियों में दिया गया पुष्ट कार्य ठीक काम करता है, सिवाय इसके कि मुझे 0x03 से पहले '#' जोड़ना था:

void put_char(char c)
{
    asm (
    "mov r0, #0x03\n"   /* SYS_WRITEC */
    "mov r1, %[msg]\n"
    "bkpt #0xAB\n"
    :
    : [msg] "r" (&c)
    : "r0", "r1"
    );
}

इन कार्यों से आउटपुट को देखने के लिए, मैं सबसे पहले OpenOCD को शुरू करता हूं, फिर हाथ-कोई-ईबी-जीडीपी का उपयोग करके कनेक्ट करें:

target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load code.elf
continue

ध्यान दें कि संदेश OpenOCD प्रक्रिया के स्टॉपआउट पर दिखाई देते हैं, GDB कंसोल पर नहीं।


1
एक बग है, साइज़ोफ़ () स्ट्रेलन () होना चाहिए।

1
धन्यवाद user107642 वास्तव में यह संभव है कि यहां साइज़ोफ का उपयोग किया जाए यदि 's' एक पॉइंटर के बजाय एक सरणी है, तो मैंने इसे इस तरह से संशोधित किया है।
foldl

बहुत बढ़िया जवाब! आप यह भी putcharसरल रूप में लिख सकते हैंvoid putchar(char c) { send_command(3,&c); }
mvds

1
"Sizeof" स्ट्रिंग के अनुगामी \ 0 की गिनती करेगा, जबकि स्ट्रलेन नहीं करेगा। अगर ओपेनकास्ट सिर्फ स्टैडआउट और एक xterm टर्मिनल विंडो को प्रिंट करता है, तो संभवतः यह ध्यान देने योग्य अंतर नहीं करेगा क्योंकि टर्मिनल शायद इसे अनदेखा करेगा। लेकिन अगर आप चीजों को एक फाइल में डालते हैं, तो मुझे लगता है कि आप वहां उन शून्य को खोजने के लिए आश्चर्यचकित होंगे। या प्रोटोकॉल निर्दिष्ट करता है कि आपको अनुगामी टर्मिनेटर के साथ तार भेजने की आवश्यकता है?
user242579

आह, अच्छी बात user242579। मैंने ट्रेलिंग \ 0 को ध्यान में रखने के लिए एक '-1' जोड़ा है।
तह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.