日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

serial driver 1

發布時間:2024/4/14 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 serial driver 1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
make menuconfig:


1.Device Drivers? ---> Character devices? ---> Serial drivers? ---> <*> Samsung Soc Serial support
obj-$(CONFIG_SERIAL_CORE) += serial_core.o?? 是串口核心
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o??? 是串口具體實現

2.控制臺終端
計算機顯示器通常被稱為控制臺終端(console)。必須有一個(些)特殊文件與console相關聯,比如虛擬終端tty1 tty2 串口ttySAC0 ttySAC1等。系統所發出的信息會發送到console對應的文件上。

如果不選此項,在啟動kernel后就不輸出了。
Starting kernel ...Uncompressing Linux...................................................................................................................................... ................... done, booting the kernel.uboot里設置的 console=ttySAC0 ,決定了使用ttySAC0作控制臺終端。

在samsung.c中實現console。
/* s3c24xx_serial_initconsole** initialise the console from one of the uart drivers */static struct console s3c24xx_serial_console = {.name = S3C24XX_SERIAL_NAME,.device = uart_console_device,.flags = CON_PRINTBUFFER,.index = -1,.write = s3c24xx_serial_console_write,.setup = s3c24xx_serial_console_setup };int s3c24xx_serial_initconsole(struct platform_driver *drv,struct s3c24xx_uart_info *info){struct platform_device *dev = s3c24xx_uart_devs[0];dbg("s3c24xx_serial_initconsole\n");/* select driver based on the cpu */if (dev == NULL) {printk(KERN_ERR "s3c24xx: no devices for console init\n");return 0;}if (strcmp(dev->name, drv->driver.name) != 0)return 0;s3c24xx_serial_console.data = &s3c24xx_uart_drv;s3c24xx_serial_init_ports(info);register_console(&s3c24xx_serial_console);return 0; }
3.<*> Samsung S3C2440/S3C2442 Serial port support
普通串口 /dev/ttySAC*
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
1.串口的平臺設備分散在mach-mini2440.c,arch/arm/plat-s3c/init.c等,在系統啟動時注冊.比如mach-mini2440.c
static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {[0] = {//串口0.hwport = 0,.flags = 0,.ucon = 0x3c5,.ulcon = 0x03,.ufcon = 0x51,},[1] = {//串口1.hwport = 1,.flags = 0,.ucon = 0x3c5,.ulcon = 0x03,.ufcon = 0x51,},[2] = {//串口2.hwport = 2,.flags = 0,.ucon = 0x3c5,.ulcon = 0x03,.ufcon = 0x51,} };比如init.c
void __init s3c24xx_init_uartdevs(char *name,
?? ??? ??? ??? ?? struct s3c24xx_uart_resources *res,
?? ??? ??? ??? ?? struct s3c2410_uartcfg *cfg, int no)
{
?? ?struct platform_device *platdev;
?? ?struct s3c2410_uartcfg *cfgptr = uart_cfgs;
?? ?struct s3c24xx_uart_resources *resp;
?? ?int uart;

?? ?memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);

?? ?for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
?? ??? ?platdev = s3c24xx_uart_src[cfgptr->hwport];

?? ??? ?resp = res + cfgptr->hwport;

?? ??? ?s3c24xx_uart_devs[uart] = platdev;

?? ??? ?platdev->name = name;
?? ??? ?platdev->resource = resp->resources;
?? ??? ?platdev->num_resources = resp->nr_resources;

?? ??? ?platdev->dev.platform_data = cfgptr;
?? ?}

?? ?nr_uarts = no;
}


