成人精品水蜜桃_成人在线丰满少妇av_91亚洲国产高清_欧美日韩免费区域视频在线观看

首頁 新聞 > 科技 > 正文

Linux下的串口總線驅動(一)

一.系統理論

PC機南橋的LPC總線(Low Pin Count并行總線,代替以前的ISA總線)上掛接了一個超級I/O模塊,而UART是這個超級模塊芯片組的一部分,這個UART通過RS232線程轉換與串行端口相連。與RS232不同,RS485并不是標準的PC接口,但在嵌入式領域,會為了可靠通信而使用RS485,RS485使用差分信號,因此其傳輸距離可以達到數百米,而RS232傳輸距離僅數幾米,在處理器一端,RS485接口是半雙工的UART操作。

本文引用地址:http://www.eepw.com.cn/article/201611/319918.htm

Linux包含如下幾種終端設備:串行端口終端(/dev/ttySn)、偽終端(/dev/pty)、控制終端(/dev/tty)、控制臺終端(/dev/ttyn,/dev/conslole)。串行端口終端使用的設備名為/dev/ttyS0,/dev/ttyS1等,對應的設備號為(4,0),(4,1)。通過查看/proc/tty/drivers文件可以知道什么類型的tty設備存在以及什么驅動被加載到內核,這個文件包括一個當前存在的不同tty驅動的列表,包括驅動名,缺省的節點名,驅動的主編號,驅動的次編號范圍,以及tty驅動的類型。

I/O系統調用是從帶有線路規程的TTY I/O核心開始,然后通過TTY層,最后到達UART驅動層。主要涉及串口內核配置、UART層內核代碼、TTY層內核代碼、線路規程內核代碼、串口測試代碼五個部分。

二.串口內核配置

對于Mini2440串口驅動,我想從配置開始講起。在內核中Kconfig必須完成一層層調用,如果沒有在上一個Kconfig中調用該層Kconfig,那么該層Kconfig中的內容不會在此出現。這種情況下,只有當該層的Kconfig被其他層調用,該層Kconfig中的內容才會被顯示。所以我們找找drivers/serial/Kconfig在哪里被調用的呢?

在/drivers/char/kconfig中可以看到一行代碼source "drivers/serial/Kconfig",那我們就到drivers/serial/Kconfig下看看

Samsung SoC serial support對應于samsung.oserial_core.o

config SERIAL_SAMSUNG

tristate "Samsung SoC serial support"

depends on ARM && PLAT_S3C

select SERIAL_CORE

Support for console on Samsung SoC serial port對應于控制臺驅動

Samsung S3C2440/S3C2442 Serial port support對應于s3c2440.o

在/drivers/char/Makefile中可以看到

obj-y+= mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o

我們知道tty_io.on_tty.o tty_ioctl.otty_ldisc.o tty_buffer.o tty_port.o已編入內核

自此,我們知道關于串口驅動,我們內核中被編譯了s3c2440.osamsung.oserial_core.o tty_io.on_tty.o tty_ioctl.otty_ldisc.o tty_buffer.o tty_port.o

我們對此進行分類,屬于UART層的是s3c2440.osamsung.o;屬于TTY層的是serial_core.o;屬于線路規程的是tty_io.on_tty.o tty_ioctl.otty_ldisc.o tty_buffer.o tty_port.o 。

好了,對于串口的地圖我們已經分析好了,那我們就按照UART層,TTY層,線路規程一個個的逛逛吧。

三.UART層內核代碼

我們先看看samsung.o的init代碼吧,這里面完成了uart_driver的注冊

static int __init s3c24xx_serial_modinit(void)

{

int ret;

ret = uart_register_driver(&s3c24xx_uart_drv);//注冊uart_driver

if (ret < 0) {

printk(KERN_ERR "failedto register UART driver\n");

return -1;

}

return 0;

}

static struct uart_driver s3c24xx_uart_drv = {

.owner= THIS_MODULE,

.dev_name= "s3c2410_serial", //設備名

.nr= CONFIG_SERIAL_SAMSUNG_UARTS,//UART端口個數

.cons= S3C24XX_SERIAL_CONSOLE,//指向控制臺結構

.driver_name= S3C24XX_SERIAL_NAME,//驅動的名字

.major= S3C24XX_SERIAL_MAJOR,//串口主設備號

.minor= S3C24XX_SERIAL_MINOR,//串口次設備號

};

我們關注下上面這個結構體中一個成員S3C24XX_SERIAL_CONSOLE

#define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console

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

};

上面是控制臺的結構體成員。

