娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

ARM-Linux S5PV210 UART驅(qū)動(dòng)(4)----串口驅(qū)動(dòng)初始化過程

發(fā)布者:Jikai最新更新時(shí)間:2024-12-17 來源: cnblogs關(guān)鍵字:ARM-Linux  S5PV210  UART驅(qū)動(dòng)  串口驅(qū)動(dòng)  初始化過程 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

對(duì)于S5PV210 UART驅(qū)動(dòng)來說,主要關(guān)心的就是drivers/serial下的samsung.c和s5pv210.c連個(gè)文件。


由drivers/serial/Kconfig:


  config SERIAL_SAMSUNG

    depends on ARM && PLAT_SAMSUNG


  config SERIAL_S5PV210

    depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442) && SERIAL_SAMSUNG_CONSOLE


可以看出模塊的依賴關(guān)系,先加載samsung.ko,然后再加載s5pv210.ko。


所以串口的初始化的簡要過程如下:


samsung.c中模塊加載函數(shù)s3c24xx_serial_modinit調(diào)用uart_register_driver(&s3c24xx_uart_drv),注冊(cè)了s3c24xx_uart_drv這個(gè)uart_driver;


s5pv210.c中模塊加載函數(shù)s5p_serial_init ----> s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf) ---->  platform_driver_register(drv) 注冊(cè)了s5p_serial_driver這個(gè)平臺(tái)驅(qū)動(dòng),


                 有了平臺(tái)驅(qū)動(dòng)后,當(dāng)平臺(tái)設(shè)備與平臺(tái)驅(qū)動(dòng)match之后,調(diào)用s5p_serial_probe ----> s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]) ---->  s3c24xx_serial_init_port初始化UART端口

>  uart_add_one_port添加端口


《《《《====接下來具體分析====》》》》



一、注冊(cè)u(píng)art_driver


/* 模塊加載函數(shù)*/

static int __init s3c24xx_serial_modinit(void)

{

    int ret;


    ret = uart_register_driver(&s3c24xx_uart_drv);/*注冊(cè)u(píng)art_driver*/

    if (ret < 0) {

        printk(KERN_ERR 'failed to register UART drivern');

        return -1;

    }


    return 0;

}


在模塊加載函數(shù)中調(diào)用serial_core.c中的uart_register_driver()注冊(cè)s3c24xx_uart_drv這個(gè)uart_driver,實(shí)際上在uart_register_driver()中包含了tty_register_driver(),代碼如下:


/**

 *    uart_register_driver - register a driver with the uart core layer

 *    @drv: low level driver structure

 *

 *    Register a uart driver with the core driver.  We in turn register

 *    with the tty layer, and initialise the core driver per-port state.

 *

 *    We have a proc file in /proc/tty/driver which is named after the

 *    normal driver.

 *

 *    drv->port should be NULL, and the per-port structures should be

 *    registered using uart_add_one_port after this call has succeeded.

 */

 /*實(shí)際上是填充uart_driver結(jié)構(gòu)體*/

int uart_register_driver(struct uart_driver *drv)

