01_basicLinux内核模块-CSDN博客文章浏览阅读23次。环境ID=ubuntuMakefilemodules:clean:basic.creturn 0;运行效果。https://blog.csdn.net/m0_37132481/article/details/136157384?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22136157384%22%2C%22source%22%3A%22m0_37132481%22%7Duart.c
root@T:/media/sf_D_DRIVE/kmodule/03_uart# cat uart.c
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/device.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/io.h>
#define TAG "HELLO# "
static void my_uart_stop_tx(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
}
static void echo_putchar(struct uart_port *port, u8 ch)
{
/* write char output */
printk("%c", ch);
/* read char input */
uart_insert_char(port, 0, 0, ch, 0);
tty_flip_buffer_push(&port->state->port);
}
static void my_uart_start_tx(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
u8 ch;
u8 tx_ready = 1;
uart_port_tx(port, ch, tx_ready, echo_putchar(port, ch));
}
static void my_uart_stop_rx(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
}
static unsigned int my_uart_tx_empty(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
return 0;
}
/* no modem control lines */
static unsigned int my_uart_get_mctrl(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
}
static void my_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
printk(TAG "%s\n", __func__);
}
static void my_uart_break_ctl(struct uart_port *port, int break_state)
{
printk(TAG "%s\n", __func__);
}
static int my_uart_startup(struct uart_port *port)
{
int ret = 0;
printk(TAG "%s\n", __func__);
return ret;
}
static void my_uart_shutdown(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
}
static void my_uart_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old)
{
printk(TAG "%s\n", __func__);
}
static const char *my_uart_type(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
return port->type == PORT_21285 ? "my_uart_type" : NULL;
}
static void my_uart_release_port(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
}
static int my_uart_request_port(struct uart_port *port)
{
printk(TAG "%s\n", __func__);
return 0;
}
static void my_uart_config_port(struct uart_port *port, int flags)
{
printk(TAG "%s\n", __func__);
if (flags & UART_CONFIG_TYPE)
port->type = PORT_21285;
}
/*
* verify the new serial_struct (for TIOCSSERIAL).
*/
static int my_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
{
printk(TAG "%s\n", __func__);
int ret = 0;
return ret;
}
static const struct uart_ops my_uart_ops = {
.tx_empty = my_uart_tx_empty,
.get_mctrl = my_uart_get_mctrl,
.set_mctrl = my_uart_set_mctrl,
.stop_tx = my_uart_stop_tx,
.start_tx = my_uart_start_tx,
.stop_rx = my_uart_stop_rx,
.break_ctl = my_uart_break_ctl,
.startup = my_uart_startup,
.shutdown = my_uart_shutdown,
.set_termios = my_uart_set_termios,
.type = my_uart_type,
.release_port = my_uart_release_port,
.request_port = my_uart_request_port,
.config_port = my_uart_config_port,
.verify_port = my_uart_verify_port,
};
static struct uart_port my_uart_port = {
.mapbase = 0xaabbccdd,
.iotype = UPIO_MEM,
.irq = 0,
.fifosize = 16,
.ops = &my_uart_ops,
.flags = UPF_BOOT_AUTOCONF,
};
static struct uart_driver my_uart_reg = {
.owner = THIS_MODULE,
.driver_name = "my_uart_driver",
.dev_name = "ttyMyUart",
.major = 204,
.minor = 4,
.nr = 1,
};
static int __init my_uart_init(void)
{
int ret;
my_uart_port.dev = kzalloc(sizeof(*my_uart_port.dev), GFP_KERNEL);
dev_set_name(my_uart_port.dev, "%s", "my_uart_device");
ret = device_register(my_uart_port.dev);
my_uart_port.dev = get_device(my_uart_port.dev);
ret = uart_register_driver(&my_uart_reg);
if (ret == 0)
ret = uart_add_one_port(&my_uart_reg, &my_uart_port);
printk("ret=%d\n", ret);
return ret;
}
static void __exit my_uart_exit(void)
{
uart_remove_one_port(&my_uart_reg, &my_uart_port);
uart_unregister_driver(&my_uart_reg);
device_unregister(my_uart_port.dev);
kfree(my_uart_port.dev);
}
module_init(my_uart_init);
module_exit(my_uart_exit);
MODULE_LICENSE("GPL");
效果
root@T:/media/sf_D_DRIVE/kmodule/03_uart# ls /dev/ttyMyUart0
/dev/ttyMyUart0