<em id="hanht"></em>

    <dd id="hanht"></dd>

    <em id="hanht"><acronym id="hanht"></acronym></em>
    
    <button id="hanht"></button>
    <rp id="hanht"><object id="hanht"><blockquote id="hanht"></blockquote></object></rp><em id="hanht"></em>

    首頁 > 學院 > 系統知識 > 正文

    怎樣優雅的將Docker Registry中容器鏡像遷移至Harbor

    2022-07-09 12:57:39
    字體:
    來源:轉載
    供稿:網友
    前言
    上一篇文章中最后在操作led燈的硬件時候,我們是直接讀的原理圖,去操作的寄存器,這種情況是我們絕大多數情況下會這樣子進行操作,而本章我們的核心重點是使用總線機制,也就是通過修改設備樹的方法來操作硬件。
     
    涉及到的概念介紹
    1.總線的概念
    總線是處理器與一個或者多個設備之間的通道。在設備模型中,所有的設備都通過總線相連。甚至是那些內部的虛擬“平臺”總線??偩€可以相互插入,比如一個USB控制器通常是一個PCI設備。設備模型展示了總線和它們所控制的設備之間的連接。
     
    1.驅動程序
    1.1 總線的使用邏輯首先調用
     
    為了正確地注冊到內核,所有的platform驅動程序都必須創建的主要結構體是struct platform_driver結構體。該結構體由許多回調函數和變量組成,向platform描述了platform驅動程序。所以我們需要寫一個struct platform_driver結構體。然后在其中有兩個比較重要的回調函數:probe和remove
     
    int (*probe)(…)指向platform驅動程序中的探測函數的指針。當platform核心有一個它認為驅動程序需要控制的struct platform_device時,就會調用該函數。所以我們會在這個函數中寫驅動程序的邏輯。
    int (*remove)(…)指向一個移除函數的指針,當struct platform_device被從系統中移除,或者platform驅動程序正在從內核中卸載時,platform核心調用該函數。
    為了把struct platform_driver注冊到platform核心中,需要調用以struct platform_driver為參數的platform_driver_register函數。通常在platform驅動程序的模塊化代碼中完成該工程。
     
    當platform驅動程序將要被卸載的時候,需要把struct platform_driver從內核注銷。這是通過調用platform_driver_unregister完成的。
     
    1.2 完整實現代碼
     
    #include <linux/module.h>
    #include <linux/poll.h>
    #include <linux/fs.h>
    #include <linux/errno.h>
    #include <linux/miscdevice.h>
    #include <linux/kernel.h>
    #include <linux/major.h>
    #include <linux/mutex.h>
    #include <linux/proc_fs.h>
    #include <linux/seq_file.h>
    #include <linux/stat.h>
    #include <linux/init.h>
    #include <linux/device.h>
    #include <linux/tty.h>
    #include <linux/kmod.h>
    #include <linux/gfp.h>
    #include <linux/gpio/consumer.h>
    #include <linux/platform_device.h>
    #include <linux/of_gpio.h>
    #include <linux/of_irq.h>
    #include <linux/interrupt.h>
    #include <linux/irq.h>
    #include <linux/slab.h>
    #include <linux/fcntl.h>
    #include <linux/timer.h>
    #include <linux/workqueue.h>
    #include <asm/current.h>
    static int major;
    static struct class *sr501_class;
    static struct gpio_desc *sr501_gpio;
    static int irq;
    static int sr501_data = 0;   
    static wait_queue_head_t sr501_wq;
    /* 實現對應的open/read/write等函數,填入file_operations結構體                   */
    static ssize_t sr501_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
    {
    #if 0
        int val;
        int len = (size < 4)? size : 4;
         
        val = gpiod_get_value(sr501_gpio);  
        copy_to_user(buf, &val, len);
        return len;
    #else
        int val;
        int len = (size < 4)? size : 4;
        /* 1. 有數據就copy_to_uesr */
        /* 2. 無數據就休眠:  放入某個鏈表 */
        wait_event_interruptible(sr501_wq, sr501_data);  
        copy_to_user(buf, &sr501_data, len);
        sr501_data = 0;
        return len;
    #endif
    }
     
    static unsigned int sr501_drv_poll(struct file *fp, poll_table * wait)
    {
        return 0;
    }
    /* 定義自己的file_operations結構體                                              */
    static struct file_operations sr501_fops = {
        .owner   = THIS_MODULE,
        .read    = sr501_drv_read,
        .poll    = sr501_drv_poll,
    };
    static irqreturn_t sr501_isr(int irq, void *dev_id)
    {
        printk("%s %s line %d ", __FILE__, __FUNCTION__, __LINE__);
        /* 1. 記錄數據 */
        sr501_data = 1;
        /* 2. 喚醒APP:去同一個鏈表把APP喚醒 */
        wake_up(&sr501_wq);  
        return IRQ_HANDLED;
    }
    /* 1. 從platform_device獲得GPIO
     * 2. gpio=>irq
     * 3. request_irq
     */
    static int sr501_probe(struct platform_device *pdev)
    {
        /* 1. 獲得硬件信息 */
        sr501_gpio = gpiod_get(&pdev->dev, NULL, 0);
        gpiod_direction_input(sr501_gpio);
        irq = gpiod_to_irq(sr501_gpio);
        request_irq(irq, sr501_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr501", NULL);
        /* 注冊file_operations    */
        major = register_chrdev(0, "sr501", &sr501_fops);   
     
        sr501_class = class_create(THIS_MODULE, "sr501_class");
        if (IS_ERR(sr501_class)) {
            printk("%s %s line %d ", __FILE__, __FUNCTION__, __LINE__);
            unregister_chrdev(major, "sr501");
            return PTR_ERR(sr501_class);
        }
        /* 2. device_create */
        device_create(sr501_class, NULL, MKDEV(major, 0), NULL, "sr501");
     
        return 0;
    }
    static int sr501_remove(struct platform_device *pdev)
    {
        device_destroy(sr501_class, MKDEV(major, 0));
        class_destroy(sr501_class);
        unregister_chrdev(major, "sr501");
    }
    static const struct of_device_id qzk_sr501[] = {
        { .compatible = "qzk,sr501" },
        { },
    };
    /* 1. 定義platform_driver */
    static struct platform_driver sr501s_driver = {
        .probe      = sr501_probe,
        .remove     = sr501_remove,
        .driver     = {
            .name   = "qzk_sr501",
            .of_match_table = qzk_sr501,
        },
    };
    /* 2. 在入口函數注冊platform_driver */
    static int __init sr501_init(void)
    {
        int err;
        printk("%s %s line %d ", __FILE__, __FUNCTION__, __LINE__);
        init_waitqueue_head(&sr501_wq);
        err = platform_driver_register(&sr501s_driver);  
        return err;
    }
    /* 3. 有入口函數就應該有出口函數:卸載驅動程序時,就會去調用這個出口函數
     *     卸載platform_driver
     */
    static void __exit sr501_exit(void)
    {
        printk("%s %s line %d ", __FILE__, __FUNCTION__, __LINE__);
     
        platform_driver_unregister(&sr501s_driver);
    }
    /* 7. 其他完善:提供設備信息,自動創建設備節點                                     */
     
    module_init(sr501_init);
    module_exit(sr501_exit);
    MODULE_LICENSE("GPL");
    2.修改設備樹
    2.1 修改思路
     
    在上述驅動中of_device_id結構體中的.compatible = “qzk,sr501”,所以我們需要將設備樹中添加一個這樣的設備節點
     
    2.2 修改代碼如下:
     
    Linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull-14x14.dts
     
    HDF驅動框架探路(六):linux總線機制imx6ull驅動sr501紅外傳感器-鴻蒙HarmonyOS技術社區
    3.應用側測試程序
     測試程序完成實現代碼
     
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
     
    int main(int argc, char **argv)
    {
        int fd;
        int val;
        fd = open("/dev/sr501", O_RDWR);
        if (fd == -1)
        {
            printf("can not open file %s ", argv[1]);
            return -1;
        }
     
        while (1)
        {
            read(fd, &val, 4);
            if (val == 0x1) {
                printf("detect people ");
            }
        }
         
        close(fd);
         
        return 0;
    }
    4.編譯
      make編譯驅動程序
     
    KERN_DIR =  ~/imx6ullpro/Linux-4.9.88 # 板子所用內核源碼的目錄
    all:
        make -C $(KERN_DIR) M=`pwd` modules
        $(CROSS_COMPILE)gcc -o sr501_test sr501_test.c
    clean:
        make -C $(KERN_DIR) M=`pwd` modules clean
        rm -rf modules.order
    obj-m += sr501_drv.o
    直接執行make腳本執行上述Makefile生成測試程序和驅動ko文件
     

    (編輯:錯新網)

    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    一级特黄大片欧美久久久久_一本一道久久综合狠狠老_JLZZ日本人年轻护士_欧美男男作爱VIDEOS可播放
      <em id="hanht"></em>

      <dd id="hanht"></dd>

      <em id="hanht"><acronym id="hanht"></acronym></em>
      
      <button id="hanht"></button>
      <rp id="hanht"><object id="hanht"><blockquote id="hanht"></blockquote></object></rp><em id="hanht"></em>