8. 编写串口驱动
终于开始进行驱动的移植与编写了!
提到驱动,在最近几年的u-boot版本中,uboot引入了驱动模型(driver model),那具体是什么呢?各位别急,我们之后的每一个驱动都将使用这种驱动模型进行编写,那现在先看比较简单的串口驱动,从实际的驱动中一步步的了解驱动模型dm。
8.1 驱动代码
首先在drivers/serial目录下新建一个文件serial_s3c2440.c,全部内容如下:
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2020 Asymptote
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <linux/compiler.h>
#include <asm/io.h>
#include <serial.h>
DECLARE_GLOBAL_DATA_PTR;
struct s3c2440_serial {
u32 ulcon;
u32 ucon;
u32 ufcon;
u32 umcon;
u32 utrstat;
u32 uerstat;
u32 ufstat;
u32 umstat;
u32 utxh;
u32 urxh;
u32 ubrdiv;
};
struct s3c2440_serial_priv {
struct s3c2440_serial *reg;
};
int s3c2440_serial_setbrg(struct udevice *dev, int baudrate)
{
struct s3c2440_serial_priv *priv = dev_get_priv(dev);
u32 val, uclk;
/* 使用pclk时钟,大小为50MHz */
uclk = 50000000;
val = uclk / baudrate;
writel(val / 16 - 1, &priv->reg->ubrdiv);
return 0;
}
static int s3c2440_serial_getc(struct udevice *dev)
{
struct s3c2440_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->reg->utrstat) & (1 << 0)))
return -EAGAIN;
return (int)(readb(&priv->reg->urxh) & 0xff);
}
static int s3c2440_serial_putc(struct udevice *dev, const char ch)
{
struct s3c2440_serial_priv *priv = dev_get_priv(dev);
if (!(readl(&priv->reg->utrstat) & (1 << 2)))
return -EAGAIN;
writeb(ch, &priv->reg->utxh);
return 0

本文详细介绍U-Boot串口驱动的移植过程,包括驱动代码编写、设备树配置、Kconfig与Makefile修改等内容,适合初学者入门。
最低0.47元/天 解锁文章
836