對于UART驅動,我們除了需要注冊uart_driver外,還需要注冊端口,我們看看s3c2440.o。

這個文件里面注冊了一個平臺設備,其中平臺設備的探測函數最終調用了samsung.o中的s3c24xx_serial_probe函數。

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]; //選擇s3c24xx_uart_port

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);//注冊CPU頻率

if (ret < 0)

dev_err(&dev->dev, "failed to add cpufreq notifier\n");

return 0;

probe_err:

return ret;

}

通過上面的函數,我們發現在UART層,我們調用了uart_add_one_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,//對UART操作的函數

.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,//對UART操作的函數

.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,//對UART操作的函數

.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,//對UART操作的函數

.flags= UPF_BOOT_AUTOCONF,

.line= 3,

}

}

#endif

};

在端口的定義中,我們知道s3c24xx_uart_port中定義了一個uart_port結構體,繼續跟蹤對UART的操作函數

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,//類似于write

.stop_rx= s3c24xx_serial_stop_rx,

.enable_ms= s3c24xx_serial_enable_ms,

.break_ctl= s3c24xx_serial_break_ctl,

.startup= s3c24xx_serial_startup,//類似于open

.shutdown= s3c24xx_serial_shutdown,//類似于close

.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_ops函數,我們需要自己去實現uart層的具體操作。

我們在UART層主要涉及uart_driver,uart_port,uart_ops三個結構體,并調用tty層的uart_register_driver和uart_add_one_port完成驅動和端口的注冊,UART層具體操作函數需要用戶自己設計。

好了,總結下UART驅動層需要完成的任務:

其一,定義uart_driver、uart_ops、uart_port等結構體的實例并在適當的地方根據具體硬件和驅動的情況初始化它們,當然具體設備XXX的驅動可以將這些結構套在新定義的XXX_uart_driver、XXX_uart_ops、XXX_uart_port之內。

其二,在模塊初始化時調用uart_register_driver()和uart_add_one_port()以注冊UART驅動并添加端口,在模塊卸載時調用uart_unregister_driver()和uart_remove_one_port()以注銷UART驅動并移除端口。

其三,根據具體硬件的datasheet實現uart_ops中的成員函數,這些函數的實現成為UART驅動的主體工作。

關鍵詞: Linux串口總線驅

最近更新

關于本站 管理團隊 版權申明 網站地圖 聯系合作 招聘信息

Copyright © 2005-2018 創投網 - m.7778890.com All rights reserved
聯系我們:33 92 950@qq.com
豫ICP備2020035879號-12

 

