<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 元件/連接器 > 設計應用 > HMC5883L驅動(dòng)及調試的總結

HMC5883L驅動(dòng)及調試的總結

作者: 時(shí)間:2017-10-27 來(lái)源:網(wǎng)絡(luò ) 收藏

  關(guān)于I2C

本文引用地址:http://dyxdggzs.com/article/201710/368938.htm

  因為手頭有幾個(gè),都需要用到I2C接口,所以在之前就將I2C子系統復習并深入研究了一番。以下我所提到的或貼出的部分代碼也許不適合真正的板級驅動(dòng),因為是以模塊化形式做測試的。

  在此模塊化驅動(dòng)中,不僅要注冊驅動(dòng)(i2c_driver),同時(shí)也要對設備信息進(jìn)行注冊(i2c_client),我認為在這里不分前后順序(就像“先有雞還是先有蛋”的問(wèn)題一樣沒(méi)有意義)。在前邊分析i2c子系統的時(shí)候提到過(guò),對于在i2c注冊后再添加的新的設備不能再用 i2c_register_board_info了,這會(huì )導致設備完全不能被激活,而需要用的是i2c_new_device才能將設備動(dòng)態(tài)的注冊到系統中

  在使用i2c_new_device時(shí)候不僅需要設備的i2c_board_info結構體,還需要其所依附的I2C總線(xiàn)號。首先,關(guān)于總線(xiàn)號,可以通過(guò)i2cdetect命令進(jìn)行查看:

  然后,在代碼中可以這樣使用:

  這樣就獲取了指定總線(xiàn)號的i2c_adapter指針,之后就可以利用這個(gè)指針給i2c_new_device用了。最后需要注意,在注冊完設備信息后,要使用i2c_put_adapter(adap)將指針釋放掉。

  用于描述硬件信息的結構體可以做為i2c_client的私有數據保存,而這個(gè)結構體中往往也要保存對應的client。這種互相的對應關(guān)系應該在probe接口函數中進(jìn)行:

  驅動(dòng)未寫(xiě),調試先行。如果在開(kāi)始著(zhù)手書(shū)寫(xiě)驅動(dòng)前就能直接的通過(guò)工具的簡(jiǎn)單應用對器件進(jìn)行調試查看的話(huà),會(huì )對驅動(dòng)的書(shū)寫(xiě)有很大的幫助。所以這里要說(shuō)一下關(guān)于I2C在shell中的幾個(gè)調試命令i2cdetect, i2cdump, i2cget, i2cset。首先是i2cdetect,一般用來(lái)探測和羅列總線(xiàn)(上邊就演示了一下),一般使用方法是:羅列總線(xiàn)-》探測有效設備

  查看效果如下:

  這里就可以看到,設備從地址為0x68和0x1e的設備有實(shí)際有效的硬件連接,分別是和AD0接地(不連)的MPU6050。0x54 55 56 57為EEPROM,設備忙。

  其次是i2cdump,用來(lái)查看器件內部寄存器值,用法為i2cdump -y 總線(xiàn)號 設備地址

  然后是i2cget和i2cset,分別是對寄存器進(jìn)行獲取和寫(xiě)入。用法為i2cget -y 總線(xiàn)號 設備地址 寄存器地址 模式和i2cset -y 總線(xiàn)號 設備地址 寄存器地址 數值 模式。模式默認為b(byte)即讀取8bit數據,i2cget可用模式有b/w/c,i2cset可用模式有b/w/c/i/s,其中w為 word(16bit),i和s分別為I2C和SMBUS的block數據。

  Mutex互斥鎖

  千萬(wàn)不要忘記初始化mutex互斥鎖。靜態(tài)初始化DEFINE_MUTEX(mutex_name),動(dòng)態(tài)初始化mutex_init(struct mutex *lock)。忘記初始化就使用的話(huà)是會(huì )直接造成內核報錯的。

  在中斷上下文中不要使用mutex互斥鎖,因為如果出現了競態(tài),mutex有可能進(jìn)入睡眠,而中斷上下文中是絕對不允許睡眠的。所以千萬(wàn)不要使用,如果一定要在中斷中使用鎖機制來(lái)保護一些驅動(dòng)資源,建議使用spinlock自旋鎖(semaphore信號量也不允許使用,同樣的原因)。

  關(guān)注死鎖。哪個(gè)操作需要進(jìn)行鎖一定要事先自行規劃好,不要在某操作一進(jìn)入的時(shí)候鎖,而進(jìn)入其子步驟后又鎖,這樣就直接死鎖了,系統freeze掉。

  關(guān)于中斷

  中斷的使用很簡(jiǎn)單,但是卻有很多值得注意的細節點(diǎn)。

  GPIO中斷。如一些開(kāi)發(fā)板上,外部擴展出來(lái)很多GPIO口,但是卻找不到IRQ口,所以就需要將GPIO擴展為中斷線(xiàn)。在代碼中,使用gpio_to_irq(gpio_nr)函數(linux/gpio.h)就可以得到自動(dòng)轉換后的中斷線(xiàn)號了,可以用來(lái)請求中斷。

  若在request_irq的時(shí)候最后給的參數不為NULL,那么在free_irq的時(shí)候,第二個(gè)參數也就必須與其一致,否則會(huì )使系統找不到要釋放哪個(gè)中斷的處理程序句柄(當然了,為NULL就都為NULL,這個(gè)沒(méi)有問(wèn)題,只要一致就可以)。

  工作隊列

  工作隊列分work_struct 和delayed_work。區別就是delayed_work會(huì )在指定的延遲后開(kāi)始運行,而work_struct會(huì )立即被調度運行。

  初始化。INIT_WORK(struct work_struct *work, void (*work_func)(struct work_struct *work))動(dòng)態(tài)初始化work_struct。INIT_DELAYED_WORK(struct delayed_work *work, void (*work_func)(struct work_struct *work))動(dòng)態(tài)初始化delayed_work,在delayed_work的work_func工作函數中,可以通過(guò)強制轉換將*work轉換為 struct delayed_work類(lèi)型。

  調度。work_struct的調度為schedule_work(struct work_struct *work),而delayed_work則需要另外一個(gè)延遲參數schedule_delayed_work(struct delayed_work *work, unsigned long delay),這里的delay參數就是延遲多久后投入工作,單位是jiffies,常會(huì )用到類(lèi)如msecs_to_jiffies(msecs)等轉換函數。

  如果未對工作函數指定隊列,那么其會(huì )自動(dòng)進(jìn)入system_wq中,在驅動(dòng)中也常會(huì )用到定義自己的工作隊列,但是簡(jiǎn)單工作往往沒(méi)有需要這樣做。

  對于頻繁上報信息的工作,最好定義自己的工作隊列,將此工作放入自己的工作隊列中運行,而不是放入系統默認的system_wq中,這樣會(huì )避免在系統忙的時(shí)候自己的工作被很快調度走,有自己的工作隊列在這方面能夠起到很大的作用。

  completion同步

  因為在調試過(guò)程中嘗試了自檢,而又涉及到中斷,所以采用了completion作為同步機制,這里提出簡(jiǎn)單用法。

  初始化。init_completion(struct completion *wait)

  等待。wait_for_completion_timeout(struct completion *wait, unsigned long timeout),返回值為剩余時(shí)間,如果剩余時(shí)間為0,也就是說(shuō)明超時(shí)了。

  喚醒。complete(struct completion *wait)



關(guān)鍵詞: HMC5883L 傳感器 適配器

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>