GDB, OpenOCD ve arm-none-eabi-gcc kullanarak STM32 keşif panosu ile hata ayıklama mesajlarını gdb konsoluna nasıl yazdırabilirim?


15

OpenOCD, arm-none-eabi-gcc ve gdb kullanarak bir STM32 Cortex M0 keşif panosu (32F0308DISCOVERY) programlıyorum. SWD üzerinden hata ayıklama iletileri günlüğü herhangi bir basit yolu olup olmadığını merak ediyordum. Yarı barındırma seçeneğini okudum, ancak bu newlib veya diğer büyük kütüphaneleri çekmeyi gerektiriyor gibi görünüyor. (Yalnızca 64k flaş kullanılabilir.) SWD üzerinden metin kaydetmenin daha hafif bir yolu var mı, yoksa UART tek pratik seçeneği mi kullanıyor?


1
Yarı barındırma seçeneğini denemenizi öneririm. Gösterge olarak, CooCox (ücretsiz bir Windows Cortex-M ortamı) tarafından M3 / 4 için sunulan kütüphaneler oldukça minimalist, tek baytlık transfer 17 montaj talimatıdır. Eski bir (STM32F4) projenin yarı gölgelenmesi ve -O0 ile yeniden oluşturulması, kod boyutuna 48 bayt ekledi.
markt

Bağlayıcınız kullanılmayan kodu çıkarmayabilir. Alternatiflere gelince, texane'ın stlink araçlarını kullanmak için github repo'su basit bir posta kutusu şemasına sahiptir, ancak henüz denemedim.
Chris Stratton

Yanıtlar:


15

İşaretçiler için teşekkürler, markt ve chris-stratton. Yarı barındırma seçeneğinin oldukça basit olduğu ortaya çıktı. OpenOCD konsoluna mesaj gönderebilen birkaç basit günlük rutininin kaynağını bulmayı başardım. Onları buraya göndereceğim çünkü (i) çalışmak için bazı değişiklikler gerekli ve (ii) Bence bu bilgi yeni başlayan insanlar için bulmak çok kolay değil.

İlk olarak, D kodu burada kolayca aşağıdaki C fonksiyonu sağlamak üzere adapte edilir:

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 konsoluna dize yazmak için send_command çağrısı örneği:

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

İkincisi, burada yorumlarda verilen putChar işlevi iyi çalışır, ancak 0x03 önce bir '#' eklemek zorunda kaldım:

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

Bu işlevlerden çıktıya bakmak için, önce OpenOCD'yi başlattım, sonra arm-none-eabi-gdb kullanarak aşağıdaki gibi bağlanıyorum:

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

İletilerin GDB konsolunda değil, OpenOCD işleminin stdout'unda göründüğünü unutmayın.


1
Bir hata var, sizeof () strlen () olmalıdır.

1
Teşekkürler user107642. Aslında 's' bir işaretçi yerine bir dizi ise sizeof burada kullanmak mümkündür, bu yüzden bu şekilde değiştirdim.
katlanabilir

Mükemmel cevap! Ayrıca yazabilirsiniz putcharolarak basit olarakvoid putchar(char c) { send_command(3,&c); }
MVDs

1
"Sizeof" dizgenin sonundaki \ 0 değerini sayar, strlen bunu yapmaz. Openocd sadece stdout'a ve bir xterm terminal penceresine yazdırırsa, terminal muhtemelen görmezden geleceği için bu fark edilir bir fark yaratmaz. Ama sonuçta bir şeyleri bir dosyaya koyarsanız, sanırım bu sıfırları orada bulmak sizi şaşırtacak. Veya protokol sondaki sonlandırıcı ile dizeleri göndermeniz gerektiğini belirtiyor mu?
user242579

Ah, iyi nokta kullanıcı242579. Sondaki \ 0 değerini hesaba katmak için bir '-1' ekledim.
Aralık'ta katlanır
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.