免费国外b站刺激战场直播app,柴火垛里的疯狂55集,百万日元的女人们,洞房初夜

程序小白
認(rèn)證:優(yōu)質(zhì)創(chuàng)作者
所在專題目錄 查看專題
單片機(jī)應(yīng)用與驅(qū)動開發(fā)之路:這時的你只需要扣動扳機(jī)。
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之uart注冊①
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之uart設(shè)備創(chuàng)建②
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之uart操作方法③
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之uart中斷處理④
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之淺析注冊機(jī)制⑤
作者動態(tài) 更多
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之HWTIMER開發(fā)①
1星期前
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之SPI總線操作方法③
2星期前
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之SPI對象創(chuàng)建②
2星期前
電子元器件那些事兒:三極管工作區(qū)的判斷如此簡單①
3星期前
RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之SPI原理①
11-11 14:37

RT-Thread驅(qū)動之路:stm32設(shè)備驅(qū)動開發(fā)之uart注冊①


      開篇分割線,驅(qū)動開發(fā)和應(yīng)用是完全兩條路子,系統(tǒng)里面應(yīng)用程序想要通過名稱或者句柄找到驅(qū)動的必要條件就是,驅(qū)動已經(jīng)被注冊到了系統(tǒng)里了,那么我們的第一篇就聊聊他是如何被注冊到系統(tǒng)里面的,直接上圖看下其調(diào)用關(guān)系:

      首先我們看到系統(tǒng)初始化過程中,需要對板載硬件進(jìn)行初始化,調(diào)用rt_hw_board_init,而內(nèi)部使用大量的預(yù)編譯宏進(jìn)行開關(guān)控制各個硬件部分是不是需要進(jìn)行初始化,接下來看下函數(shù)rt_hw_usart_init:

int rt_hw_usart_init(void)
{
    rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
    rt_err_t result = 0;

    stm32_uart_get_dma_config();

    for (int i = 0; i < obj_num; i++)
    {
        uart_obj[i].config = &uart_config[i];
        uart_obj[i].serial.ops    = &stm32_uart_ops;
        uart_obj[i].serial.config = config;
        /* register UART device */
        result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
                                       RT_DEVICE_FLAG_RDWR
                                       | RT_DEVICE_FLAG_INT_RX
                                       | RT_DEVICE_FLAG_INT_TX
                                       | uart_obj[i].uart_dma_flag
                                       , NULL);
        RT_ASSERT(result == RT_EOK);
    }

    return result;
}

      這里我們先不分析代碼里面的大部分內(nèi)容,而是迎來了系統(tǒng)為我們提供的第一個注冊函數(shù)rt_hw_serial_register,它是你理解注冊的第一步接下來我們看下這個函數(shù)的原形:

/*
 * serial register
 */
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct serial_device *serial)
{
    RT_ASSERT(device != RT_NULL);

    device->type        = RT_Device_Class_Char;
    device->rx_indicate = RT_NULL;
    device->tx_complete = RT_NULL;
    device->init        = rt_serial_init;
    device->open        = rt_serial_open;
    device->close       = rt_serial_close;
    device->read        = rt_serial_read;
    device->write       = rt_serial_write;
    device->control     = rt_serial_control;
    device->user_data   = serial;

    /* register a character device */
    return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
}

      我們注意下它的輸入?yún)?shù),這非常重要,第一個就是一個對象實體(當(dāng)然C語言中就是一個結(jié)構(gòu)體變量),第二個參數(shù)我們得給這個對象起個名字,這樣方便我們的應(yīng)用更好的找到我們的對象,第三個參數(shù)是對象的人設(shè)(舉個例子它可以進(jìn)行那些操作的合集,比如或者讀or寫),四個參數(shù)則是這個對象的私有數(shù)據(jù)(user_data,也就是我和別人不一樣的點),這個函數(shù)的主要任務(wù)就是,定義設(shè)備的類型:RT_Device_Class_Char,并且設(shè)備的動作賦真實可操作的值:初始化/打開/關(guān)閉/讀/寫/控制操作。

      最后的最后它需要調(diào)用系統(tǒng)提供的rt_device_register完成最終的注冊,原型如下:

      最后的最后我們倒序的方式回憶一下,設(shè)備注冊都做了什么:

rt_device_register:設(shè)備對象dev  與設(shè)備name 建立聯(lián)系,并賦值掙得操作flag類型。

rt_hw_serial_register:設(shè)備對象dev的操作方法具體賦值,私有數(shù)據(jù)賦值和類型賦值,豐富dev對象,然后調(diào)用rt_device_register。

rt_hw_usart_init:傳入真實的設(shè)備操作方法,比如我們用的是stm32芯片,這里就需要將真實的硬件驅(qū)動操作方法,串口配置參數(shù)傳入到serial結(jié)構(gòu)體中,下一章我們會基于這個API講講設(shè)備驅(qū)動的詳細(xì)實現(xiàn)細(xì)節(jié)。

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 4
關(guān)注 138
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