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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

A20串口驱动分析

發(fā)布時間:2023/12/10 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 A20串口驱动分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

串口驅(qū)動的整體框架實際上和顯示驅(qū)動類似

驅(qū)動程序是一個字符設(shè)備,驅(qū)動的實質(zhì)內(nèi)容都是在一個平臺總線設(shè)備驅(qū)動程序里


1.? 串口驅(qū)動的分析,從"drivers/tty/serial/8250/8250.c"開始

???? serial8250_init為入口函數(shù),從這個函數(shù)一路分析下去,下面列出主要代碼

???????????? serial8250_reg.nr = UART_NR;????????? UART_NR為8,查看datasheet可知A20支持8個uart
?? ????????? ret = uart_register_driver(&serial8250_reg);


???? uart_register_driver在”drivers/tty/serial/serial_core.c“中可以找到

???????????? normal->type? = TTY_DRIVER_TYPE_SERIAL;?

???????????? normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

???????????? tty_register_driver


??? tty_register_driver"drivers/tty/tty_io.c"這個文件中找到如下函數(shù)

?????????? alloc_chrdev_region

?????????? register_chrdev_region

?????????? cdev_init

??????????? cdev_add

?????????? if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
?? ??? ?????????? for (i = 0; i < driver->num; i++) {
?? ??? ??? ?????????????? d = tty_register_device(driver, i, NULL);
?? ??? ??? ?????????????? if (IS_ERR(d)) {
?? ??? ??? ??? ??????????????? error = PTR_ERR(d);
?? ??? ??? ??? ? ? ? ? ? ? ?? goto err;
?? ??? ??? ?????????????? }
?? ??? ?????????? }
?? ? ? ?? }

????????? 前四個函數(shù)是創(chuàng)建一個字符設(shè)備驅(qū)動程序的典型函數(shù),后面那段if語句之所以拿出來說一下,是因為

????????? tty_register_device這個函數(shù)是用來創(chuàng)建設(shè)備文件的,但是這個if語句是不會執(zhí)行,因為從上面的分析可?

????????? 知道這個驅(qū)動的flags里TTY_DRIVER_DYNAMIC_DEV。那么什么時候創(chuàng)建了設(shè)備文件呢。實際上,上面幾個文件只是一個框架性的東西。


2.?? 接下來分析另一路主線

????? ”drivers/tty/serial/8250/8250_sunxi.c"

?????? sw_serial_init

?????? 這里注冊了一個平臺總線驅(qū)動和平臺總線設(shè)備

???????????? script_get_item(uart_para, "uart_used", &val);

???????????? 從配置文件中得到某一個串口是否可用如果可用的話,在調(diào)用如下函數(shù)

??????????? platform_device_register

??????????? platform_driver_register

?????????? 來完成平臺總線驅(qū)動和平臺總線設(shè)備的匹配

????????? 分析device和driver 如下

????????? static struct platform_driver sw_serial_driver = {
?????????????????? .probe????? = sw_serial_probe,
?????????????????? .remove???? = sw_serial_remove,
?? ? ? ? ? ? ? ? ? .suspend??? = sw_serial_suspend,
?????????????????? .resume???? = sw_serial_resume,
?? ? ? ? ? ? ? ? ? .driver???? = {
??????????????????????????? .name?? = "sunxi-uart",
??????????????????????????? .owner? = THIS_MODULE,
?????????????????? },
????????? };

