ฉันจะพิมพ์ข้อความดีบั๊กไปยังคอนโซล gdb ด้วยบอร์ดค้นพบ STM32 โดยใช้ GDB, OpenOCD และ arm-none-eabi-gcc ได้อย่างไร


15

ฉันกำลังเขียนโปรแกรมค้นพบบอร์ด STM32 Cortex M0 (32F0308DISCOVERY) โดยใช้ OpenOCD, arm-none-eabi-gcc และ gdb ฉันสงสัยว่ามีวิธีที่ตรงไปตรงมาในการบันทึกข้อความดีบั๊กผ่าน SWD ฉันได้อ่านเกี่ยวกับตัวเลือกการกำหนดเซมาสเตอรีแล้ว แต่ดูเหมือนว่าจะต้องมีการดึงใน newlib หรือไลบรารีขนาดใหญ่อื่น ๆ (มีแฟลชเพียง 64k เท่านั้น) มีวิธีที่มีน้ำหนักเบากว่าในการบันทึกข้อความผ่าน SWD หรือใช้ UART เป็นตัวเลือกที่ใช้งานได้จริงหรือไม่?


1
ฉันขอแนะนำให้คุณลองใช้ตัวเลือกการกระจายสัญญาณ ตามข้อบ่งชี้ห้องสมุดที่นำเสนอโดย CooCox (สภาพแวดล้อม Windows Cortex-M ฟรี) สำหรับ M3 / 4 นั้นค่อนข้างเรียบง่ายการถ่ายโอนไบต์เดียวคือ 17 คำแนะนำในการประกอบ การสร้างโปรเจ็กต์เก่า (STM32F4) อีกครั้งด้วยเซมิโคลอนและ -O0 เพิ่ม 48 ไบต์ให้กับขนาดโค้ด
เครื่องหมาย

คุณอาจไม่มีตัวเชื่อมโยงที่ไม่ได้ใช้รหัส สำหรับทางเลือก repo github ของ texane สำหรับการขับเคลื่อนเครื่องมือ stlink นั้นมีรูปแบบการรับเมล์บอกซ์ที่ง่าย ๆ แต่ฉันยังไม่ได้ลองเลย
Chris Stratton

คำตอบ:


15

ขอบคุณสำหรับพอยน์เตอร์, markt และ chris-stratton ตัวเลือกการส่งสัญญาณกลับกลายเป็นเรื่องที่ค่อนข้างตรงไปตรงมา ฉันจัดการเพื่อค้นหาแหล่งที่มาสำหรับสองสามขั้นตอนการบันทึกง่าย ๆ ที่สามารถส่งข้อความไปยังคอนโซล OpenOCD ฉันจะโพสต์ไว้ที่นี่เนื่องจาก (i) พวกเขาต้องการการแก้ไขเพื่อให้ทำงานได้และ (ii) ฉันคิดว่าข้อมูลนี้ไม่ใช่เรื่องง่ายที่จะหาคนที่เพิ่งจะเริ่มต้น

อันดับแรกรหัส D ที่นี่สามารถปรับเปลี่ยนได้ง่ายเพื่อให้ฟังก์ชั่น C ต่อไปนี้:

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");
}

ตัวอย่างของการเรียก send_command เพื่อเขียนสตริงไปยังคอนโซล OpenOCD:

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);

ประการที่สองฟังก์ชั่น putChar ที่ได้รับในความคิดเห็นที่นี่ทำงานได้ดียกเว้นว่าฉันต้องเพิ่ม '#' ก่อน 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 ก่อนจากนั้นเชื่อมต่อโดยใช้ arm-none-eabi-gdb ดังนี้

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

โปรดทราบว่าข้อความปรากฏใน stdout ของกระบวนการ OpenOCD ไม่ใช่ที่คอนโซล GDB


1
มีข้อผิดพลาด sizeof () ควรเป็น strlen ()

1
ขอบคุณ user107642 ในความเป็นจริงมันเป็นไปได้ที่จะใช้ sizeof ที่นี่ถ้า 's' เป็นอาร์เรย์แทนที่จะเป็นตัวชี้ดังนั้นฉันจึงแก้ไขมันในแบบนั้น
foldl

คำตอบที่ดี! คุณสามารถเขียนได้putcharง่ายเหมือนvoid putchar(char c) { send_command(3,&c); }
mvds

1
"sizeof" จะนับตามท้าย \ 0 ของสตริงในขณะที่ strlen จะไม่ หาก openocd เพิ่งพิมพ์ไปที่ stdout และหน้าต่างเทอร์มินัล xterm นั่นอาจจะไม่สร้างความแตกต่างที่น่าสังเกตเพราะเทอร์มินัลอาจไม่สนใจมัน แต่ถ้าคุณวางสิ่งต่าง ๆ ลงในไฟล์ฉันคิดว่าคุณจะประหลาดใจเมื่อพบเลขศูนย์ในนั้น หรือโปรโตคอลระบุว่าคุณต้องการส่งสตริงด้วยเทอร์มิเนลต่อท้ายหรือไม่?
242579

อ่าผู้ใช้จุดดี 242579 ฉันได้เพิ่ม '-1' เพื่อคำนึงถึงส่วนท้าย \ 0
foldl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.