{

    /*聲明一個(gè)tty_driver,接下來填充其中的成員,并使uart_driver中的tty_driver指向這個(gè)結(jié)構(gòu)*/

    struct tty_driver *normal;

    int i, retval;


    BUG_ON(drv->state);


    /*

     * Maybe we should be using a slab cache for this, especially if

     * we have a large number of ports to handle.

     */

     /*分配設(shè)備私有信息結(jié)構(gòu)體的內(nèi)存空間,并初始化為零*/

    drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);

    if (!drv->state)

        goto out;


    normal = alloc_tty_driver(drv->nr);/*分配tty驅(qū)動(dòng)*/

    if (!normal)

        goto out_kfree;


    drv->tty_driver = normal;/*填充uart_driver中封裝的tty_driver,使其指向分配好的tty驅(qū)動(dòng)*/


    /*初始化tty_driver結(jié)構(gòu)體*/

    normal->owner        = drv->owner;

    normal->driver_name    = drv->driver_name;

    normal->name        = drv->dev_name;

    normal->major        = drv->major;

    normal->minor_start    = drv->minor;

    normal->type        = TTY_DRIVER_TYPE_SERIAL;//tty驅(qū)動(dòng)的類型

    normal->subtype        = SERIAL_TYPE_NORMAL;//tty驅(qū)動(dòng)的子類

    normal->init_termios    = tty_std_termios;//初始的termios,即初始的線路設(shè)置,用來提供一個(gè)線路設(shè)置集合

    normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;//控制模式

    normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;

    normal->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

    normal->driver_state    = drv;//~~~~~~

    tty_set_operations(normal, &uart_ops);//設(shè)置tty驅(qū)動(dòng)操作,normal->ops=&uart_ops


    /*

     * Initialise the UART state(s).初始化UART狀態(tài)

     */

    for (i = 0; i < drv->nr; i++) {

        struct uart_state *state = drv->state + i;

        struct tty_port *port = &state->port;


        tty_port_init(port);//tty端口初始化

        port->close_delay     = 500;    /* .5 seconds */

        port->closing_wait    = 30000;    /* 30 seconds */

        tasklet_init(&state->tlet, uart_tasklet_action,

                 (unsigned long)state);//初始化tasklet,即中斷的底半部機(jī)制

    }


    retval = tty_register_driver(normal);//注冊(cè)tty設(shè)備

    if (retval >= 0)

        return retval;


    put_tty_driver(normal);

out_kfree:

    kfree(drv->state);

out:

    return -ENOMEM;

}


二、注冊(cè)平臺(tái)驅(qū)動(dòng) 


s5p_serial_init ----> s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf) ---->  platform_driver_register(drv)


int s3c24xx_serial_init(struct platform_driver *drv,

            struct s3c24xx_uart_info *info)

{

    dbg('s3c24xx_serial_init(%p,%p)n', drv, info);


#ifdef CONFIG_PM

    drv->suspend = s3c24xx_serial_suspend;

    drv->resume = s3c24xx_serial_resume;

#endif


    return platform_driver_register(drv);

}


直接調(diào)用platform_driver_register,注冊(cè)了 s5p_serial_driver這個(gè)平臺(tái)驅(qū)動(dòng)。


三、平臺(tái)驅(qū)動(dòng)的探測函數(shù)probe()


因?yàn)榘製art驅(qū)動(dòng)注冊(cè)為platform驅(qū)動(dòng),當(dāng)平臺(tái)驅(qū)動(dòng)與平臺(tái)設(shè)備進(jìn)行匹配的時(shí)候會(huì)調(diào)用平臺(tái)總線的match函數(shù),匹配成功后就會(huì)調(diào)用平臺(tái)驅(qū)動(dòng)的xxx_probe()函數(shù)來進(jìn)行一系列的初始化工作。


UART驅(qū)動(dòng)的probe()調(diào)用過程如下:


s5p_serial_probe ----> s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]) 


最終調(diào)用的是s3c24xx_serial_probe();


詳細(xì)的代碼分析如下:


/* Device driver serial port probe */

int s3c24xx_serial_probe(struct platform_device *dev,

             struct s3c24xx_uart_info *info)

{

    struct s3c24xx_uart_port *ourport;//s3c24xx_uart_port封裝了uart_port

    int ret;


    dbg('s3c24xx_serial_probe(%p, %p) %dn', dev, info, dev->id);


    if (dev->id >= ARRAY_SIZE(s3c24xx_serial_ports)) {

        dev_err(&dev->dev, 'unsupported device id %dn', dev->id);

        return -ENODEV;

    }


    ourport = &s3c24xx_serial_ports[dev->id];//s3c24xx_serial_ports是s3c24xx_uart_port結(jié)構(gòu)體類型的

    ourport->channelnum= dev->id;



    dbg('%s: initialising port %p...n', __func__, ourport);


    ret = s3c24xx_serial_init_port(ourport, info, dev);//初始化UART端口 ------->

    if (ret < 0)

        goto probe_err;


    dbg('%s: adding portn', __func__);

    uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);//添加端口,配置端口,構(gòu)造與本端口對(duì)應(yīng)的設(shè)備節(jié)點(diǎn)

    platform_set_drvdata(dev, &ourport->port);//將ourport->port保存成平臺(tái)總線設(shè)備的私有數(shù)據(jù)。以后再要使用它時(shí)只需調(diào)用platform_get_drvdata()就可以了


    ret = device_create_file(&dev->dev, &dev_attr_clock_source);//添加設(shè)備屬性

    if (ret < 0)

        printk(KERN_ERR '%s: failed to add clksrc attr.n', __func__);

/*

注冊(cè)通知鏈,當(dāng)CPU頻率改變時(shí)調(diào)用函數(shù)s3c24xx_serial_cpufreq_transition,最終調(diào)用函數(shù)

s3c24xx_serial_set_termios設(shè)置波特率

*/

    ret = s3c24xx_serial_cpufreq_register(ourport);//動(dòng)態(tài)頻率調(diào)節(jié)初始化

    if (ret < 0)

        dev_err(&dev->dev, 'failed to add cpufreq notifiern');


    return 0;


 probe_err:

    return ret;


其中s3c24xx_serial_init_port函數(shù)的分析如下:


/* s3c24xx_serial_init_port

 *

 * initialise a single serial port from the platform device given

 */

/*初始化UART端口,建立各結(jié)構(gòu)體的聯(lián)系,申請(qǐng)中斷,IO資源。復(fù)位端口*/

static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,

                    struct s3c24xx_uart_info *info,

                    struct platform_device *platdev)

{

    struct uart_port *port = &ourport->port;

    struct s3c2410_uartcfg *cfg;

    struct resource *res;

    int ret;


    dbg('s3c24xx_serial_init_port: port=%p, platdev=%pn', port, platdev);


    if (platdev == NULL)

        return -ENODEV;


    //s3c24xx_init_uarts --> s5pv210_init_uarts --> s5pv210_common_init_uarts --> s3c24xx_init_uartdevs -->>platdev->dev.platform_data = cfgptr

    //在該函數(shù)中將cfg掛到platdev->dev.platform_data上。

    cfg = s3c24xx_dev_to_cfg(&platdev->dev);//獲取cfg


    if (port->mapbase != 0)

        return 0;


    if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) {

        printk(KERN_ERR '%s: port %d bigger than %dn', __func__,

               cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS);

        return -ERANGE;

    }


    /* setup info for port */

    port->dev    = &platdev->dev;//讓端口uart_port的成員dev指向平臺(tái)設(shè)備

    //ourport的結(jié)構(gòu)體類型為struct s3c24xx_uart_port不是uart_port。

    //此處的info的結(jié)構(gòu)體類型為s3c24xx_uart_info在文件samsung.h 中定義,s5pv210.c中初始化。不是uart_info。

    ourport->info    = info;


    /* copy the info in from provided structure */

    ourport->port.fifosize = info->fifosize;


    dbg('s3c24xx_serial_init_port: %p (hw %d)...n', port, cfg->hwport);


    port->uartclk = 1;


    if (cfg->uart_flags & UPF_CONS_FLOW) {

        dbg('s3c24xx_serial_init_port: enabling flow controln');

        port->flags |= UPF_CONS_FLOW;

    }


    /* sort our the physical and virtual addresses for each UART */

[1] [2]
關(guān)鍵字:ARM-Linux  S5PV210  UART驅(qū)動(dòng)  串口驅(qū)動(dòng)  初始化過程 引用地址:ARM-Linux S5PV210 UART驅(qū)動(dòng)(4)----串口驅(qū)動(dòng)初始化過程

上一篇:ARM-Linux S5PV210 UART驅(qū)動(dòng)(5)----串口的open操作(tty_open、uart_open)
下一篇:ARM-Linux S5PV210 UART驅(qū)動(dòng)(2)---- 終端設(shè)備驅(qū)動(dòng)

推薦閱讀最新更新時(shí)間:2025-03-31 08:06

