Linux GPIO驅動分析
<p> </p><pre name="code" class="html"><pre name="code" class="html">#include<linux/string.h> #include<linux/list.h> #include<linux/pci.h> #include<asm/uaccess.h> #include<asm/atomic.h> #include<asm/unistd.h> #include<mach/map.h> #include<mach/regs-clock.h> #include<mach/regs-gpio.h> #include<plat/gpio-cfg.h> #include<mach/gpio-bank-e.h> #include<mach/gpio-bank-k.h> #include"s3c6410_gpio.h" #defineDEVICE_NAME"leds" staticlongsbc2440_leds_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg) { switch(cmd){ unsignedtmp; case0: case1: if(arg>4){ return-EINVAL; } tmp=readl(S3C64XX_GPKDAT); tmp&=~(1<<(4+arg));//把暫存器的該位清零 tmp|=((!cmd)<<(4+arg));//將暫存器的該位復位或者置位,取決於cmd writel(tmp,S3C64XX_GPKDAT);//將tmp寫入暫存器 //printk(DEVICE_NAME":%d%d\n",arg,cmd); return0; default: return-EINVAL; } } //該結構體中成員函式是字元裝置驅動與核心的介面 staticstructfile_operationsdev_fops={ .owner =THIS_MODULE, .unlocked_ioctl =sbc2440_leds_ioctl, }; //misdevice:雜項裝置,即主裝置號為10的特殊字元裝置。 staticstructmiscdevicemisc={ //MISC_DYNAMIC_MINOR來動態獲取次裝置號。 .minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME, .fops=&dev_fops, }; staticint__initdev_init(void) { intret; { unsignedtmp; tmp=readl(S3C64XX_GPKCON); //GPKCON配置GPK4到GPK7配置為0001輸出模式。 tmp=(tmp&~(0xffffU<<16))|(0x1111U<<16); writel(tmp,S3C64XX_GPKCON); //燈滅 tmp=readl(S3C64XX_GPKDAT); tmp|=(0xF<<4); writel(tmp,S3C64XX_GPKDAT); } //註冊裝置 //該函式會自動建立裝置節點,即裝置檔案。 ret=misc_register(&misc); printk(DEVICE_NAME"\tinitialized\n"); returnret; } staticvoid__exitdev_exit(void) { misc_deregister(&misc); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("FriendlyARMInc.");
該程式中與硬體的關聯性檔案是s3c6410_gpio.h,包含的方式是#include"s3c6410_gpio.h"
"#include<stdlib.h>”用於標準庫檔案或系統提供的標頭檔案,到儲存系統標準標頭檔案的位置查詢標頭檔案。
而"#include"userdefined.h"用於使用者自定義的標頭檔案,先從當前目錄查詢是否有指定名稱的標頭檔案,若當前目錄未找到該標頭檔案,再從標準檔案目錄中查詢。這兩種方式有他們的本質區別。
採用第二種包含方式,直接在當前工程目錄下找到了該檔案,內容如下:
/******************************************Copyright(c)************************************************ ** 檔名稱: s3c6410_gpio.h ** 作 者: tandesir ** 版 本: v1.0 ** 說 明: s3c6410 gpio操作 ** 修改記錄: 2011-9-27建立 ** 最後修改時間: 2011-10-5 ******************************************************************************************************/ #ifndef __S3C6410_GPIO_H__ #define __S3C6410_GPIO_H__ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/gpio.h> #include <linux/io.h> #include <mach/hardware.h> #include <mach/map.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank-n.h> #include <mach/regs-clock.h> #include <asm/irq.h> #include <plat/gpio-core.h> #include <plat/gpio-cfg.h> void s3c6410_gpio_cfgpin(unsigned int pin, unsigned int function) { //s3c_gpio_cfgpin(pin,function); unsigned int tmp; tmp = readl(S3C64XX_GPNCON); tmp = (tmp & ~(3<<pin*2))|(function<<pin*2); writel(tmp, S3C64XX_GPNCON); } void s3c6410_gpio_pullup(unsigned int pin, unsigned int to) { //s3c_gpio_setpull(pin,to); unsigned int tmp; tmp = readl(S3C64XX_GPNPUD); tmp = (tmp & ~(3<<pin*2))|(to<<pin*2); writel(tmp, S3C64XX_GPNPUD); } unsigned int s3c6410_gpio_getpin(unsigned int pin) { unsigned int tmp; tmp = readl(S3C64XX_GPNDAT); tmp = tmp & (1 << (pin)); return tmp; } void s3c6410_gpio_setpin(unsigned int pin, unsigned int dat) { unsigned int tmp; tmp = readl(S3C64XX_GPNDAT); tmp &= ~(1 << (pin)); tmp |= ( (dat) << (pin) ); writel(tmp, S3C64XX_GPNDAT); ; } #endif
這與在微控制器程式設計中所見到的標頭檔案不相同,裡面的內容是一些函式的實現方法。
但是在C檔案中並沒有用到這些函式。C檔案與該標頭檔案都是直接對暫存器進行操作。
所以關鍵的地方便是暫存器與地址的對映在什麼地方?可疑的標頭檔案是:
#include<mach/map.h>
#include<mach/regs-clock.h>
#include<mach/regs-gpio.h>
#include<plat/gpio-cfg.h>
#include<mach/gpio-bank-e.h>
#include<mach/gpio-bank-k.h>
這幾個檔案到底在什麼地方?
這就是在寫驅動檔案之前為什麼要編譯核心的原因了!在編譯核心的時候,會配置核心的環境,比如用的主晶片的型號,在裡面便會指定編譯驅動時所需要用到的檔案的路徑,比如該晶片的型號是S3c6410,那麼便會在原始碼樹的/linux-2.6.38/arch/arm/
mach-s3c64xx尋找相應檔案。所以以上標頭檔案的位置在/linux-2.6.38/arch/arm/
mach-s3c64xx中。
Map.h中定義了各種暫存器的對映
在regs-gpio.h檔案中
定義了一些基地址
在gpio-bank-n.h檔案中定義了程式中用到的一些暫存器
在mach檔案中,看到了很多類似的檔案:
這應該就是晶片的多組IO口,當使用哪一組IO便呼叫哪一個檔案。
相關推薦
Linux GPIO驅動分析
<p> </p><pre name="code" class="html"><pre name="code" class="html">#include<linux/string.h> #include<li
Linux 8250驅動分析
com for 目前 lin .html www. http ibm mat 1. 介紹 8250是IBM PC及兼容機使用的一種串口芯片; 16550是一種帶先進先出(FIFO)功能的8250系列串口芯片; 16550A則是16550的升級版本, 修復了FIFO相關BUG
S3C2440 linux LCD驅動分析
環境: 硬體平臺 TQ2440 東華3.5 inch TFT LCD
Linux I2C驅動分析與實現--例子
通過上篇《Linux I2C驅動分析與實現(二)》,我們對Linux子系統已經不陌生,那麼如何實現I2C驅動呢? 編寫客戶驅動的方法 在核心中有兩種方式的i2c客戶驅動的編寫方法,一種叫legacy傳統方式,另一種是newstyle方式. 前 一種legacy是一種舊式的方法,在2.
LInux裝置驅動分析—— kmalloc和kzalloc函式
今晚在研究EVM5728開發板上面Linux系統的IIC裝置驅動程式,偶然之間看到驅動程式中有一處使用了kzalloc函式,本人之前都是使用Linux核心提供的kmalloc / kfree函式來給裝置相關結構體分配 / 釋放記憶體的,第一次看到kzall
轉:linux GPIO驅動
Linux 下驅動GPIO 其實不用自己寫,最近專案要用到開發板上的GPIO,搜尋了一番,發現linux 下實現GPIO 驅動實在是太方便了,有現成的framework 可用,基本上要做的事情就是定義一下 Linux 下通過框架實現LED 大致過程如下 1、實現框架要求的幾個
Linux spi驅動分析(一)----匯流排驅動
一、SPI匯流排驅動介紹 SPI匯流排總共需要四根線,包括MOSI、MISO、CLK和CS。本文首先從SPI設備註冊開始來講述SPI匯流排驅動。 二、設備註冊 在系統啟動的時候,會按照順序執行一些初始化程式,比如device_initcall和module_i
Linux spi驅動分析(三)----spiddev分析
static longspidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){ int err = 0; int retval = 0; struct spid
Linux spi驅動分析(二)----SPI核心(bus、device_driver和device)
struct device { struct device *parent; struct device_private *p; struct kobject kobj; const char *init_name; /* init
Linux uvc驅動分析
本文基於AM6C平臺Linux3.0.8核心。 一、ioctl呼叫流程 1.common/drivers/media/video/uvc/uvc_driver.c module_init(uvc_init); static int __init uvc_init(voi
Linux裝置驅動分析之熱拔插
/*輔助函式uevent_helper(/sbin/mdev,mdev是busybox的傑作)用於對熱拔插裝置進行建立及刪除 */if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {char *a
linux通用GPIO驅動
決定 輸入輸出 gpio 發現 文件導出 寫入 echo direction linux開發 Linux開發平臺實現了通用GPIO的驅動,用戶通過,SHell或者系統調用能控制GPIO的輸出和讀取其輸入值。其屬性文件均在/sys/class/gpio/目錄下,該目錄下有ex
19.Linux-USB總線驅動分析
kmalloc 開發 硬件 ctrl 地址 allow end 處理 interface 如下圖所示,以windows為例,我們插上一個沒有USB設備驅動的USB,就會提示你安裝驅動程序 為什麽一插上就有會提示信息? 是因為windows自帶了USB總線驅動程序
linux音頻alsa-uda134x驅動分析之二(時鐘)
lin pen play 個數 inter and 文本 ted word Audio Clocking音頻時鐘==============This text describes the audio clocking terms in ASoC and digital au
Linux核心啟動過程分析(十)-----RTC驅動分析
參考https://blog.csdn.net/xuao20060793/article/details/46433263這篇博文 RTC驅動分析: Class.c (drivers\rtc):subsys_initcall(rtc_init); static int __init
04-Linux裝置樹系列-GPIO驅動實踐
1. 前言 GPIO驅動開發可能算是Linux核心裝置驅動開發中最為簡單、最常見的一個方向,對於開發板的按鍵、LED、蜂鳴器、電源控制等模組,可能都是使用GPIO實現的。Linux核心的GPIO子系統在核心不斷的演進過程中進行了多次的重構,本文的第二
Linux SD/MMC/SDIO驅動分析
一、SD/MMC/SDIO概念區分 SD(SecureDigital)與 MMC(MultimediaCard) SD 是一種 flash memory card 的標準,也就是一般常見的 SD 記憶卡,而 MMC 則是較早的一種記憶卡標準,目前已經被 SD 標準所取代。
10. LCD驅動程式 ——框架分析 第017課 LCD原理詳解及裸機程式分析 15.linux-LCD層次分析(詳解)
引言: 由LCD的硬體原理及操作(可參看韋哥部落格:第017課 LCD原理詳解及裸機程式分析) 我們知道只要LCD控制器的相關暫存器正確配置好,就可以在LCD面板上顯示framebuffer中的內容。 若應用程式需要在LCD螢幕上顯示文字或影象時,只需要把相應的顯示內容以正確的格式寫到Framebuff
Linux--核心---I2C匯流排驅動分析 以linux3.10.0 RK3288為例
Linux 3.10.0 iic匯流排註冊過程 I2C匯流排驅動包括I2C介面卡驅動載入與解除安裝以及I2C匯流排通訊方法 I2C核心提供了i2c_adapter的增加和刪除函式、i2c_driver的增加和刪除函式、i2c_client的依附和脫離函式 以及i2c傳輸、傳送
Linux裝置驅動程式架構分析之一個I2C驅動例項
作者:劉昊昱 核心版本:3.10.1 編寫一個I2C裝置驅動程式的工作可分為兩部分,一是定義和註冊I2C裝置,即i2c_client;二是定義和註冊I2C裝置驅動,即i2c_driver。下面我們就以mini2440的I2C裝置at24c08 EEPROM為例,介紹如