2.串口的平臺驅動在
arch/arm/mach-s3c2440/s3c2440.c和samsung.c
初始化:
s3c2440.c初始化時注冊了平臺驅動
static int __init s3c2440_serial_init(void) {return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);//見下面 }static void __exit s3c2440_serial_exit(void) {platform_driver_unregister(&s3c2440_serial_driver); }module_init(s3c2440_serial_init); module_exit(s3c2440_serial_exit);//samsung.c int s3c24xx_serial_init(struct platform_driver *drv,struct s3c24xx_uart_info *info) {dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);#ifdef CONFIG_PMdrv->suspend = s3c24xx_serial_suspend;drv->resume = s3c24xx_serial_resume; #endifreturn platform_driver_register(drv); }
samsung.c在初始化時就注冊了串口驅動
static int __init s3c24xx_serial_modinit(void) {int ret;ret = uart_register_driver(&s3c24xx_uart_drv);if (ret < 0) {printk(KERN_ERR "failed to register UART driver\n");return -1;}return 0; }static void __exit s3c24xx_serial_modexit(void) {uart_unregister_driver(&s3c24xx_uart_drv); }module_init(s3c24xx_serial_modinit); module_exit(s3c24xx_serial_modexit);

看一下平臺驅動的probe,可知是在probe函數里面添加串口
s3c2440.c
static struct s3c24xx_uart_info s3c2440_uart_inf = {.name = "Samsung S3C2440 UART",.type = PORT_S3C2440,.fifosize = 64,.rx_fifomask = S3C2440_UFSTAT_RXMASK,.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,.rx_fifofull = S3C2440_UFSTAT_RXFULL,.tx_fifofull = S3C2440_UFSTAT_TXFULL,.tx_fifomask = S3C2440_UFSTAT_TXMASK,.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,.get_clksrc = s3c2440_serial_getsource,.set_clksrc = s3c2440_serial_setsource,.reset_port = s3c2440_serial_resetport, };/* device management */static int s3c2440_serial_probe(struct platform_device *dev) {dbg("s3c2440_serial_probe: dev=%p\n", dev);return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);//見下面 }//samsung.c static int probe_index;int s3c24xx_serial_probe(struct platform_device *dev,struct s3c24xx_uart_info *info) {struct s3c24xx_uart_port *ourport;int ret;dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index);ourport = &s3c24xx_serial_ports[probe_index];probe_index++;dbg("%s: initialising port %p...\n", __func__, ourport);ret = s3c24xx_serial_init_port(ourport, info, dev);if (ret < 0)goto probe_err;dbg("%s: adding port\n", __func__);uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);platform_set_drvdata(dev, &ourport->port);ret = device_create_file(&dev->dev, &dev_attr_clock_source);if (ret < 0)printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__);ret = s3c24xx_serial_cpufreq_register(ourport);if (ret < 0)dev_err(&dev->dev, "failed to add cpufreq notifier\n");return 0;probe_err:return ret; }
幾個重要的結構體
//uart_ops static struct uart_ops s3c24xx_serial_ops = {.pm = s3c24xx_serial_pm,.tx_empty = s3c24xx_serial_tx_empty,.get_mctrl = s3c24xx_serial_get_mctrl,.set_mctrl = s3c24xx_serial_set_mctrl,.stop_tx = s3c24xx_serial_stop_tx,.start_tx = s3c24xx_serial_start_tx,.stop_rx = s3c24xx_serial_stop_rx,.enable_ms = s3c24xx_serial_enable_ms,.break_ctl = s3c24xx_serial_break_ctl,.startup = s3c24xx_serial_startup,.shutdown = s3c24xx_serial_shutdown,.set_termios = s3c24xx_serial_set_termios,.type = s3c24xx_serial_type,.release_port = s3c24xx_serial_release_port,.request_port = s3c24xx_serial_request_port,.config_port = s3c24xx_serial_config_port,.verify_port = s3c24xx_serial_verify_port, };//uart_driver static struct uart_driver s3c24xx_uart_drv = {.owner = THIS_MODULE,.dev_name = "s3c2410_serial",.nr = CONFIG_SERIAL_SAMSUNG_UARTS,.cons = S3C24XX_SERIAL_CONSOLE,.driver_name = S3C24XX_SERIAL_NAME,.major = S3C24XX_SERIAL_MAJOR,.minor = S3C24XX_SERIAL_MINOR, };//s3c24xx_uart_port static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {[0] = {.port = {.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),.iotype = UPIO_MEM,.irq = IRQ_S3CUART_RX0,.uartclk = 0,.fifosize = 16,.ops = &s3c24xx_serial_ops,.flags = UPF_BOOT_AUTOCONF,.line = 0,}},[1] = {.port = {.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),.iotype = UPIO_MEM,.irq = IRQ_S3CUART_RX1,.uartclk = 0,.fifosize = 16,.ops = &s3c24xx_serial_ops,.flags = UPF_BOOT_AUTOCONF,.line = 1,}}, #if CONFIG_SERIAL_SAMSUNG_UARTS > 2[2] = {.port = {.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),.iotype = UPIO_MEM,.irq = IRQ_S3CUART_RX2,.uartclk = 0,.fifosize = 16,.ops = &s3c24xx_serial_ops,.flags = UPF_BOOT_AUTOCONF,.line = 2,}}, #endif #if CONFIG_SERIAL_SAMSUNG_UARTS > 3[3] = {.port = {.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock),.iotype = UPIO_MEM,.irq = IRQ_S3CUART_RX3,.uartclk = 0,.fifosize = 16,.ops = &s3c24xx_serial_ops,.flags = UPF_BOOT_AUTOCONF,.line = 3,}} #endif };
//serial_core.h struct uart_port {spinlock_t lock; /* port lock */unsigned long iobase; /* in/out[bwl] */unsigned char __iomem *membase; /* read/write[bwl] */unsigned int (*serial_in)(struct uart_port *, int);void (*serial_out)(struct uart_port *, int, int);unsigned int irq; /* irq number */unsigned long irqflags; /* irq flags */unsigned int uartclk; /* base uart clock */unsigned int fifosize; /* tx fifo size */unsigned char x_char; /* xon/xoff char */unsigned char regshift; /* reg offset shift */unsigned char iotype; /* io access style */unsigned char unused1;#define UPIO_PORT (0) #define UPIO_HUB6 (1) #define UPIO_MEM (2) #define UPIO_MEM32 (3) #define UPIO_AU (4) /* Au1x00 type IO */ #define UPIO_TSI (5) /* Tsi108/109 type IO */ #define UPIO_DWAPB (6) /* DesignWare APB UART */ #define UPIO_RM9000 (7) /* RM9000 type IO */unsigned int read_status_mask; /* driver specific */unsigned int ignore_status_mask; /* driver specific */struct uart_state *state; /* pointer to parent state */struct uart_icount icount; /* statistics */struct console *cons; /* struct console, if any */ #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)unsigned long sysrq; /* sysrq timeout */ #endifupf_t flags;#define UPF_FOURPORT ((__force upf_t) (1 << 1)) #define UPF_SAK ((__force upf_t) (1 << 2)) #define UPF_SPD_MASK ((__force upf_t) (0x1030)) #define UPF_SPD_HI ((__force upf_t) (0x0010)) #define UPF_SPD_VHI ((__force upf_t) (0x0020)) #define UPF_SPD_CUST ((__force upf_t) (0x0030)) #define UPF_SPD_SHI ((__force upf_t) (0x1000)) #define UPF_SPD_WARP ((__force upf_t) (0x1010)) #define UPF_SKIP_TEST ((__force upf_t) (1 << 6)) #define UPF_AUTO_IRQ ((__force upf_t) (1 << 7)) #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) #define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) #define UPF_FIXED_PORT ((__force upf_t) (1 << 29)) #define UPF_DEAD ((__force upf_t) (1 << 30)) #define UPF_IOREMAP ((__force upf_t) (1 << 31))#define UPF_CHANGE_MASK ((__force upf_t) (0x17fff)) #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))unsigned int mctrl; /* current modem ctrl settings */unsigned int timeout; /* character-based timeout */unsigned int type; /* port type */const struct uart_ops *ops;unsigned int custom_divisor;unsigned int line; /* port index */resource_size_t mapbase; /* for ioremap */struct device *dev; /* parent device */unsigned char hub6; /* this should be in the 8250 driver */unsigned char suspended;unsigned char unused[2];void *private_data; /* generic platform data pointer */ };
在probe中(s3c24xx_serial_probe(),samsung.c)用uart_add_one_port()將uart_port加入uart_driver

每一uart_port對應一個uart_ops,主要工作就是實現這些函數指針。

轉載于:https://www.cnblogs.com/-song/archive/2011/12/17/3331900.html

總結

以上是生活随笔為你收集整理的serial driver 1的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。