淺談分析Arm linux 內(nèi)核移植及系統(tǒng)初始化過程
4.1. 處理器、設(shè)備4.2. 描述 設(shè)備描述主要兩個(gè)結(jié)構(gòu)體完成:struct resource和struct platform_device。 先來看看著兩個(gè)結(jié)構(gòu)體的定義: struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; struct resource *parent, *sibling, *child; }; Resource結(jié)構(gòu)體主要是描述了設(shè)備在系統(tǒng)中的起止地址、名稱、標(biāo)志以及為了鏈?zhǔn)矫枋龇奖阒赶虮窘Y(jié)構(gòu)體類型的指針。Resource定義的實(shí)例將被添加到platform_d
[單片機(jī)]
ARM-LINUX學(xué)習(xí)筆記
昨天安裝了ssh服務(wù)之后今天在windows上用xshell登陸發(fā)現(xiàn)登錄不上,原因是使用了virtualbox的NAT模式,在NAT模式下,客戶機(jī)可以很方便地上網(wǎng),但是想要鏈接宿主機(jī)就需要打開網(wǎng)絡(luò)地址映射 首先要知道ssh服務(wù)使用的是22端口,然后打開windows主機(jī)上的適配器,virtualbox安裝了一張?zhí)摂M網(wǎng)卡,如下 虛擬地址為192.168.56.1,接下來在虛擬機(jī)的設(shè)置界面設(shè)置網(wǎng)絡(luò)地址映射,首先還要知道虛擬機(jī)的IP地址,如下 地址為10.0.2.15,就可以去做端口轉(zhuǎn)發(fā)了,位置如下 按照步驟來,設(shè)置名稱隨意,主機(jī)IP設(shè)置為虛擬機(jī)網(wǎng)卡的IP,端口可以寫一個(gè)未被占用的任意端口,子系統(tǒng)IP為linux宿主
[單片機(jī)]
<font color='red'>ARM-LINUX</font>學(xué)習(xí)筆記
嵌入式專題: S5PV210 - MPEG4編碼
我想說不同的平臺(tái),如tiny210和x210。它們的頭文件是有稍微區(qū)別的。 我這個(gè)是x210下的代碼。但都須要注意的是NV12T與NV12的問題,默認(rèn)要求輸入的圖片是NV12T,經(jīng)過調(diào)整之后,能夠同意用NV12。 即便如此。NV12格式的圖片也不好拿到啊。 #include stdio.h #include string.h #include stdlib.h #include unistd.h #include ../mfc/SsbSipMfcApi.h #include ../mfc/MfcConvert.h #include ../mm/MMClock.h int test_enc_mpeg4(
[單片機(jī)]
【ARM裸機(jī)s5pv210 】時(shí)鐘配置
clock.c // 時(shí)鐘控制器基地址 #define ELFIN_CLOCK_POWER_BASE 0xE0100000 // 時(shí)鐘相關(guān)的寄存器相對(duì)時(shí)鐘控制器基地址的偏移值 #define APLL_LOCK_OFFSET 0x00 #define MPLL_LOCK_OFFSET 0x08 #define APLL_CON0_OFFSET 0x100 #define APLL_CON1_OFFSET 0x104 #define MPLL_CON_OFFSET 0x108 #define CLK_SRC0_OFFSET 0x200 #define CL
[單片機(jī)]
S5PV210 串口配置與實(shí)驗(yàn)(輪詢方式)
S5PV210 UART 相關(guān)說明 通用異步收發(fā)器簡稱 UART, 即 UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTER,它用來傳輸串行數(shù)據(jù)。發(fā)送數(shù)據(jù)時(shí), CPU 將并行數(shù)據(jù)寫入 UART,UART 按照一定的格式在一根電線上串行發(fā)出;接收數(shù)據(jù)時(shí), UART 檢測另一根電線的信號(hào),將串行收集在緩沖區(qū)中, CPU 即可讀取 UART 獲得這些數(shù)據(jù)。 在 S5PV210 中, UART 提供了 4 對(duì)獨(dú)立的異步串口 I/O 端口,有 4 個(gè)獨(dú)立的通道,每個(gè)通道可以工作于 DMA 模式或者中斷模式。其中,通道 0 有 256byte 的的發(fā)送 FIFO 和 256byte 的接收 FIF
[單片機(jī)]
<font color='red'>S5PV210</font> 串口配置與實(shí)驗(yàn)(輪詢方式)
S5PV210點(diǎn)亮LED
GPIO簡介 GPIO(通用輸入/輸出端口)是相對(duì)于芯片而言的,如果在對(duì)應(yīng)的芯片存在GPIO引腳則可以通過讀這些引腳來獲取引腳的變化(即:引腳的高低電平的變化)。 通過寄存器來訪問引腳: 在S3C2410芯片中存在117個(gè)I/O端口,共分為A~H共8組分別為GPA~~GPH,在S3C2440中存在130個(gè)I/O端口,共分為A~J 9組名分別為GPA~GPJ,配置這些端口相應(yīng)的寄存器(GPXCON, x=A~H/J),設(shè)置引腳是用于輸入/輸出,或者是用于特殊功能。控制s3c2440的GPIO端口的寄存器有3類,分別是GPxCON、GPxDAT、GPxUP (x=A ~ J): GPxCON:GPIO控制寄存器,可以設(shè)置選定GPIO口
[單片機(jī)]
<font color='red'>S5PV210</font>點(diǎn)亮LED
【ARM】S5PV210芯片的啟動(dòng)流程
S5PV210芯片的設(shè)計(jì)者的思想 (1)芯片啟動(dòng)后執(zhí)行iRom(BL0)的內(nèi)容,進(jìn)行時(shí)鐘和看門狗等外設(shè)的初始化,將BL1和BL2拷貝到片內(nèi)SRAM; (2)跳轉(zhuǎn)到片內(nèi)SRAM執(zhí)行,完成外部SDRAM的初始化,并將OS從存儲(chǔ)設(shè)備拷貝到SDRAM內(nèi); (3)跳轉(zhuǎn)到SRAM內(nèi)執(zhí)行OS的起始代碼。 由于U-BOOT的大小的限制,無法全部拷貝到片內(nèi)的SRAM,所以U-BOOT的設(shè)計(jì)者設(shè)計(jì)了一下流程 (1)芯片啟動(dòng)后執(zhí)行iRom(BL0)的內(nèi)容,進(jìn)行時(shí)鐘和看門狗等外設(shè)的初始化,將BL1拷貝到片內(nèi)SRAM; (2)跳轉(zhuǎn)到片內(nèi)SRAM內(nèi)進(jìn)行執(zhí)行,完成SDRAM的初始化,將BL2拷貝到SDRAM內(nèi),執(zhí)行。 (3)跳轉(zhuǎn)到SDRAM內(nèi)的BL2進(jìn)行執(zhí)行
[單片機(jī)]
【ARM】<font color='red'>S5PV210</font>芯片的啟動(dòng)流程
S5PV210的SD卡啟動(dòng)實(shí)戰(zhàn)1~2
《朱老師物聯(lián)網(wǎng)大講堂》學(xué)習(xí)筆記 學(xué)習(xí)地址:www.zhulaoshi.org 待燒錄bin程序大于16kb, 分bl1 16kb, 16kb以后的為bl2兩部分, 從sd卡復(fù)制bl2到ddr中特定位置,跳轉(zhuǎn)執(zhí)行bl2。 BL1大致要做,關(guān)開門狗,設(shè)置棧,開iCache,初始化DDR,從SD卡賦值BL2到DDR中特定位置, 然后跳轉(zhuǎn)執(zhí)行BL2, 這個(gè)圖是SD卡布局圖,BLOCK 0是保留的, 這個(gè)細(xì)節(jié)在linux下使用命令燒錄可以看出來, #!/bin/sh sudo dd iflag=dsync oflag=dsync if=210.bin of=/dev/sdb seek=1 而直接使用燒錄工具,這個(gè)細(xì)節(jié)就被工具
[單片機(jī)]
<font color='red'>S5PV210</font>的SD卡啟動(dòng)實(shí)戰(zhàn)1~2
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 峨边| 岳池县| 枣阳市| 东港市| 达尔| 抚顺市| 惠来县| 阳江市| 遵义县| 普定县| 宜丰县| 营山县| 孟津县| 芜湖县| 七台河市| 年辖:市辖区| 四川省| 十堰市| 铁岭市| 天水市| 陕西省| 靖边县| 济源市| 板桥市| 美姑县| 永安市| 基隆市| 南漳县| 思南县| 深水埗区| 钟祥市| 海南省| 江城| 龙海市| 溆浦县| 渭源县| 额济纳旗| 清远市| 柳州市| 牟定县| 科技|