<ruby id="55ddb"><mark id="55ddb"></mark></ruby>
    <p id="55ddb"><cite id="55ddb"><dfn id="55ddb"></dfn></cite></p>
          <ruby id="55ddb"></ruby>
          <p id="55ddb"></p>

          <pre id="55ddb"></pre>

          <p id="55ddb"></p><pre id="55ddb"><del id="55ddb"><mark id="55ddb"></mark></del></pre>

          創作

          完善資料讓更多小伙伴認識你,還能領取20積分哦, 立即完善>

          3天內不再提示

          RT-Thread記錄(十、全面認識 I/O 設備模型)

          矜辰所致 ? 來源:矜辰所致 ? 作者:矜辰所致 ? 2022-06-30 10:38 ? 次閱讀
          學完 RT-Thread 內核,從本文開始熟悉了解 RT-Thread I/O 設備管理相關知識。

          目錄

          前言
          一、RT-Thread 的 I/O設備管理

          1.1 什么是 I/O 設備模型
          1.2 I/O 設備模型框架解析
          1.2.1 應用程序
          1.2.2 I/O 設備管理層
          1.2.3 設備驅動框架層
          1.2.4 設備驅動層
          1.2.5 硬件
          1.3 I/O 設備操作邏輯說明
          1.4 I/O 設備模型框架有什么用?

          二、I/O 設備模型操作 API

          2.1 I/O 設備控制塊
          2.1.1 設備類型 type
          2.1.2 設備注冊 flag
          2.1.3 設備訪問 open_flag
          2.2 創建 I/O 設備相關
          2.2.1 創建設備
          2.2.2 銷毀設備
          2.2.3 設備注冊
          2.2.4 設備注銷
          2.3 訪問 I/O 設備相關
          2.3.1 查找設備
          2.3.2 初始化設備
          2.3.3 打開和關閉設備
          2.3.4 讀寫設備
          2.3.5 控制設備
          2.3.6 數據收發回調

          三、新建 I/O 設備模型實例
          結語

          前言

          我們已經把 RT-Thread 內核學習完成,也已經使用 RT-Thread 做了一個實例應用。

          但是作為一個操作系統, RT-Thread 除了內核部分還有自己的設備框架,類似于 Linux 操作系統設備的管理方式的 I/O 設備模型。

          從本文開始,我們要開始學習了解 RT-Thread 的 I/O 設備模型。

          說明,概念性質的說明主要還是使用引用方式,畢竟有權威的官方在,對于一些細節的理解,我會闡述自己的看法,同時會設計一些實例加深我們對基本概念的理解。

          ?? 我想做到的是,僅此一片文章,讓所有人都能明白RT-Thread 的I/O 設備模型 ??

          一、RT-Thread 的 I/O設備管理

          有些小伙伴在剛接觸到這個概念的時候還不太明白, I/O 設備模型,IO口? IO口的模型?

          注意這里的 I/O 指的是 Input/Output。I/O 設備,就是指的輸入 / 輸出設備。

          所謂 I/O 設備模型,指的是 RT-Thread 把所有的 輸入 / 輸出設備當做一類對象,然后通過自己的一套體系對這類對象進行管理,這類 I/O 設備對象就可以認為是 I/O 設備模型。

          RT-Thread 提供了一套模型框架用來對所有的輸入/輸出設備進行管理的,名叫 I/O 設備模型框架 ,其 位于硬件層和應用程序之間,包括IO設備管理層、設備驅動框架層和設備驅動層,向上層層抽象,目標是針對各種不同的I/O設備提供給應用程序相同的接口,如下圖:

          pYYBAGK9DJWALOWBAAOPg3TZ6Ho023.png

          1.2 I/O 設備模型框架解析

          根據上圖,結合工程代碼,我們對每個層分別說:

          1.2.1 應用程序

          我們寫的應用程序,調用 I/O 設備管理層給的接口進行底層硬件操作;

          對應 main.c :

          poYBAGK9DJWAK43VAAA3FT2lzKM769.png

          1.2.2 I/O 設備管理層

          I/O 設備管理層實現了對設備驅動程序的封裝。
          應用程序通過 I/O 設備管理接口獲得正確的設備驅動,然后通過這個設備驅動與底層 I/O 硬件設備進行數據交互。
          設備驅動程序的升級、更替不會對上層應用產生影響。這種方式使得設備的硬件操作相關的代碼能夠獨立于應用程序而存在,雙方只需關注各自的功能實現,從而降低了代碼的耦合性、復雜性,提高了系統的可靠性。

          對應 device.c

          pYYBAGK9DJWAEce_AAApcEWezF4881.png

          1.2.3 設備驅動框架層

          設備驅動框架層對同類硬件設備驅動的抽象,將不同廠家的同類硬件設備驅動中相同的部分抽取出來,將不同部分留出接口,由驅動程序實現。

          對應的比如 serial.c 等

          poYBAGK9DJaAG9KJAAA3hwS3nZU266.png

          ?? 上面的 I/O 設備管理層 和 設備驅動框架層 是屬于RT-Thread 系統的范疇,官方已寫好,所以在項目中的位置存放于 rt-thread 文件夾下面。

          1.2.4 設備驅動層

          設備驅動層是一組驅使硬件設備工作的程序,實現訪問硬件設備的功能。它負責創建和注冊 I/O 設備,就類似于使用裸機編寫程序時候的底層驅動。
          裸機的驅動是直接被應用層調用,這里的驅動是提供給 設備驅動框架層調用 或者 直接給 I/O 設備管理層調用的。

          對于一些常用的芯片或者與官方有合作的芯片,官方也會提供了寫好的驅動,比如STM32,下圖就是官方已經寫好的基于STM32 的設備驅動層的代碼。

          對應比如 drv_gpio.c 、drv_usart.c 這些 :

          pYYBAGK9DJaAf10ZAAA651d5Q04796.png

          ?? 設備驅動層的編寫是需要基于芯片或外設的手冊、SDK,是需要額外實現的。
          但是有些常用芯片和外設官方已經幫我們寫好了,比如基于 STM32 的 HAL 庫,RT-Thread官方已經實現了基于 STM32 的設備驅動層 。

          1.2.5 硬件層

          比如Flash芯片,SD卡,stm32芯片等外設和MCU設備。

          1.3 I/O 設備操作邏輯說明

          簡單介紹一下 I/O 設備操作邏輯,這部分應用官方的說明。

          對于操作邏輯簡單的設備,可以不經過設備驅動框架層,直接將設備注冊到 I/O 設備管理器中,過程如下:

          在我們本文后面的新建設備模型實例中就舉了個簡單設備的例子。

          poYBAGK9DJaASOvsAADEkSQNTGw266.png

          對于復雜點的設備,需要經過設備驅動框架層:

          pYYBAGK9DJaAXsODAACyCrlrinY973.pngpoYBAGK9DJaADCALAADNyf5MhT0777.png

          為了更好的理解上面的流程,可以結合工程源碼理解,多看源碼,比如下圖所示:

          pYYBAGK9DJeAKfIJAAD8rGHr6D0552.png

          1.4 I/O 設備模型框架有什么用?

          有很多初學者會問, I/O 設備模型意義在哪里? 在裸機使用中,比如操作一個IO口,直接調用驅動函數,不是更簡單,更直接,使用了設個模型,反而變得復雜了?

          在某些時候,如果你只使用一種芯片一種方案,或許某種意義上說, I/O 設備模型確實可能會比直接調用驅動函數復雜。 也可以說,你使用的方案單一,項目簡單,沒有必要使用 I/O 設備模型,甚至可能連 RTOS 都不一定需要。

          總之就是,只用一種芯片方案簡單項目或者內存空間實在有限,完全是可以不用這個框架,直接用 RT-Thread Nano 完成功能,和我們前面講的項目實例一樣完成,是沒有問題的!

          但是作為一個工程師,不能局限在一種方案上面,尤其當今芯片市場變幻莫測,指不定哪天需要換芯片,換方案呢? 而且 RT-Thread 作為一個面向對象思想設計的操作系統,必須得全面考慮,需要降低了代碼的耦合性、復雜性,提高了系統的可靠性,能夠使得系統運行與不同的芯片設備上。

          如果沒有 I/O 設備模型,那么每次換方案,從底層到應用層所有的代碼基本上都得重寫,對于簡單的項目無所謂,對于復雜一點的項目,那可是需要花費大量功夫。

          使用了 RT-Thread 的 I/O 設備模型,不管你使用哪種MCU,應用層對設備操作的函數一模一樣,設備驅動程序的升級、更替不會對上層應用產生影響。這種方式使得設備的硬件操作相關的代碼能夠獨立于應用程序而存在,雙方只需關注各自的功能實現。

          如果學過 Linux 的朋友肯定知道,RT-Thread 的 I/O 設備模型 思想 是和 Linux 類似的,作為嵌入式工程師,如果你懂 Linux,那么就應該知道 I/O 設備模型框架 的優點。如果你不懂 Linux,那么學會了 RT-Thread 操作系統的 I/O 設備模型,對于以后深入學習 Linux 操作系統,也是有幫助的 。 這話沒毛??! 感覺怎么說怎么有道理,人往高處走嘛!= =!

          所有最終結果就是,反正就是好,人往高處走,學會了沒壞處 = =!

          二、I/O 設備模型操作 API

          上文我們說明了RT-Thread I/O 設備模型的基本概念先關內容,也了解了 I/O 設備模型框架以及操作邏輯,那么我們用戶該如何來實現這一流程呢?

          所以現在我們就來學習一下I/O設備模型操作的相關API函數,包括創建、注冊、訪問等 。。。

          2.1 I/O 設備控制塊

          我們不止一次的說明了 RT-Thread 的面向對象的思想,在RT-Thread中,設備也是一種內核對象,那么他和以前說的線程,IPC機制,定時器等對象一樣,有自己的對象控制塊。

          在以前博文:RT-Thread記錄(六、IPC機制之信號量、互斥量和事件集)這里再次額外說明一下,因為只要理解了這種思想,對于學會他們的使用就更加簡單了,在IPC機制的時候我們使用圖片說明過:

          poYBAGK9DJeAZ3NoAAPLTvh7m9w388.pngpYYBAGK9DJiACQcdAAQfsPD-ENk782.png

          其實我們可以看一下設備對象的控制塊:

          poYBAGK9DJiAIzRcAAEkupi7DCI510.png

          上源碼方便以后復制:

          /**
           * Device structure 設備控制塊
           */
          struct rt_device
          {
              struct rt_object          parent;                   /**< inherit from rt_object */
          
              enum rt_device_class_type type;                     /**< device type */
              rt_uint16_t               flag;                     /**< device flag */
              rt_uint16_t               open_flag;                /**< device open flag */
          
              rt_uint8_t                ref_count;                /**< reference count */
              rt_uint8_t                device_id;                /**< 0 - 255 */
          
              /* device call back */
              rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
              rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
          
          #ifdef RT_USING_DEVICE_OPS
              const struct rt_device_ops *ops;
          #else
              /* common device interface */
              rt_err_t  (*init)   (rt_device_t dev);
              rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
              rt_err_t  (*close)  (rt_device_t dev);
              rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
              rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
              rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);
          #endif
          
          #if defined(RT_USING_POSIX)
              const struct dfs_file_ops *fops;
              struct rt_wqueue wait_queue;
          #endif
          
              void                     *user_data;                /**< device private data */
          };

          2.1.1 設備類型 type

          設備對象的控制塊中對于設備類型使用了一個rt_device_class_type枚舉的方式,其可能的設備類型如下(簡單的沒有注釋,還有部分嗎不太清楚的,以后更新):

          pYYBAGK9DJiAIFJlAAEf0PiIGlg009.png

          設備類型 需要在創建的時候選擇好,寫驅動的時候應該知道自己寫的是什么類型的設備。

          2.1.2 設備注冊 flag

          設備對象的控制塊中有一個 flag 參數,設備模式標志 ,表示設備是屬于什么狀態的設備,可讀、可寫、收發等,其可以有的參數如下:

          poYBAGK9DJiAO5iiAADbHHtBd0s404.png

          注意,該標志可以采用或的方式支持多種參數。

          設備注冊 flag 需要在創建的時候選擇好,寫驅動的時候應該知道自己寫的設備是什么狀態,比如只讀。只寫,中斷接收之類的。

          2.1.3 設備訪問 open_flag

          設備對象的控制塊中有一個 open_flag 參數,設備打開模式標志 ,表示對設備進行什么操作,其可以有的參數如下:

          pYYBAGK9DJiAQMcEAACi9CQYMmU840.png

          設備訪問的時候,需要使用這個 open_flag 來判斷需要對設備進行什么操作,是讀?還是寫? 還是發送等。。。

          ?? 介紹了 I/O 設備控制塊,讓我們清楚我們要操作的對象是什么,我們在 設備驅動層 要寫的設備驅動以及上層應用對 I/O 設備的訪問, 就是基于這個控制塊來進行的。

          2.2 創建 I/O 設備相關

          我們按照 先創建設備,再訪問設備 的順序來介紹對于的 API 函數。

          2.2.1 創建設備

          老規矩用源碼,解釋看注釋(使用起來也方便復制 ~ ~?。?/p>

          /*
          參數的含義:
          1、type 		設備類型,上面 2.1.1 小結說明的設備類型
          2、attach_size  用戶數據大小
          返回值:
          創建成功,返回設備的控制塊指針
          創建失敗,返回RT_BULL 
          */
          
          rt_device_t rt_device_create(int type, int attach_size)
          
          /**
           * device (I/O) class type  設備類型
           */
          enum rt_device_class_type
          {
              RT_Device_Class_Char = 0,                           /**< character device */
              RT_Device_Class_Block,                              /**< block device */
              RT_Device_Class_NetIf,                              /**< net interface */
              RT_Device_Class_MTD,                                /**< memory device */
              RT_Device_Class_CAN,                                /**< CAN device */
              RT_Device_Class_RTC,                                /**< RTC device */
              RT_Device_Class_Sound,                              /**< Sound device */
              RT_Device_Class_Graphic,                            /**< Graphic device */
              RT_Device_Class_I2CBUS,                             /**< I2C bus device */
              RT_Device_Class_USBDevice,                          /**< USB slave device */
              RT_Device_Class_USBHost,                            /**< USB host bus */
              RT_Device_Class_SPIBUS,                             /**< SPI bus device */
              RT_Device_Class_SPIDevice,                          /**< SPI device */
              RT_Device_Class_SDIO,                               /**< SDIO bus device */
              RT_Device_Class_PM,                                 /**< PM pseudo device */
              RT_Device_Class_Pipe,                               /**< Pipe device */
              RT_Device_Class_Portal,                             /**< Portal device */
              RT_Device_Class_Timer,                              /**< Timer device */
              RT_Device_Class_Miscellaneous,                      /**< Miscellaneous device */
              RT_Device_Class_Sensor,                             /**< Sensor device */
              RT_Device_Class_Touch,                              /**< Touch device */
              RT_Device_Class_PHY,                                /**< PHY device */
              RT_Device_Class_Unknown                             /**< unknown device */
          };

          設備被創建后,需要實現它訪問硬件的操作方法,要按照下面的函數指針實現這些對于設備的操作函數:

          /* common device interface */
              rt_err_t  (*init)   (rt_device_t dev);
              rt_err_t  (*open)   (rt_device_t dev, rt_uint16_t oflag);
              rt_err_t  (*close)  (rt_device_t dev);
              rt_size_t (*read)   (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
              rt_size_t (*write)  (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
              rt_err_t  (*control)(rt_device_t dev, int cmd, void *args);

          這里引用官方的說明:

          poYBAGK9DJmAbYFbAAI0qwEx3Bg850.png

          2.2.2 銷毀設備

          此函數不一定需要使用,但是有創建就應該有銷毀:

          /*
          參數的含義:
          dev 	設備句柄
          */
          void rt_device_destroy(rt_device_t dev)

          2.2.3 設備注冊

          設備被創建后,需要注冊到 I/O 設備管理器中,應用程序才能夠訪問:

          /*
          參數的含義:
          dev 	設備句柄
          name 	設備名稱,
          設備名稱的最大長度由 rtconfig.h 中定義的宏 RT_NAME_MAX 指定,多余部分會被自動截掉
          flags 	設備模式標志,就是上面介紹的 2.1.2 設備注冊 flag
          返回值:
          RT_EOK 	注冊成功
          -RT_ERROR 	注冊失敗,dev 為空或者 name 已經存在
          */
          rt_err_t rt_device_register(rt_device_t dev,
                                      const char *name,
                                      rt_uint16_t flags)
          
          
          /*設備注冊 flag*/
          #define RT_DEVICE_FLAG_DEACTIVATE       0x000           /**< device is not not initialized */
          
          #define RT_DEVICE_FLAG_RDONLY           0x001           /**< read only */
          #define RT_DEVICE_FLAG_WRONLY           0x002           /**< write only */
          #define RT_DEVICE_FLAG_RDWR             0x003           /**< read and write */
          
          #define RT_DEVICE_FLAG_REMOVABLE        0x004           /**< removable device */
          #define RT_DEVICE_FLAG_STANDALONE       0x008           /**< standalone device */
          #define RT_DEVICE_FLAG_ACTIVATED        0x010           /**< device is activated */
          #define RT_DEVICE_FLAG_SUSPENDED        0x020           /**< device is suspended */
          #define RT_DEVICE_FLAG_STREAM           0x040           /**< stream mode */
          
          #define RT_DEVICE_FLAG_INT_RX           0x100           /**< INT mode on Rx */
          #define RT_DEVICE_FLAG_DMA_RX           0x200           /**< DMA mode on Rx */
          #define RT_DEVICE_FLAG_INT_TX           0x400           /**< INT mode on Tx */
          #define RT_DEVICE_FLAG_DMA_TX           0x800           /**< DMA mode on Tx */
          上面需要額外說明的一點,設備流模式 `RT_DEVICE_FLAG_STREAM` 參數用于向串口終端輸出字符串:
          當輸出的字符是 “\n” 時,自動在前面補一個 “\r” 做分行。

          2.2.4 設備注銷

          創建對銷毀,注冊對注銷:

          /**
          參數 	描述
          dev 	設備句柄
          返回 	——
          RT_EOK 	成功
           */
          rt_err_t rt_device_unregister(rt_device_t dev)

          當設備注銷后的,設備將從設備管理器中移除,也就不能再通過設備查找搜索到該設備。注銷設備不會釋放設備控制塊占用的內存。
          注銷只是把這個 設備對象結構體 從管理鏈表中去掉,并不會釋放這個對象結構體的空間,要釋放空間需要調用銷毀設備函數。

          ?? 創建 I/O 設備相關的函數,和 I/O 設備模型框架中 設備驅動層 有關,在我們底層寫驅動的時候需要使用。

          2.3 訪問 I/O 設備相關

          上面我們說的創建 I/O 設備相關是和 設備驅動層 有關的代碼,本小結說的訪問 I/O 設備就是和 應用程序有關的代碼,就是告訴我們應用程序怎么去操作我們上面創建的設備。

          I/O 設備管理接口與 I/O 設備的操作方法的映射關系下圖:

          pYYBAGK9DJmAYOf9AAERyxaJSRg014.png

          2.3.1 查找設備

          注冊過的設備才能被查找到,名字對應注冊時候使用的名字:

          /**
          參數 	描述
          name 	設備名稱
          返回 	——
          設備句柄 	查找到對應設備將返回相應的設備句柄
          RT_NULL 	沒有找到相應的設備對象
           */
          rt_device_t rt_device_find(const char *name)

          2.3.2 初始化設備

          對應底層rt_err_t (*init) (rt_device_t dev); 的實現函數:

          /**
          參數 	描述
          dev 	設備句柄
          返回 	——
          RT_EOK 	設備初始化成功
          錯誤碼 	設備初始化失敗
           */
          rt_err_t rt_device_init(rt_device_t dev)

          當一個設備已經初始化成功后,調用這個接口將不再重復做初始化 0。

          2.3.3 打開和關閉設備

          打開設備:

          對應底層rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); 的實現函數:

          /*
          參數 	描述
          dev 	設備句柄
          oflags 	設備打開模式標志,上面 2.1.3 小結說明的設備訪問 open_flag
          返回 	——
          RT_EOK 	設備打開成功
          -RT_EBUSY 	如果設備注冊時指定的參數中包括 RT_DEVICE_FLAG_STANDALONE 參數,此設備將不允許重復打開
          其他錯誤碼 	設備打開失敗
          */
          rt_err_t  rt_device_open (rt_device_t dev, rt_uint16_t oflag);
          
          #define RT_DEVICE_FLAG_INT_RX           0x100           /**< INT mode on Rx */
          #define RT_DEVICE_FLAG_DMA_RX           0x200           /**< DMA mode on Rx */
          #define RT_DEVICE_FLAG_INT_TX           0x400           /**< INT mode on Tx */
          #define RT_DEVICE_FLAG_DMA_TX           0x800           /**< DMA mode on Tx */
          
          #define RT_DEVICE_OFLAG_CLOSE           0x000           /**< 設備已經關閉(內部使用) */
          #define RT_DEVICE_OFLAG_RDONLY          0x001           /**< read only access */
          #define RT_DEVICE_OFLAG_WRONLY          0x002           /**< write only access */
          #define RT_DEVICE_OFLAG_RDWR            0x003           /**< read and write */
          #define RT_DEVICE_OFLAG_OPEN            0x008           /**< device is opened */
          #define RT_DEVICE_OFLAG_MASK            0xf0f           /**< mask of open flag */

          注:如果上層應用程序需要設置設備的接收回調函數,則必須以 RT_DEVICE_FLAG_INT_RX 或者 RT_DEVICE_FLAG_DMA_RX 的方式打開設備,否則不會回調函數。

          關閉設備:

          對應底層rt_err_t (*close) (rt_device_t dev); 的實現函數:

          /*
          dev 	設備句柄
          返回 	——
          RT_EOK 	關閉設備成功
          -RT_ERROR 	設備已經完全關閉,不能重復關閉設備
          其他錯誤碼 	關閉設備失敗
          */
          rt_err_t  rt_device_open (rt_device_t dev, rt_uint16_t oflag);

          關閉設備接口和打開設備接口需配對使用,打開一次設備對應要關閉一次設備,這樣設備才會被完全關閉,否則設備仍處于未關閉狀態。

          2.3.4 讀寫設備

          讀設備:

          對應底層rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); 的實現函數:

          /**
          參數 	描述
          dev 	設備句柄
          pos 	讀取數據偏移量
          buffer 	內存緩沖區指針,讀取的數據將會被保存在緩沖區中
          size 	讀取數據的大小
          返回 	——
          讀到數據的實際大小 	如果是字符設備,返回大小以字節為單位,如果是塊設備,返回的大小以塊為單位
          0 	需要讀取當前線程的 errno 來判斷錯誤狀態
           */
          rt_size_t rt_device_read(rt_device_t dev,
                                   rt_off_t    pos,
                                   void       *buffer,
                                   rt_size_t   size)

          調用這個函數,會從 dev 設備中讀取數據,并存放在 buffer 緩沖區中,這個緩沖區的最大長度是 size,pos 根據不同的設備類別有不同的意義。

          寫設備:

          對應底層rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); 的實現函數:

          /**
          參數 	描述
          dev 	設備句柄
          pos 	寫入數據偏移量
          buffer 	內存緩沖區指針,放置要寫入的數據
          size 	寫入數據的大小
          返回 	——
          寫入數據的實際大小 	如果是字符設備,返回大小以字節為單位;如果是塊設備,返回的大小以塊為單位
          0 	需要讀取當前線程的 errno 來判斷錯誤狀態
           */
          rt_size_t rt_device_write(rt_device_t dev,
                                    rt_off_t    pos,
                                    const void *buffer,
                                    rt_size_t   size)

          調用這個函數,會把緩沖區 buffer 中的數據寫入到設備 dev 中,寫入數據的最大長度是 size,pos 根據不同的設備類別存在不同的意義。

          2.3.5 控制設備

          對應底層rt_err_t (*control)(rt_device_t dev, int cmd, void *args); 的實現函數:

          /**
          參數 	描述
          dev 	設備句柄
          cmd 	命令控制字,這個參數通常與設備驅動程序相關,見下面列出的參數
          arg 	控制的參數
          返回 	——
          RT_EOK 		函數執行成功
          -RT_ENOSYS 	執行失敗,dev 為空
          其他錯誤碼 	執行失敗
           */
          rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)
          
          
          /**
           * general device commands 上面 cmd 的參數
           */
          #define RT_DEVICE_CTRL_RESUME           0x01            /**< resume device */
          #define RT_DEVICE_CTRL_SUSPEND          0x02            /**< suspend device */
          #define RT_DEVICE_CTRL_CONFIG           0x03            /**< configure device */
          #define RT_DEVICE_CTRL_CLOSE            0x04            /**< close device */
          
          #define RT_DEVICE_CTRL_SET_INT          0x10            /**< set interrupt */
          #define RT_DEVICE_CTRL_CLR_INT          0x11            /**< clear interrupt */
          #define RT_DEVICE_CTRL_GET_INT          0x12            /**< get interrupt status */

          2.3.6 數據收發回調

          這個對于 設備控制塊中參數中的兩個設備回調函數:

          poYBAGK9DJmAQ-FvAAAjUuLwMOc015.png

          硬件設備收到數據:

          /**
          參數 	描述
          dev 	設備句柄
          rx_ind 	回調函數指針
          返回 	——
          RT_EOK 	設置成功
           */
          rt_err_t
          rt_device_set_rx_indicate(rt_device_t dev,
                                    rt_err_t (*rx_ind)(rt_device_t dev, rt_size_t size))

          該函數的回調函數由調用者提供。當硬件設備接收到數據時,會回調這個函數并把收到的數據長度放在 size 參數中傳遞給上層應用。上層應用線程應在收到指示后,立刻從設備中讀取數據。

          硬件設備發送數據:

          在應用程序調用 rt_device_write() 寫入數據時,如果底層硬件能夠支持自動發送,那么上層應用可以設置一個回調函數。
          這個回調函數會在底層硬件數據發送完成后 (例如 DMA 傳送完成或 FIFO 已經寫入完畢產生完成中斷時) 調用。

          通過如下函數設置設備發送完成指示:

          /**
          參數 	描述
          dev 	設備句柄
          tx_done 	回調函數指針
          返回 	——
          RT_EOK 	設置成功
           */
          rt_err_t
          rt_device_set_tx_complete(rt_device_t dev,
                                    rt_err_t (*tx_done)(rt_device_t dev, void *buffer))

          調用這個函數時,回調函數由調用者提供,當硬件設備發送完數據時,由驅動程序回調這個函數并把發送完成的數據塊地址 buffer 作為參數傳遞給上層應用。上層應用(線程)在收到指示時會根據發送 buffer 的情況,釋放 buffer 內存塊或將其作為下一個寫數據的緩存。

          ?? 訪問 I/O 設備相關的函數,和 I/O 設備模型框架中 應用程序 有關,是我們上層寫應用程序直接調用的函數。

          三、新建 I/O 設備模型實例

          RT-Thread 驅動都是在 drivers 目錄下面:

          poYBAGK9DJmAYVBuAABCG9j0hGQ134.png

          我們在目錄下新建一個文件,作為驅動示例:

          pYYBAGK9DJmAbSWvAADKwnU6FFs295.png

          我們寫一個簡單的基本框架:

          1、創建一個設備;
             使用 rt_device_create 創建一個設備,需要定義一個 rt_device_t 接口體接收設備設備句柄。
          
          2、實現設備操作的函數:
             實現設備對象中對于 設備操作的init,open,close等 函數。
          
          3、注冊設備到 I/O 設備管理器;
             使用 rt_device_register 將設備注冊到設備管理器。

          drv_demo.c中,我們實現如下代碼:

          poYBAGK9DJmALQEkAABuTuaInAY314.png

          其次,我們需要實現一下設備操作的函數:

          pYYBAGK9DJqAQYcpAABPqLr1W74608.png

          最后,別忘了使用 INIT_BOARD_EXPORT 把設備初始化的代碼加入板級硬件初始化:

          poYBAGK9DJqABG66AAAffT8TlJ8363.png

          上一下設備模型實例代碼:

          #include 
          #include 
          
          rt_err_t  demo_init(rt_device_t dev)
          {
              rt_kprintf("demo_init ok!\n");
              return 0;
          }
          rt_err_t  demo_open(rt_device_t dev, rt_uint16_t oflag)
          {
              rt_kprintf("demo_open ok!\n");
              return 0;
          }
          rt_err_t  demo_cloes(rt_device_t dev)
          {
              rt_kprintf("demo_cloes ok!\n");
              return 0;
          }
          
          int rt_drvdemo_init(void){
          
              rt_device_t demo_dev = RT_NULL;
          
              demo_dev = rt_device_create(RT_Device_Class_Char, 0);
              if(demo_dev == RT_NULL){
                  LOG_E("demo device create failed...\n");
                  return -1;
              }
          
              demo_dev->init=demo_init;
              demo_dev->open=demo_open;
              demo_dev->close=demo_cloes;
          
              rt_device_register(demo_dev,"drvdemo",RT_DEVICE_FLAG_RDWR);
              return 0;
          }
          
          
          INIT_BOARD_EXPORT(rt_drvdemo_init);

          上面我們完成的是 設備驅動層的 代碼,接下來我們還需要簡單演示一下,如果在應用層 使用這個 demo 設備。

          我們根據上文所介紹的 訪問 I/O 設備 進行對應操作,這里直接上圖說明一下使用流程:

          pYYBAGK9DJqAJv7QAACs50bc4uU608.png

          看一下測試結果,我們實現的 3 個驅動函數都只有打印輸出,所以我們可以通過打印信息查看是否正確執行的驅動函數的內容:

          poYBAGK9DJqAR76DAACrGvu2Bvw047.png

          通過上面的測試,我們實現了一個簡單的設備驅動的設計,雖然demo比較簡單,但是經過這么一個過程可以讓我們更加的理解 RT-Thread I/O 設備模型的工作方式和流程。

          結語

          本文全面了解了 RT-Thread I/O 設備模型,說明了設備模型存在的意義,描述了一下設備模型相關的操作函數,最后使用了一個新建 I/O設備模型的例子,說明了 I/O 設備模型 的工作方式。

          在我們使用 RT-Thread 的時候,其實大部分常用的設備 RT-Thread 已經幫我們寫好了驅動,我們直接在應用層調用操作接口即可,接下來的系列文章我們將要學習 RT-Thread 常用的 I/O 設備模型。


          ?? 希望開頭的愿景能夠實現,通過本文讓所有人了解 RT-Thread I/O 設備模型 (* ̄︶ ̄) ??

          本文就到這里,謝謝大家!

          審核編輯:湯梓紅

          • 內核
            +關注

            關注

            3

            文章

            776

            瀏覽量

            36685
          • Linux
            +關注

            關注

            73

            文章

            7573

            瀏覽量

            194156
          • 模型
            +關注

            關注

            1

            文章

            1342

            瀏覽量

            44009
          • RT-Thread
            +關注

            關注

            27

            文章

            414

            瀏覽量

            33897
          收藏 人收藏

            評論

            相關推薦

            為什么Linux服務器需要文件壓縮

              本文提供了 Linux 文件壓縮至關重要的原因。這種技術在組織中起著至關重要的作用,尤其是那些處....
            的頭像 星星科技指導員 發表于 07-01 14:43 ? 45次 閱讀

            從深度到統信,從桌面到根社區 | Linux 中國

            導讀: 作為多年來一直關注開源技術發展的開源人,我約了統信的任紫東先生聊了聊,希望將從深度到統信,再到加入歐拉生態的背后...
            發表于 07-01 14:24 ? 739次 閱讀

            英飛凌加入RT-Thread開源共同體 為物聯網開發者提供系統級解決方案

            日前,全球半導體解決方案的領導者英飛凌科技(中國)有限公司(以下簡稱“英飛凌”)與知名物聯網操作系統....
            發表于 07-01 14:24 ? 86次 閱讀

            RT_Thread該怎么使用數學函數進行浮點運算呢

            最近要做運動控制器,使用了支持浮點運算的F407單片機。那么RT_Thread該怎么使用數學函數進行浮點運算呢? 第一步就是開啟單...
            發表于 07-01 14:13 ? 951次 閱讀

            Java代碼編寫技巧

            自從畢業后,今年已經是我工作的第 8 個年頭了,我甚至都快忘記了到底是哪年畢業的。
            的頭像 Android編程精選 發表于 07-01 12:47 ? 24次 閱讀

            RT-Thread是如何從內部Flash讀取WAV音頻播放呢

            開始實驗前,開發板 SDK 請選擇 1.0.7 之后的版本 最終的工程可以在這里下載 wav_player_rom.zip 使能相關組件 需要使用到...
            發表于 07-01 11:53 ? 1168次 閱讀

            RT-Thread Studio IDE使用的基礎介紹

            rt-thread studio 安裝 首先需要確保已經安裝 rt-thread studio 在工具欄找到 SDK 管理器,點擊后在彈出窗口,Board_Supp...
            發表于 07-01 11:41 ? 1104次 閱讀

            四種方式來讓您以簡單模式訪問遷移器

            比如,我們想要遷移一個本地集成庫,在Component元件面板里選擇該集成庫,然后點擊遷移庫(Mig....
            的頭像 DigiPCBA得極 發表于 07-01 11:25 ? 613次 閱讀

            RT-Thread記錄(十一、UART設備—源碼解析)

            一文帶你深入理解 RT-Thread I/O 設備模型 — UART 設備源碼分析。
            的頭像 矜辰所致 發表于 07-01 11:24 ? 765次 閱讀
            RT-Thread記錄(十一、UART設備—源碼解析)

            基于Art-Pi的NTP同步時鐘+DHT11獲取溫度的設計實現

            開發環境:RT-Thread Studio 開發板:Art-Pi OS版本:4.0.3 硬件 顯示屏:金逸晨GMG12864-03A 溫濕度:DHT1...
            發表于 07-01 11:24 ? 1162次 閱讀

            網絡TCP通信程序卡在while死循環中怎么去修復呢

            問題發生位置:drv_eth.c文件rt_stm32_eth_tx函數中(254行) 修復方法:stm32f4xx_hal_eth.h頭文件631行Lock成員變量定義為...
            發表于 07-01 11:12 ? 1206次 閱讀

            文本預訓練的模型架構及相關數據集

            多模態預訓練的數據通常來源于大規模的模態間對齊樣本對。由于時序維度的存在,視頻當中包含了比圖片更加豐....
            的頭像 深度學習自然語言處理 發表于 07-01 11:08 ? 177次 閱讀

            淺析在Windows系統中將RT-Thread移植到Zynq的步驟

            一、功能簡介 在window系統中將rtthread移植到zynq 在sdk中實現無bsp的zynq工程調試 在zynq中演示rtthread的shell功能 二、配...
            發表于 07-01 10:48 ? 1551次 閱讀

            RT Smart上RIL通信組件及應用的移植和開發工作簡述

            1、Linux RIL的概述與驅動 在移動網絡通信中,尤其是智能手機,平板等智能設備中,RIL是一個非常重要的組件,RIL使各...
            發表于 07-01 10:29 ? 2199次 閱讀

            將Android操作系統移植到嵌入式平臺的最佳實踐

              遵循上述嵌入式工程實踐,您可以確保在嵌入式平臺上高效成功地移植 Android,并增強現有連接設....
            的頭像 星星科技指導員 發表于 07-01 10:20 ? 117次 閱讀

            Linux Ril中使用共享內存交互相關資料分享

            1、移植RIL到ART-Smart之共享內存簡析 本次移植的linux ril中,rild作為一個client與modem通過AT命令交互,同時也作為...
            發表于 07-01 10:17 ? 2306次 閱讀

            MISRA C在安全和安全編程中的位置

              由于 C 仍將是 Linux 內核等大型程序的基礎語言,我們可以預見兩種趨勢的共存,以更好地防止....
            的頭像 星星科技指導員 發表于 07-01 10:07 ? 112次 閱讀
            MISRA C在安全和安全編程中的位置

            CH341驅動CH341PAR_LINUX.ZIP, 在ubuntu 16.04無法make成功怎么解決?

            從下載的Linux_USB2I2C驅動 ,  在ubuntu 16.04 無法 make 成功, 請問有更新版本么? ...
            發表于 07-01 07:01 ? 112次 閱讀

            大佬帶你理解RT-Thread內核并上手實踐

            內核是操作系統最重要的部分,學習RT-Thread也是從最基本的內核開始。 ? RT-Thread內....
            發表于 06-30 17:10 ? 149次 閱讀

            通過Uboot?TFTP啟動rt-smart內核

            介紹Windows下通過 Uboot??TFTP 方式下載和啟動rt-smart 內核
            的頭像 RT-thread 發表于 06-30 12:34 ? 1224次 閱讀
            通過Uboot?TFTP啟動rt-smart內核

            Windows和Linux操作系統的流式處理API

            在本文中,我們分析了 Windows 和 Linux 操作系統的流式處理 API;提出了基于事件的線....
            的頭像 星星科技指導員 發表于 06-30 10:52 ? 100次 閱讀
            Windows和Linux操作系統的流式處理API

            如何選擇嵌入式操作系統

              對于 SMP 系統,操作系統的選擇是按照本文迄今為止描述的方式進行的,另外一個因素是操作系統必須....
            的頭像 星星科技指導員 發表于 06-30 10:41 ? 132次 閱讀
            如何選擇嵌入式操作系統

            關于Windows和Linux操作系統中線程同步了解

            線程可以是可連接的(默認情況下)或分離的。當一個可連接線程終止時,信息(標識符、終止狀態、線程計數器....
            的頭像 星星科技指導員 發表于 06-30 10:31 ? 80次 閱讀
            關于Windows和Linux操作系統中線程同步了解

            ScarecrowApiDoc接口管理系統

            ./oschina_soft/gitee-scarecrowApiDoc.zip
            發表于 06-30 10:31 ? 8次 閱讀
            ScarecrowApiDoc接口管理系統

            如何判斷硬件是否支持嵌入式Linux

              如果該部分不受支持,則值得擁有一份最新的 Linux 內核源代碼以進行交叉引用。如果最近添加了支....
            的頭像 星星科技指導員 發表于 06-30 09:46 ? 46次 閱讀
            如何判斷硬件是否支持嵌入式Linux

            利用YOCTO的力量進行Linux操作系統移植項目

              隨時可用的 開發工具:作為 Yocto 用戶,您可以訪問各種開發工具,例如應用程序開發工具包 (....
            的頭像 星星科技指導員 發表于 06-30 09:05 ? 86次 閱讀
            利用YOCTO的力量進行Linux操作系統移植項目

            基于RT-Thread的麻雀一號無人值守門禁系統

            采用麻雀一號為主控設備來實現,攝像頭數據,人體紅外感應或門開關來判斷是否有人闖入機房。通過Node-....
            的頭像 極速紫韻 發表于 06-30 06:45 ? 1431次 閱讀
            基于RT-Thread的麻雀一號無人值守門禁系統

            基于RT-Thread設備運行數據分析預警系統

            本項目采用到硬件方案是:通過ART-Pi STM32H750主板上的I2C引腳和UART以及一個普通....
            的頭像 極速紫韻 發表于 06-30 06:22 ? 1340次 閱讀
            基于RT-Thread設備運行數據分析預警系統

            基于RT-Thread和AB32VG1開發板實現家庭安全檢測功能

            基于RT-Thread和中藍訊科開發板,實現按鍵觸發語音報警和NodeRed收集報警信息并上報騰訊云....
            的頭像 極速紫韻 發表于 06-30 00:36 ? 1224次 閱讀
            基于RT-Thread和AB32VG1開發板實現家庭安全檢測功能

            使用軟件查找硬件錯誤

              總之,您必須在生成掩碼之前運行軟件,以證明您的計算硬件是正確的。仿真是做到這一點的唯一現實方法,....
            的頭像 星星科技指導員 發表于 06-29 15:25 ? 120次 閱讀

            傳統嵌入式設備能力的新可能性

              開始使用框架。汽車開發商有 Autosar。工業開發人員可以從嵌入式 Linux 入手,作為理解....
            的頭像 星星科技指導員 發表于 06-29 15:16 ? 134次 閱讀

            cronshow PHP定時任務控制臺

            ./oschina_soft/cronshow.zip
            發表于 06-29 14:36 ? 6次 閱讀
            cronshow PHP定時任務控制臺

            嵌入式通信管理機的核心優勢和作用

            摘要:隨著物聯網技術的發展,各種應用及系統推陳出新,不斷更新換代,而通信管理機是系統的數據樞紐,在整....
            的頭像 panqin888 發表于 06-29 12:33 ? 58次 閱讀

            RK3566JD4 Linux_SDK源碼包

            采用RK3566四核64位處理器, 集成雙核心架構GPU以及高效能NPU; 支持PCIe2.1和SA....
            發表于 06-29 11:37 ? 8次 閱讀
            RK3566JD4 Linux_SDK源碼包

            RK3566JD4 linux-headers

            采用RK3566四核64位處理器, 集成雙核心架構GPU以及高效能NPU; 支持PCIe2.1和SA....
            發表于 06-29 11:30 ? 8次 閱讀
            RK3566JD4 linux-headers

            RK3568J Linux_Upgrade_Tool_v1.65

            采用Rockchip RK3588新一代旗艦級八核64位處理器,最大可配32GB大內存;支持8K視頻....
            發表于 06-29 11:22 ? 10次 閱讀
            RK3568J Linux_Upgrade_Tool_v1.65

            RK3566JD4 firefly linux repack工具

            采用RK3566四核64位處理器, 集成雙核心架構GPU以及高效能NPU; 支持PCIe2.1和SA....
            發表于 06-29 10:54 ? 5次 閱讀
            RK3566JD4 firefly linux repack工具

            RK3568J firefly-linux-repack

            采用Rockchip新一代64位處理器RK3568,集成雙核心架構GPU以及高效能NPU;最大支持8....
            發表于 06-29 10:46 ? 10次 閱讀
            RK3568J firefly-linux-repack

            RK3568J Linux_Upgrade_Tool_v1.59

            采用Rockchip新一代64位處理器RK3568,集成雙核心架構GPU以及高效能NPU;最大支持8....
            發表于 06-29 10:45 ? 8次 閱讀
            RK3568J Linux_Upgrade_Tool_v1.59

            RK3568J Linux_SDK 源碼包

            采用Rockchip新一代64位處理器RK3568,集成雙核心架構GPU以及高效能NPU;最大支持8....
            發表于 06-29 10:40 ? 8次 閱讀
            RK3568J Linux_SDK 源碼包

            STM32L051上使用RT-Thread (五、完結篇)

            應用篇-在STM32L051上使用RT-Thread 第五篇,也是本次應用的完結篇。
            的頭像 矜辰所致 發表于 06-29 10:34 ? 1522次 閱讀
            STM32L051上使用RT-Thread (五、完結篇)

            RK3568J linux headers

            采用Rockchip新一代64位處理器RK3568,集成雙核心架構GPU以及高效能NPU;最大支持8....
            發表于 06-29 10:29 ? 10次 閱讀
            RK3568J linux headers

            基于RTOS內核的滴答處理程序優先級設置

              RTOS 內核用戶在配置滴答優先級和頻率方面可能具有的靈活性肯定會給剛接觸內核的開發人員帶來一些....
            的頭像 星星科技指導員 發表于 06-29 09:12 ? 232次 閱讀
            基于RTOS內核的滴答處理程序優先級設置

            PT32x00x存儲器和總線構架說明

            n Cortex?-M0 內核系統總線(S-bus)
            的頭像 吳先生 發表于 06-29 09:07 ? 68次 閱讀
            PT32x00x存儲器和總線構架說明

            智能自助洗車機的硬件接口需求及解決方案

            說到“洗車”,以前人們最先想到的應該就是汽車美容店人工洗車和自動洗車。
            的頭像 敏敏子呦 發表于 06-29 08:55 ? 55次 閱讀

            通過mmap實現零拷貝技術

            我們知道,linux系統中用戶空間和內核空間是隔離的,用戶空間程序不能隨意的訪問內核空間數據,只能通....
            的頭像 Linux閱碼場 發表于 06-28 17:33 ? 215次 閱讀

            pwru的使用方法、經典場景及實現原理

            pwru 是 Cilium 推出的基于 eBPF 開發的網絡數據包排查工具,它提供了更細粒度的網絡數....
            的頭像 馬哥Linux運維 發表于 06-28 17:27 ? 179次 閱讀

            虛擬硬件平臺為開發人員帶來光明的未來

              虛擬硬件平臺為開發人員帶來了光明的未來,免除了他們等待硬件可用性的痛苦,并提供了硬件開發板無法提....
            的頭像 星星科技指導員 發表于 06-28 14:42 ? 139次 閱讀

            一點Flash在嵌入式設備中大有幫助

              許多嵌入式應用程序都能夠從 Flash 技術中受益。例如,集成遠程信息處理系統將車隊交互、GPS....
            的頭像 星星科技指導員 發表于 06-28 14:15 ? 250次 閱讀

            使用VMX設計的能量計實時測量系統

            作為額外的獎勵,當 Linux 被故意崩潰時,視頻會消失,但音樂會在安全模式下播放,不會出現任何可聽....
            的頭像 星星科技指導員 發表于 06-28 11:53 ? 128次 閱讀
            使用VMX設計的能量計實時測量系統

            簡化SBC的嵌入式Linux軟件開發

            即使桌面平臺可以保證從現在起大約五年后,Linux 內核和相關的發行版也是移動的目標。內核和標準庫在....
            的頭像 星星科技指導員 發表于 06-28 11:45 ? 187次 閱讀
            簡化SBC的嵌入式Linux軟件開發

            使用Eclipse Process Framework構建嵌入式軟件

              在設計醫療設備時,FDA QSR 規定的設計指南和法規可以與系統和軟件開發中的最佳實踐同時解決。....
            發表于 06-28 11:35 ? 75次 閱讀
            使用Eclipse Process Framework構建嵌入式軟件

            STM32L051上使用RT-Thread (四、串口通訊)

            應用篇-在STM32L051上使用RT-Thread 第四篇,巧妙的使用信號量處理串口通訊。
            的頭像 矜辰所致 發表于 06-28 10:59 ? 1517次 閱讀
            STM32L051上使用RT-Thread (四、串口通訊)

            Linux與Windows文件換行符的區別

            當一個文件在Windows和Linux上交替操作后,經常遇到一些莫名其妙的問題,如shell腳本無法....
            的頭像 一口Linux 發表于 06-27 15:18 ? 97次 閱讀

            TI的Sitara AM6442實時網絡處理器

              AM6442 的集成 Cortex-A53 內核為 Linux 應用程序提供了理想的計算特性,并....
            發表于 06-27 14:24 ? 302次 閱讀
            TI的Sitara AM6442實時網絡處理器

            基于ANSI C加密庫的RTCA DO-178C的DAL A支持

              鑒于與重新啟動航空電子系統相關的嚴格性能要求,wolfSSL 的服務組織隨時為希望跟上公司技術的....
            的頭像 星星科技指導員 發表于 06-27 14:09 ? 133次 閱讀

            嵌入式Linux上的以太網TSN簡介

            這些是您可能每天都在使用的各種基于 Linux 的嵌入式系統背后的關鍵構建塊,甚至可能不知道它們運行....
            的頭像 星星科技指導員 發表于 06-27 11:56 ? 188次 閱讀
            嵌入式Linux上的以太網TSN簡介

            AM4379 AM437x ARM Cortex-A9 微處理器 (MPU)

            TI AM437x高性能處理器基于ARM Cortex-A9內核。 這些處理器通過3D圖形加速得到增強,可實現豐富的圖形用戶界面,還配備了協處理器,用于進行確定性實時處理(包括EtherCAT,PROFIBUS,EnDat等工業通信協議)。該器件支持高級操作系統(HLOS)?;贚inux的® 可從TI免費獲取。其它HLOS可從TI的設計網絡和生態系統合作伙伴處獲取。 這些器件支持對采用較低性能ARM內核的系統升級,并提供更新外設,包括QSPI-NOR和LPDDR2等存儲器選項。 這些處理器包含功能方框圖中顯示的子系統,并且后跟相應的“說明”中添加了更多信息說明。 處理器子系統基于ARM Cortex-A9內核,PowerVR SGX™圖形加速器子系統提供3D圖形加速功能以支持顯示和高級用戶界面。 可編程實時單元子系統和工業通信子系統(PRU-ICSS與ARM內核分離,允許單獨操作和計時,以實現更高的效率和靈活性.PRU-ICSS支持更多外設接口和EtherCAT,PROFINET,EtherNet /IP,PROFIBUS,以太網Powerlink,Sercos,EnDat等...
            發表于 09-25 11:51 ? 646次 閱讀
            AM4379 AM437x ARM Cortex-A9 微處理器 (MPU)