Как дождаться символов от UART и передать обратно по UART в ARM Cortex-M3, эмулированном Qemu

Пытаюсь сделать эхо полученных данных по UART, т.е. дождаться символов с UART и передать обратно по UART. Я эмулирую плату LM3S811 в QEMU. Я приложил файл .c и код запуска и компоновщика. Я получаю ошибки при компиляции файла .c, и я не знаю, правильный ли подход для выполнения эха данных, полученных по UART. Было бы полезно, если бы были предоставлены какие-либо ссылки, объясняющие программирование на «голом железе» с нуля. Спасибо.

main.c

#define  U0RBR (*((volatile unsigned int *) 0x4000C000))
#define  U0DLL (*((volatile unsigned int *) 0x4000C000))
#define  U0THR (*((volatile unsigned int *) 0x4000C000))
#define  U0LCR (*((volatile unsigned int *) 0x4000C00C))
#define  U0DLM (*((volatile unsigned int *) 0x4000C004))
#define  U0LSR (*((volatile unsigned int *) 0x4000C014))

void UART0_init(void);
unsigned char UART0_RxChar(void);
void UART0_TxChar(char ch);

void UART0_init(void)
{
    volatile unsigned int PINSEL0 = 0x0;

    PINSEL0 = 0x00000005;
    U0LCR = 0x83;
    U0DLM = 0x00;
    U0DLL = 0x61;
    U0LCR = 0x03;
}


unsigned char UART0_RxChar(void)
{
    while ((U0LSR & 0x01) == 0);
        return U0RBR;
}

void UART0_TxChar(char ch)
{
    U0THR = ch;
    while ((U0LSR & 0x40) == 0);
}

int main(void)
{
    char receive;

    UART0_init();
    while (1) {
        receive = UART0_Rxchar();
        UART0_TxChar(receive);

    }
    return 0;
}

запуск.s

.thumb
.global start
start:
.word 0x20001000
.word main

flash.ld

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00002000
}

SECTIONS 
{
    .text : {
        *(.vectors);
        *(.text);
        etext = .;
    } > FLASH

    .rodata : {
        *(.rodata);
    } > FLASH

    .data : {
        sdata = .;
        *(.data);
        edata = .;
    } > SRAM AT > FLASH


    .bss : {
        sbss = .;
        *(.bss);
        ebss = .;
    } > SRAM
}

Ошибки при компиляции команды файла .c: arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 - c main.c -o main.o

main.c:7:2: error: 'PINSEL0' undeclared (first use in this function)
  PINSEL0 = PINSEL0 | 0x00000005;
  ^
main.c:7:2: note: each undeclared identifier is reported only once for each function it appears in
main.c:8:2: error: 'UOLCR' undeclared (first use in this function)
  UOLCR = 0x83;
  ^
main.c:9:2: error: 'U0DLM' undeclared (first use in this function)
  U0DLM = 0x00;
  ^
main.c:10:2: error: 'U0DLL' undeclared (first use in this function)
  U0DLL = 0x61;
  ^
main.c:11:2: error: 'U0LCR' undeclared (first use in this function)
  U0LCR = 0x03;

После добавления адреса регистра в Qemu печатается только символ «a», и я не могу ввести его в терминале. Вызванная команда была qemu-system-arm -M lm3s811evb -kernel main.bin -monitor stdio


person Paulson Raja L    schedule 20.07.2020    source источник
comment
Вы, видимо, забыли включить заголовок, содержащий адреса ваших регистров.   -  person Jester    schedule 20.07.2020
comment
почти уверен, что у него нет uart 16550 ... прочитайте документацию для этой части. (после того, как вы исправите код и определите регистры).   -  person old_timer    schedule 21.07.2020
comment
@Шут. Спасибо за комментарий, но я не могу получить регистрационный адрес U0LSR, UODLL, не могли бы вы предоставить какую-либо ссылку или помочь найти адрес регистров. Спасибо.   -  person Paulson Raja L    schedule 21.07.2020
comment
документация на деталь содержит адреса каждого из этих регистров. достаточно просто погуглить номер детали, или зайдите на ti.com, затем найдите LM3S811 и загрузите техническое описание, для этой части на этом сайте один документ содержит как адреса, так и описания регистров (у некоторых поставщиков/деталей есть техническое описание и одно или для полной картины требуется больше отдельных справочных руководств).   -  person old_timer    schedule 21.07.2020
comment
@old_timer Спасибо, сэр, я отредактировал ответ, и даже после адреса регистра я получаю только символ «а», напечатанный в терминале. Не могли бы вы помочь мне с этим, так как я работаю над этим очень долго и не могу получить желаемый результат. Спасибо.   -  person Paulson Raja L    schedule 21.07.2020
comment
хорошо, у вас есть документация, так что вы уже знаете регистр данных, теперь вам нужно посмотреть регистр состояния (uart_fr или что-то в этом роде) и найти rx не пустым (проверить пустой статус rx и, если он не пустой, то прочитать следующий символ ). аналогичным образом ищите tx не полный, ждите не полный, тогда вы можете отправить символ.   -  person old_timer    schedule 21.07.2020
comment
это симулятор, поэтому вам, вероятно, не нужно точно настраивать часть (включить uart0, включить gpio, настроить контакты gpio для альтернативной функции uart, настроить скорость передачи данных uart, биты, четность, стоповые биты и т. д.), мы знаем, что tx вам не нужен чтобы сделать это, так что, вероятно, не нужно делать это, чтобы получить и т. д.   -  person old_timer    schedule 21.07.2020
comment
@old_timer, спасибо, сэр, когда я просматривал документацию, там не было таких регистров, как UOLSR, UODLM, UODLL. Я смущен тем, иду ли я по правильному пути. Было бы полезно, если бы был предоставлен какой-либо фрагмент кода. Извините, что беспокою вас снова и снова. Спасибо.   -  person Paulson Raja L    schedule 21.07.2020
comment
Давайте продолжим обсуждение в чате.   -  person Paulson Raja L    schedule 21.07.2020
comment
Документ, который я скачал с ti Таблица 2-4. Карта памяти показывает базовый адрес для таких вещей, как UART0. И затем описания регистров для UART находятся в главе 11. Включая значения сброса, но UART вы обычно записываете весь регистр, а не чтение-изменение-запись (например, gpio, где регистр охватывает многие/все контакты, и вы хочу возиться только с одним контактом и будет выполнять чтение-изменение-запись).   -  person old_timer    schedule 22.07.2020
comment
между этим и предыдущим вопросом у вас есть все, что вам нужно.   -  person old_timer    schedule 22.07.2020
comment
на самом деле, если посмотреть еще раз, этот документ выполнен в стиле nxp, он дает вам базовый адрес в каждом описании регистра, вам не нужно смотреть на карту памяти, просто перейдите прямо к описанию регистра.   -  person old_timer    schedule 22.07.2020