Dzięki za wskazówki, markt i chris-stratton. Opcja półhostingu okazała się dość prosta. Udało mi się znaleźć źródło kilku prostych procedur rejestrowania, które mogą wysyłać wiadomości do konsoli OpenOCD. Zamieszczę je tutaj, ponieważ (i) wymagały one modyfikacji, aby działały oraz (ii) Myślę, że te informacje nie są bardzo łatwe do znalezienia dla osób, które dopiero zaczynają.
Pierwszy kod D tutaj łatwo dostosowany, aby zapewnić następującą funkcję: 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");
}
Przykład wywołania polecenia send_command w celu napisania ciągu znaków do konsoli 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);
Po drugie, funkcja putChar podana w komentarzach tutaj działa dobrze, z tym wyjątkiem, że musiałem dodać „#” przed 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"
);
}
Aby zobaczyć wyniki tych funkcji, najpierw uruchamiam OpenOCD, a następnie łączę się za pomocą arm-none-eabi-gdb w następujący sposób:
target remote localhost:3333
monitor arm semihosting enable
monitor reset halt
load code.elf
continue
Zauważ, że komunikaty pojawiają się na standardowym etapie procesu OpenOCD, a nie na konsoli GDB.