本文主要通过学习韦东山老师的课程,详情可通过百问网驱动大全进行学习。
串口,通用异步接收机和发射机(Universal Asynchronous Receiver and Transmitter)。PC 机一般有两个串行口COM 1 和COM 2 。串行口不同于并行口之处在于它的数据和控制信息是一位接一位地传送出去的。
主要功能:①通过串口打印调试信息。②外接各种模块:GPS/蓝牙
如何使用串口:
①设置波特率
②格式:数据位/停止位/校验位/流控
示例:发送1Byte,比如’A’?
‘A’,二进制位:0b01000001
①双方约定波特率:每一位占据的时间
编程部分:
1.构造驱动基本框架
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/rational.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <asm/irq.h>
#include <linux/busfreq-imx.h>
#include <linux/platform_data/serial-imx.h>
#include <linux/platform_data/dma-imx.h>
static struct uart_port *virt_port;//uart_port include haedware
static struct uart_driver virtual_uart_driver = {
.owner = THIS_MODULE,
.driver_name = "VIRT_UART",
.major = 0,
.minor = 0,
.nr = 1,//number,drv support 1 serial
};
//Interrupt func
static irqreturn_t virtual_rxint(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
unsigned int rx, flg, ignored = 0;
struct tty_port *port = &sport->port.state->port;
unsigned long flags, temp;
}
static int serial_imx_probe(struct platform_device *pdev)
{
int rxirq;
int ret;
/*通过设备树获取硬件信息*/
rxirq=platform_get_irq(pdev,0);
/* 分配设置注册uart_port */
virt_port = devm_kzalloc(&pdev->dev, sizeof(*virt_port), GFP_KERNEL);//使用devm前缀时,系统可自动释放内存
virt_port->dev = &pdev->dev;
virt_port->iotype = UPIO_MEM;
virt_port->irq = rxirq;
virt_port->fifosize = 32;
virt_port->ops = &virt_pops;//硬件相关函数
virt_port->flags = UPF_BOOT_AUTOCONF;
virt_port->type = PORT_8250;
/*注册中断*/
ret = devm_request_irq(&pdev->dev, rxirq, virtual_rxint, 0,
dev_name(&pdev->dev), virt_port);
return uart_add_one_port(virtual_uart_driver,virt_port);//向uart_driver注册uart_port
}
static int serial_imx_remove(struct platform_device *pdev)
{
uart_remove_one_port(virtual_uart_driver, virt_port);
}
static const struct of_match_id virtual_uart_of_match[]={
{.compatible = "test,virtual_uart",},
{},
};
static struct platform_driver virtual_uart_platform_driver = {
.probe = virtual_uart_probe,
.remove = virtual_uart_remove,
.driver = {
.name = "test_virtual_uart",
.of_match_table = of_match_ptr(virtual_uart_of_match);//通过compatible方式来匹配
}
};
static int __init virtual_uart_init(void)
{
int ret = uart_register_driver(&virtual_uart_driver);//注册串口驱动
printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
if (ret)
return ret;
//注册平台驱动
ret = platform_driver_register(&virtual_uart_platform_driver);
if (ret != 0)
uart_unregister_driver(&virtual_uart_platform_driver);
return ret;
}
static void __exit virtual_uart_exit(void)
{
platform_driver_unregister(&virtual_uart_platform_driver);
uart_unregister_driver(&virtual_uart_driver);
}
module_init(virtual_uart_init);
module_exit(virtual_uart_exit);
MODULE_LICENSE("GPL");
其核心就在于uart_add_one_port,这个函数作用为:添加一个串口。