??????? struct platform_device sw_uart_dev[] = {
??? [0] = {.name = "sunxi-uart", .id = 0, .num_resources = ARRAY_SIZE(sw_uart_res[0]), .resource = &sw_uart_res[0][0], .dev.release = sunxi_serial_release},
??? [1] = {.name = "sunxi-uart", .id = 1, .num_resources = ARRAY_SIZE(sw_uart_res[1]), .resource = &sw_uart_res[1][0], .dev.release = sunxi_serial_release},
??? [2] = {.name = "sunxi-uart", .id = 2, .num_resources = ARRAY_SIZE(sw_uart_res[2]), .resource = &sw_uart_res[2][0], .dev.release = sunxi_serial_release},
??? [3] = {.name = "sunxi-uart", .id = 3, .num_resources = ARRAY_SIZE(sw_uart_res[3]), .resource = &sw_uart_res[3][0], .dev.release = sunxi_serial_release},
??? [4] = {.name = "sunxi-uart", .id = 4, .num_resources = ARRAY_SIZE(sw_uart_res[4]), .resource = &sw_uart_res[4][0], .dev.release = sunxi_serial_release},
??? [5] = {.name = "sunxi-uart", .id = 5, .num_resources = ARRAY_SIZE(sw_uart_res[5]), .resource = &sw_uart_res[5][0], .dev.release = sunxi_serial_release},
??? [6] = {.name = "sunxi-uart", .id = 6, .num_resources = ARRAY_SIZE(sw_uart_res[6]), .resource = &sw_uart_res[6][0], .dev.release = sunxi_serial_release},
??? [7] = {.name = "sunxi-uart", .id = 7, .num_resources = ARRAY_SIZE(sw_uart_res[7]), .resource = &sw_uart_res[7][0], .dev.release = sunxi_serial_release},
};

??????? 從上面兩個結(jié)構(gòu)體可以看出,8個平臺總線設(shè)備匹配了1個平臺總線驅(qū)動。

?????? 那么接下來我們看看平臺總線驅(qū)動的probe函數(shù)實現(xiàn)了什么。

3. sw_serial_probe函數(shù)分析

??? ????????? sw_serial_get_config這個函數(shù)從配置文件中得到type和port兩個參數(shù),type應(yīng)該是管腳數(shù)目,比如基本的串口使用了tx,rx,那個type就是2,加兩個流控,type就是4,全串口type就是8.

????????? sw_serial_get_resource這個函數(shù),從配置文件中得到管腳的定義,并從平臺設(shè)備的resources中得到,內(nèi)存和中斷資源。

????????? serial8250_register_port????? serial8250_register_port定義8250.c中

????????? uart_add_one_port?? 定義在serial_core.c中

????????? tty_register_device? 定義在tty_io.c中

????????? 下面主要分析這個函數(shù)

4. struct device *tty_register_device(struct tty_driver *driver, unsigned index,
?? ??? ??? ??? ??? struct device *device)
??? {
?? ????? char name[64];

???????? 這句構(gòu)造主次設(shè)備號

?? ????? dev_t dev = MKDEV(driver->major, driver->minor_start) + index;

????????
?? ?????? if (index >= driver->num) {
?? ??? ???????? printk(KERN_ERR "Attempt to register invalid tty line number "
?? ??? ??????????????? " (%d).\n", index);
?? ??? ????????? return ERR_PTR(-EINVAL);
?? ????? }

?? ????? if (driver->type == TTY_DRIVER_TYPE_PTY)
?? ??? ?????????? pty_line_name(driver, index, name);
?? ? ? ? else

????????????????? 這句構(gòu)造串口設(shè)備文件

?? ??? ?????????? tty_line_name(driver, index, name);

?????????? 這句用name來創(chuàng)建一個設(shè)備文件
?? ?????? return device_create(tty_class, device, dev, NULL, name);
?? }

???? 最終在這里創(chuàng)建了串口的設(shè)備文件,實際這個串口真正硬件資源相關(guān)的東西都是在這個平臺總線設(shè)備和平臺總線驅(qū)動里來管理的。

???? 最上面的那個串口字符設(shè)備驅(qū)動只是一個框架性的東西。實際和顯示驅(qū)動類似,2.6內(nèi)核以后的很多驅(qū)動程序都是這種分層的方式,用平臺總線驅(qū)動程序來實現(xiàn)。


總結(jié)

以上是生活随笔為你收集整理的A20串口驱动分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。