Nuttx學習筆記之板級裝置驅動初始化
工具:FRDM-KL25Z開發板
問題:在除錯PWM驅動的過程中一直無法找到裝置節點。
1、查詢pwm註冊pwm_register的地方。
->board_app_initialize()
->kl_pwm_setup()
->pwm_register()
2、發現board_app_initialize在這裡被呼叫:
該函式從字面來理解就是板級初始化的意思,但依賴於配置BOARD_INITIALIZE,在make menuconfig中找到該配置所在位置:#ifdef CONFIG_BOARD_INITIALIZE void board_initialize(void) { /* Perform NSH initialization here instead of from the NSH. This * alternative NSH initialization is necessary when NSH is ran in user-space * but the initialization function must run in kernel space. */ #if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_LIB_BOARDCTL) (void)board_app_initialize(0); #endif /* CC3000 wireless initialization */ #ifdef CONFIG_WL_CC3000 wireless_archinitialize(0); #endif } #endif
很明顯,在這裡分析了三種裝置驅動初始化的情況。│ CONFIG_BOARD_INITIALIZE: │ │ │ │ By default, there are three points in time where you can insert │ │ custom initialization logic: │ │ │ │ 1) <arch>_boardinitialize(): This function is used only for │ │ initialization of very low-level things like configuration of │ │ GPIO pins, power setting. The OS has not been initialized │ │ at this point, so you cannot allocate memory or initialize │ │ device drivers at this phase. │ │ │ │ 2) The next level of initialization is performed by a call to │ │ up_initialize() (in arch/<arch>/src/common/up_initialize.c). │ │ The OS has been initialized at this point and it is okay to │ │ initialize drivers in this phase. │ │ │ │ 3) And, finally, when the user application code starts. │ │ │ │ If BOARD_INITIALIZE is selected, then an additional initialization │ │ call will be performed in the boot-up sequence to a function │ │ called board_initialize(). board_initialize() will be │ │ call between phases 2) and 3) above, immediately after │ │ up_initialize() is called. This additional initialization │ │ phase may be used, for example, to initialize board-specific │ │ device drivers. │ │ │ │ Symbol: BOARD_INITIALIZE [=n] │ │ Type : boolean │ │ Prompt: Custom board/driver initialization │ │ Location: │ │ -> RTOS Features │ │ -> RTOS hooks │ │ Defined at sched/Kconfig:970
第一種情況是呼叫<arch>_boardinitialize(),這個函式只能進行一些低階的初始化,因為系統還沒有完全完成初始化,無法分配記憶體來完成裝置初始化。
第二種情況是呼叫up_initialize(),在這個時間節點,系統已經完成了初始化,可以進行裝置驅動的初始化。
第三種情況是在使用者應用程式中進行。
從以上的分析可以看出,很明顯在第二個階段和第三個階段中間是最適合進行板級裝置初始化的。而board_initialize()剛好就是用來完成這個任務的。
但是
board_app_initialize
依賴於
其中NSH是命令列庫,不能使用BOARDCTL介面。CONFIG_NSH_LIBRARY !CONFIG_LIB_BOARDCTL
後來發現,之所以有這樣的限制,是因為BOARDCTL介面有同樣的功能。
3、BOARDCTL介面實現初始化
void nsh_initialize(void)
{
#if defined(CONFIG_NSH_READLINE) && defined(CONFIG_READLINE_TABCOMPLETION)
/* Configure the NSH prompt */
(void)readline_prompt(g_nshprompt);
#ifdef CONFIG_READLINE_HAVE_EXTMATCH
/* Set up for tab completion on NSH commands */
(void)readline_extmatch(&g_nsh_extmatch);
#endif
#endif
/* Mount the /etc filesystem */
(void)nsh_romfsetc();
#ifdef CONFIG_NSH_ARCHINIT
/* Perform architecture-specific initialization (if configured) */
(void)boardctl(BOARDIOC_INIT, 0);
#endif
/* Bring up the network */
(void)nsh_netinit();
}
boardctl函式在這裡:
int boardctl(unsigned int cmd, uintptr_t arg)
{
int ret;
switch (cmd)
{
/* CMD: BOARDIOC_INIT
* DESCRIPTION: Perform one-time application initialization.
* ARG: The boardctl() argument is passed to the
* board_app_initialize() implementation without modification.
* The argument has no meaning to NuttX; the meaning of the
* argument is a contract between the board-specific
* initalization logic and the matching application logic.
* The value cold be such things as a mode enumeration value,
* a set of DIP switch switch settings, a pointer to
* configuration data read from a file or serial FLASH, or
* whatever you would like to do with it. Every
* implementation should accept zero/NULL as a default
* configuration.
* CONFIGURATION: CONFIG_LIB_BOARDCTL
* DEPENDENCIES: Board logic must provide board_app_initialization
*/
case BOARDIOC_INIT:
{
ret = board_app_initialize(arg);
}
break;
... ...
}
通過boardctl介面可以在使用者應用程式中對裝置驅動進行初始化。
這兩種方式裝置驅動初始化有什麼區別呢?暫時還沒有了解到。
相關推薦
Nuttx學習筆記之板級裝置驅動初始化
工具:FRDM-KL25Z開發板 問題:在除錯PWM驅動的過程中一直無法找到裝置節點。 1、查詢pwm註冊pwm_register的地方。 ->board_app_initialize() ->kl_pwm_setup() ->pwm_r
Junit學習筆記之三:測試驅動開發
1.正常的開發流程 編碼--->測試--->重複--->提交 基於測試驅動的開發 測試--->編碼--->重複--->提交 先寫了測試之後,由於測試的覆蓋率要求為100%,所以就會讓程式碼中可能存在的分支都進行測試,這樣先寫測試單元,可以
Zynq-Linux移植學習筆記之八-linux網路驅動
這一篇詳細介紹一下zynq下linux核心中網路驅動的執行過程。 1、基本層次 在linux中,網路可以分為下面三個層次: Linux網路驅動涉及到後面兩層,網路協議層中需要了解skb和netif;硬體驅動層也就是mac層,需要了解dma和dec。 按內容來說,整個網路
嵌入式Linux學習筆記(三) 字元型裝置驅動--LED的驅動開發
在成功構建了一個能夠執行在開發板平臺的系統後,下一步就要正式開始應用的開發(這裡前提是有一定的C語言基礎,對ARM體系的軟/硬體,這部分有疑問可能要參考其它教程),根據需求仔細分解任務,可以發現包含的外設有LED,BEEP,RS232,六軸感測(SPI介面),光環境感測器(I2C),音訊輸出, RTC等,
Vue.js 學習筆記之二:資料驅動開發
在 Vue.js 框架中,與 HTML 頁面元素的互動方式沒有像原生 JavaScript 介面那麼直接,它是通過先在 HTML 元素標籤中嵌入一系列類似於普通標籤屬性的 Vue 指令屬性來繫結資料,然後再通過在 JavaScript 程式碼中修改這些被繫結的資料來修改頁面元素的顯示方式與內容。在程式設計方法
linux:核心如何定位並呼叫裝置驅動初始化函式
寫過linux驅動程式的人都知道需要將驅動的初始化函式通過module_init註冊,然後在通過menuconfig配置的時候選擇隨核心一起編譯(非模組),系統在啟動的時候就能夠自動呼叫驅動初始化函數了。真是一件神奇的事情! #include <linu
[C++ primer學習筆記] 3.2.1 定義和初始化string物件
類可以定義多種初始化物件的方式:或初始值的數量不同; 或初始值的型別不同。初始化的不同方式:拷貝初始化:使用等號(=)初始化變數,實際上執行的是拷貝初始化,編譯器把等號右側的初始值拷貝到新建立的物件中去直接初始化:不使用等號,則執行的是直接初始化當初始值只有一個時,使用直接/
菜鳥stm32學習筆記(1)系統時鐘初始化函式
系統初始化函式步驟: 1:復位並配置暫存器向量表。 2:置位CR第十六位,開啟外部振盪器。 3:檢測CR第十七位,判斷外部振盪器是否準備就緒。若就緒,硬體會置位十七位。 *2和3設定的均是時鐘控制暫存器。 4:設定時鐘配置暫存器CFGR的8-10位為100使得APB1的時鐘
at91sam9260ek的板級、irq初始化-小試牛刀
話不多說,先上程式碼。 //code path:arch/arm/mach-at91/board-sam9260ek.cMACHINE_START(AT91SAM9260EK, "Atmel AT91
c++學習筆記 vptr指標的分佈和初始化
{public: Child(int a = 0, int b = 0) { this->b = b; } virtual void print() { cout << "我是兒子" << endl; }protected:private: int b;};void play
tensorflow學習筆記--三(Variables: 建立,初始化,儲存,和恢復)
tensorflow學習筆記--三 Variables: 建立,初始化,儲存,和恢復 TensorFlow Variables 是記憶體中的容納 tensor 的快取。這一小節介紹了用它們在模型訓練時(during training)建立、儲存和更新模型引數(model
ARM學習筆記之驅動程式篇七----字元裝置驅動
1.11 字元裝置驅動模型 在任何一種驅動模型中,裝置都會用核心中的一種結構來描述。字元裝置在核心中使用struct cdev來描述。 struct cdev{ struct kobject kobj; struct module *owner; const stru
韋東山嵌入式Linux學習筆記之——第12課第8節 字元裝置驅動程式之定時器防抖動
注:本文部分內容摘自《魚樹學員筆記》。 當按鍵按得比較快的時候,這裡出現了兩次中斷值,也即產生了抖動。 這裡產生了“抖動”,按鍵是機械開關,按下鬆開時裡面的金屬彈片可能抖動了好幾次。這種抖動產生了多次“脈衝”導致多次中斷。 方法: 使用定時器來防抖動。
【迅為iTop4412學習筆記】關於註冊裝置、註冊驅動、生成裝置節點小結
宣告 以下都是我剛開始看驅動視訊的個人強行解讀,如果有誤請指出,共同進步。 本節目標 瞭解註冊裝置、註冊驅動、生成裝置節點這些概念。 其實學到現在,很多東西我們都似懂非懂,而我也是剛學,也感覺很多東西似是而非,但好在程式碼過程和結果都是對
Zynq-Linux移植學習筆記之31-使用者自定義I2C驅動
1、背景介紹 板子上通過ZYNQ的I2C-0控制器連線了三片DBF晶片和一片Ti的226測功耗晶片,示意圖如下: 如上圖所示,三塊DBF晶片的I2C地址分別為2,4,8,Ti 226晶片的I2C地址為0x40.現在需要ZYNQ通過I2C匯流排讀寫這四塊晶片的暫存器數值
Airtest學習筆記之裝置管理
> 通過本篇你講了解到Airtest是如何跟安卓裝置互動的,以及多裝置時的多機互動使用。 在之前從Touch介面分析Airtest的影象識別中,在影象識別獲取到目標位置以後,發起點選的操作是通過以下這句: `G.DEVICE.touch(pos, **kwargs)
程式碼大全學習筆記之表驅動法
資料壓倒一切。如果選擇了正確的資料結構並把一切組織的井井有條,正確的演算法就不言自明。程式設計的核心是資料結構,而不是演算法。 ——Rob Pike 說明 本文基於這樣的認識:資料是易變的,邏輯是穩定的。 本文例舉的程式設計實現多為程式碼片段,但不
Zynq-Linux移植學習筆記之14-RapidIO驅動開發
在對zynq進行linux驅動開發時,除了需要針對zynq內ARM自帶的控制器適配驅動外,還需要對zynq PL部分的IP核進行驅動開發。對於ARM來說,zynq PL部分的IP核就是一段地址空間,這段地址空間包含了該IP的一系列暫存器,ARM操作該IP核的暫存器也就是
Zynq-Linux移植學習筆記之13-i2c驅動配置
1、 背景介紹 板子上通過I2C匯流排與zynq相連的是三片1848 如上圖所示,zynq通過I2C匯流排與3片CPS-1848交換晶片相連,3片1848晶片的I2C地址分別為2,4,8. 目前zynq上linux I2C驅動採用的是i2c-cadence(driver