英特尔伽利略裸机UART [英] Intel Galileo bare metal UART

查看:50
本文介绍了英特尔伽利略裸机UART的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Intel Galileo 板上编写一个小hello world"裸机应用程序.当然,使用 UEFI 打印文本(到 UART-1)效果很好,但我想在没有 UEFI 任何帮助的情况下手动"访问 UART.

I want to program a little "hello world" bare metal application on the Intel Galileo board. Using UEFI to print out text (to UART-1) works well, of course, but I want to access the UART "manually", without any help from UEFI.

在 QEMU 中,我的代码运行良好:

In QEMU my code works well:

#define COM1_PORT (0x03F8)
#define UART_PORT (COM1_PORT)

enum uart_port_offs_t
{   //          DLAB RW
    THR = 0, //   0   W  Transmitter Holding Buffer
    RBR = 0, //   0  R   Receiver Buffer
    DLL = 0, //   1  RW  Divisor Latch Low Byte
    IER = 1, //   0  RW  Interrupt Enable Register
    DLH = 1, //   1  RW  Divisor Latch High Byte
    IIR = 2, //   -  R   Interrupt Identification Register
    FCR = 2, //   -  RW  FIFO Control Register
    LCR = 3, //   -  RW  Line Control Register
    MCR = 4, //   -  RW  Modem Control Register
    LSR = 5, //   -  R   Line Status Register
    MSR = 6, //   -  R   Modem Status Register
    SR  = 7, //   -  RW  Scratch Register
};

.c 文件

void uart_init(void)
{
    outb(UART_PORT + IER, 0x00); // Disable all interrupts

    outb(UART_PORT + LCR, LCR_DLAB);
    outb(UART_PORT + DLL, BAUD_LL); // Set divisor (lo byte)
    outb(UART_PORT + DLH, BAUD_HL); //             (hi byte)
    outb(UART_PORT + LCR, LCR_WORD_BITS_8 | LCR_PAR_NONE | LCR_STOP_BITS_1);
    outb(UART_PORT + FCR, FCR_ENABLE | FCR_CLR_RECV | FCR_CLR_SEND | FCR_TRIGGER_16);
    outb(UART_PORT + MCR, MCR_DSR | MCR_RTS | MCR_AUX2);
}

ssize_t uart_write(const char *buf, size_t len)
{
    size_t written = 0;
    while (written < len) {
        while (!is_output_empty()) {
            asm volatile ("pause");
        }
        outb(UART_PORT + THR, buf[written]);
        ++written;
    }
    return written;
}

主要

SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Exiting EFI boot services ...\r\n");
SystemTable->BootServices->ExitBootServices(ImageHandle, map_key);

uart_init();

while (1) {
    const char s[] = "UART\r\n";
    uart_write(s, sizeof (s) - 1);
}

规格对我没有太大帮助.我猜英特尔 Galileo 板上的 UART 不使用/模拟普通/传统 COM 端口 3F8h、2F8h、3E8h 或 2E8h.

The specs did not help me very much. I guess that the UARTs on the Intel Galileo board don't use/emulate the normal/legacy COM ports 3F8h, 2F8h, 3E8h, or 2E8h.

谁能告诉我我做错了什么,甚至可以发布一个最小的裸机 hello world 示例?

Can anyone tell me what I am doing wrong, or even post a minimal bare metal hello world example?

推荐答案

我假设您的目标是串行端口,它是 Intel Galileo 板上的类音频"连接器.

I assume you are aiming at the serial port that is the "audio-like" connector on the Intel Galileo board.

以下是一些应该会有所帮助的资源:

Here are a few resources that should help:

  • 伽利略原理图
  • 英特尔 Quark SoC X1000 数据表
  • 英特尔伽利略 IO 映射
  • Sergey 的关于为伽利略配置串行端口的博客条目
  • 英特尔 Quark 板支持包下载,包括
    • Galileo schematic
    • Intel Quark SoC X1000 datasheet
    • Intel Galileo IO Mapping
    • Sergey's blog entry about Configuring the Serial Port for Galileo
    • Intel Quark Board Support Package downloads, including
      • Board Support Package Sources (currently ver.1.0.0)
      • Intel Quark SoC X1000 UEFI Firmware Writer’s Guide

      关于此 UART 的注意事项:

      • 这个串口作为 UART1 从 QUARK 芯片出来(见原理图).
      • 您可能需要操作一些 GPIO(有关在 Linux 中执行此操作的信息,请参阅 Sergey 的博客):
        • gpio4:此 GPIO 控制 UART 信号和一些其他连接到 Quark SoC 的信号(例如 SPI 和快速 I/O)的电平转换器.向该 GPIO 写入1"可启用电平转换器.
        • gpio40:此 GPIO 控制引脚 0 的多路复用器.向此 GPIO 写入0"会将引脚 0 连接到 UART 的 RxD(接收数据)信号.
        • gpio41:此 GPIO 控制引脚 1 的多路复用器.向此 GPIO 写入0"会将引脚 1 连接到 UART 的 TxD(传输数据)信号.
        • This serial port comes out of the QUARK chip as UART1 (see the schematics).
        • There are a few GPIOs that you may need to manipulate (see Sergey's blog for doing this in Linux):
          • gpio4: This GPIO controls level shifter for UART signals and some other signals connected to Quark SoC, such as SPI and fast I/O. Writing '1' to this GPIO enables level shifter.
          • gpio40: This GPIO controls multiplexer for pin 0. Writing '0' to this GPIO connects pin 0 to UART's RxD (receive data) signal.
          • gpio41: This GPIO controls multiplexer for pin 1. Writing '0' to this GPIO connects pin 1 to UART's TxD (transmit data) signal.
          • 寄存器DLH,DLL指定波特率
          • 决定您是需要 DMA 模式(第 18.3.1 章)、FIFO 中断模式(第 18.3.2 章)还是 FIFO 轮询模式(第 18.3.3 章).恕我直言,后者更简单但效果较差.前者还要求您正确配置 DMA.

          由于第 18 章(大约 67 页的有用信息)有很多内容需要阅读,因此我不会在此处重新输入所有内容,请阅读数据表并相应地配置寄存器.

          Since there is quite a bit to read for chapter 18 (~67 pages of useful information), I'm not going to retype all that here, please read the datasheet and configure the registers accordingly.

          一般注意事项:

          • 对于裸机方法,首先确保您的启动程序正确,配置所有时钟选项、GPIO 默认模式和值、计时器(如果有)等.对于启动清单,请阅读 X1000UEFI 固件编写者指南(启动该芯片需要做的大约 18 件事).之后,我将使用 GPIO 上的简单LED 闪烁"应用程序对其进行验证.

          • For bare-metal approach first make sure that your boot procedure is correct, configuring all the clocking options, GPIO default modes and values, timers if any, etc. For Boot checklist read chapter 4.12 in X1000 UEFI Firmware Writer’s Guide (~18 things to do to boot this chip). After that I'd verify it with a simple "LED blinking" application on a GPIO.

          修补 3F8h 和类似端口对这款 SoC 的裸机"没有帮助.您需要直接处理寄存器,或者找到并使用合适的库或框架(可能是 UEFI BIOS?).

          Tinkering with 3F8h and similar ports is not going to help on "bare metal" of this SoC. You need to deal with the registers directly, or find and use appropriate library or framework (maybe UEFI BIOS?).

          特定平台的编程源代码应该是很好的例子.例如,在 英特尔 Quark 的板级支持包源 存档 Quark_EDKII_v1.0.0.tar.gz 是 Quark/Galileo 的 UEFI 源代码.在那里,Serial.cSerial.h 文件可能正是您要找的:

          Programming sources for the particular platform should be a good read for examples. For example, in Board Support Package Sources for Intel Quark the archive Quark_EDKII_v1.0.0.tar.gz is the UEFI source code for Quark/Galileo. It there, the Serial.c and Serial.h files might just be what you are looking for:

          Quark_EDKII_v1.0.0/QuarkSocPkg/QuarkSouthCluster/Uart/Dxe/Serial.*

          Quark_EDKII_v1.0.0/QuarkSocPkg/QuarkSouthCluster/Uart/Dxe/Serial.*

          这篇关于英特尔伽利略裸机UART的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