成人精品水蜜桃_成人在线丰满少妇av_91亚洲国产高清_欧美日韩免费区域视频在线观看
色悠久久久久综合欧美99| 亚洲欧美久久| 韩日欧美一区二区三区| 青青草97国产精品免费观看| 亚洲一区自拍偷拍| 一区二区三区电影在线播| 亚洲视频资源在线| 亚洲最大色网站| 午夜激情综合网| 性做久久久久久久免费看| 首页亚洲欧美制服丝腿| 蜜桃久久精品一区二区| 国产最新精品免费| av午夜精品一区二区三区| 欧美在线高清| 亚洲国产高清视频| 午夜亚洲视频| 91行情网站电视在线观看高清版| 在线精品亚洲一区二区不卡| 欧美色涩在线第一页| 综合久久久久综合| 亚洲卡通欧美制服中文| 亚洲成人av一区| 国产一区二区日韩精品| 成人av免费在线观看| 欧美日本不卡高清| 亚洲一区综合| 欧美高清www午色夜在线视频| 欧美大片国产精品| 亚洲天堂a在线| 日韩成人一级片| 福利一区二区在线| 亚洲午夜一区| 91国偷自产一区二区开放时间| 欧美一级生活片| 亚洲欧洲成人精品av97| 美女久久久精品| 97成人超碰视| 久久中文在线| 国产欧美一区二区三区网站 | 亚洲国产经典视频| 香港成人在线视频| 成人爽a毛片一区二区免费| 国模一区二区三区| 欧美日韩高清一区二区不卡| 欧美经典一区二区| 精品亚洲成a人在线观看| 牛夜精品久久久久久久99黑人| 国产日韩欧美精品| 欧美一区永久视频免费观看| 综合自拍亚洲综合图不卡区| 九色|91porny| 亚洲精品一区二区三区蜜桃久| 欧美午夜精品久久久久久孕妇| 精品国产一区二区三区四区四| 亚洲国产日韩综合久久精品| 成人av网站在线观看免费| 久久精品123| 国产精品久久久久影院亚瑟| 精品制服美女丁香| 一级日韩一区在线观看| 欧美成人a在线| 免费人成精品欧美精品| 在线精品亚洲一区二区| 日韩一级片在线观看| 亚洲r级在线视频| 精品动漫3d一区二区三区免费版| 91麻豆精品91久久久久同性| 亚洲综合自拍偷拍| 国产在线成人| 精品奇米国产一区二区三区| 久久66热偷产精品| 性8sex亚洲区入口| 国产精品网站一区| 国产黄人亚洲片| 看欧美日韩国产| 亚洲一本大道在线| 亚洲欧美伊人| xnxx国产精品| 在线影院国内精品| 日韩精品一二三| 麻豆免费精品视频| 99热这里只有成人精品国产| 久久婷婷久久一区二区三区| 国产精品综合二区| 欧美影院午夜播放| 亚洲不卡av一区二区三区| 99精品热6080yy久久| 国产精品视频观看| 午夜久久tv| 国产欧美中文在线| 97精品视频在线观看自产线路二 | 一区二区三区国产| 在线播放日韩| 国产精品视频你懂的| 欧美精品二区| 最新高清无码专区| 亚洲美女一区| 国产精品一级在线| 欧美精品电影在线播放| 精品一区二区三区av| 欧美亚洲丝袜传媒另类| 黑人精品欧美一区二区蜜桃| 91福利国产精品| 精品一区二区影视| 欧美一卡在线观看| 成人av网在线| 国产精品美女久久久久久2018| 国内久久视频| 亚洲国产三级在线| 欧美亚洲禁片免费| 国产成人在线视频网址| 久久这里只精品最新地址| 91亚洲大成网污www| 国产精品色婷婷| 亚洲免费黄色| 蜜臀精品久久久久久蜜臀| 欧美精品三级日韩久久| 丁香五精品蜜臀久久久久99网站| 久久在线观看免费| 亚洲婷婷在线| 日韩中文字幕1| 91精品国产入口| 欧美黄色一级视频| 亚洲国产日韩一级| 在线不卡免费欧美| 午夜欧美精品久久久久久久| 亚洲综合图片区| 欧美三级中文字幕在线观看| 成人av在线播放网站| 亚洲精品写真福利| 欧美日韩国产首页| 欧美激情国产日韩| 亚洲一二三四在线| 91精品国产一区二区| 精品动漫av| 麻豆精品新av中文字幕| 国产亚洲一二三区| 久久国产直播| 99久久婷婷国产| 三级欧美韩日大片在线看| 日韩三级在线观看| 日韩一级免费| 成人精品免费视频| 亚洲成人动漫一区| 26uuu国产在线精品一区二区| 国产日韩1区| 成人性色生活片免费看爆迷你毛片| 亚洲欧洲一区二区三区| 欧美精品一二三| 一区二区冒白浆视频| 成人综合在线网站| 日精品一区二区| 国产精品色哟哟| 欧美丰满嫩嫩电影| 中国成人在线视频| 94-欧美-setu| 麻豆视频一区二区| 亚洲激情男女视频| 久久嫩草精品久久久久| 色婷婷av一区| 亚洲国产婷婷香蕉久久久久久99| 国产麻豆日韩欧美久久| 亚洲二区视频在线| 亚洲国产高清不卡| 91麻豆精品国产91久久久久久| 国产欧美日韩在线播放| 93久久精品日日躁夜夜躁欧美| 奇米一区二区三区av| 亚洲免费视频成人| 国产欧美一区二区精品仙草咪 | 亚洲女爱视频在线| 久久久久久久久久久久久女国产乱 | 中文字幕一区二区视频| 欧美大片在线观看一区| 欧洲精品中文字幕| 性色一区二区三区| 99国内精品| 国产综合婷婷| 欧美黄污视频| 不卡区在线中文字幕| 精品影视av免费| 日本女优在线视频一区二区| 亚洲综合色网站| 综合在线观看色| 国产目拍亚洲精品99久久精品| 欧美成人a在线| 日韩欧美中文一区二区| 欧美久久久久久久久中文字幕| 色综合久久久久综合体桃花网| 夜夜精品视频| 亚洲精品极品| 99爱精品视频| 一本一本久久a久久精品综合妖精| 国产一区二区中文字幕免费看| 欧美日一区二区三区在线观看国产免| 成人精品高清在线| 99久久精品国产观看| 成人97人人超碰人人99| 北条麻妃一区二区三区|