RTEMS-BBB(八):UART扩展:准备

硬件准备:

UART的介绍:通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器,将数据进行串并转换。具体来说,就是将CPU发来的并行数据转成串行数据发出去,将串口接收到的串口数据转成并行数据发给CPU。

beagleboneblack的监控口默认为J1区的UART0

P9区有UART1,2和4,现在我们要拓展使用一个UART1,测试它的收发,并且和LED结合起来

将P9区24口,26口,以及GND连接到串口转USB模块

注意到每个接口有最多8个mode,而每个mode的选择是由Control Module Register决定的

因此在datasheet中查看两组寄存器的使用:CMR和UART

首先在memory map中查到CMR和UART的基地址

再查看CMR的寄存器列表偏移量地址

再看对应寄存器的赋值方法。注意到beaglebone上的UART为16550。涉及到的寄存器有

LCR LSR DLL DLM RBR THR

软件准备:

参考RTEMS源码中的console-config.c以及相关的头文件serial.h ns16550h

看懂console-config.c

void beagle_console_init(void)
{
if(init_needed)
{
const uint32_t div = UART_CLOCK / 16 / CONSOLE_BAUD;
CONSOLE_SYSC = 2;
while ((CONSOLE_SYSS & 1) == 0)
;
if ((CONSOLE_LSR & (CONSOLE_LSR_THRE | CONSOLE_LSR_TEMT)) == CONSOLE_LSR_THRE)
{
CONSOLE_LCR = 0x83;
CONSOLE_DLL = div;
CONSOLE_DLM = (div >> 8) & 0xff;
CONSOLE_LCR = 0x03;
CONSOLE_ACR = 0x00;
}
while ((CONSOLE_LSR & CONSOLE_LSR_TEMT) == 0)
;
CONSOLE_LCR = 0x80 | 0x03;
CONSOLE_DLL = 0x00;
CONSOLE_DLM = 0x00;
CONSOLE_LCR = 0x03;
CONSOLE_MCR = 0x03;
CONSOLE_FCR = 0x07;
CONSOLE_LCR = 0x83;
CONSOLE_DLL = div;
CONSOLE_DLM = (div >> 8) & 0xff;
CONSOLE_LCR = 0x03;
CONSOLE_ACR = 0x00;
init_needed = 0;
}
}
/*初始化函数:对于控制(control)寄存器,可以赋值;对于状态(status)寄存器,只读,用于判断语句。对于ns16550来说,先用 CONSOLE_SYSC=2Module is reset)使UART重置,然后当重置完成CONSOLE_SYSS=1Reset complete)继续执行。

LSR THRE 位为 1(发送器就绪)时,置LCR最高位为 1*/(允许除数寄存器),赋值83(无奇偶校验,1 位停止位, 8 位字符长度),DLL 设为 div。置LCR 最高位为 0,ACR(手册中对应mode definition register)置0。当LSR 的 TEMT 为 1(发送器为空)时;当LCR 最高位为 0 时,置 MCR 为 3(RTS 请求发送信号有效DTR 数据终端就绪信号有效),置 FCR 为 7(允许FIFO 缓冲工作,清除接收和发送缓冲器)。*/
static uint8_t beagle_uart_get_register(uintptr_t addr, uint8_t i)
{
uint8_t v;
volatile uint32_t *reg_r = (volatile uint32_t *) addr + i;
if(reg_r == (uint32_t*) BSP_CONSOLE_UART_BASE /* reading RHR */ )
{
/* check there should be anything in the RHR before accessing it */
if(!(CONSOLE_UART_LSR & 0x01))
{
return 0;
}
}
v = (uint8_t) *reg_r;
return v;
}
static void beagle_uart_set_register(uintptr_t addr, uint8_t i, uint8_t val)
{
volatile uint32_t *reg = (volatile uint32_t *) addr;
reg [i] = val;
}
这两段应该是完成寄存器地址的传递,条件是LSR的最低位( RDR 位)为 0(接收缓冲器无数据)
static void uart_write_polled( char c )
{
if(init_needed) beagle_console_init();
while( ( CONSOLE_LSR & TX_FIFO_E ) == 0 )
;
CONSOLE_THR8 = c;
}
static void _BSP_put_char( char c ) {
uart_write_polled( c );
if (c == '\n') {
uart_write_polled('\r');
}
}
这两段是UART的写或者说发送函数,当 LSR BI 1(进入中止状态),把c赋值给 THR(发送保持寄存器)发出去。

static int _BSP_get_char(void)
{
if ((CONSOLE_LSR & CONSOLE_LSR_RDR) != 0) {
return CONSOLE_RBR;
} else {
return -1;
}
}这一段是 UART 的读或者说接收函数,当 LSR 的 RDR 位为 1,表示接收缓冲器有数据时,返回 RBR 的值。

 console_tbl Console_Configuration_Ports [] = {
{
.sDeviceName = "/dev/ttyS0",
.deviceType = SERIAL_NS16550,
#if CONSOLE_POLLED /* option to facilitate running the tests */
.pDeviceFns = &ns16550_fns_polled,
#else
.pDeviceFns = &ns16550_fns,
#endif
.ulMargin = 16,
.ulHysteresis = 8,
.pDeviceParams = (void *) CONSOLE_BAUD,
.ulCtrlPort1 = BSP_CONSOLE_UART_BASE,
.ulDataPort = BSP_CONSOLE_UART_BASE,
.ulIntVector = BSP_CONSOLE_UART_IRQ,
.getRegister = beagle_uart_get_register,
.setRegister = beagle_uart_set_register,
.ulClock = UART_CLOCK, /* 48MHz base clock */
},
};
BSP_output_char_function_type BSP_output_char = _BSP_put_char;
BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
这两段涉及到函数的后续调用和参数传递

完成以上准备后 下面就是编程了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值