上篇講了下led的原理,這篇就開始寫**:
如果是新手我建議先把《linux裝置驅動開發詳解》的裝置驅動那章看下或者網上了解下裝置驅動的模版,不然驅動的整體結構不懂的話就比較糾結了。
#include /* 所有核心模組必須有的標頭檔案 */
#include /* 所有 核心模組必須有的標頭檔案*/
#include /* printk() */
#include /* struct fops */
#include /* error codes */
#include /* cdev_alloc() */
#include /* ioremap() */
#include /* request_mem_region() */
#include /*用於產生 ioctl command */
#ifndef __kernel__
#include /* user space head file for macro _io() to generate ioctl command */
#endif
#define drv_author "yangxu"
#define drv_desc "s3c24xx led driver"
#define dev_name "led"
#define led_num 4
#ifndef led_major
#define led_major
0 /*主裝置號*/
#endif
#define drv_major_ver 1
#define drv_minor_ver 0
#define drv_rever_ver 0
#define disable 0
#define enable 1
#define gpio_input 0x00
#define gpio_output 0x01
#define platdrv_magic 0x60
#define led_off _io (platdrv_magic, 0x18)/*定義的魔數,防止和其他巨集重複,有興趣可以研究下*/
#define led_on _io (platdrv_magic, 0x19)
#define s3c_gpb_base 0x56000010
#define gpbcon_offset 0
#define gpbdat_offset 4
#define gpbup_offset 8
#define s3c_gpb_len 0x10 /* 0x56000010~0x56000020 */
int led[led_num] = ; /* four leds use gpb5,gpb6,gpb8,gpb10 我的板子是這些埠,你們的如果不一樣自己查開發板的底板原理圖*/
static void __iomem *s3c_gpb_membase;/*__iomem是linux2.6.9核心中加入的特性。是用來個表示指標是指向乙個i/o的記憶體空間。主要是為了驅動程式的通用性考慮。由於不同的cpu體系結構對i/o空間的表示可能不同。當使用__iomem時,編譯器會忽略對變數的檢查(因為用的是void __iomem)。若要對它進行檢查,當__iomem的指標和正常的指標混用時,就會發出一些警告。*/
#define s3c_gpio_write(val, reg) __raw_writel((val), (reg)+s3c_gpb_membase) /*對i/o的寫操作*/
#define s3c_gpio_read(reg) __raw_readl((reg)+s3c_gpb_membase) /*對i/o的讀操作*/
int dev_count = array_size(led); /*巨集array_size,用來求裝置結構體中裝置的個數*/
int dev_major = led_major;
int dev_minor = 0;
int debug = disable;
static struct cdev *led_cdev; /*cdev結構體可以用來描述乙個字元裝置*/
static int s3c_hw_init(void)/*記憶體和gpio初始化函式供後來的led裝置新增函式的呼叫*/
if( !(s3c_gpb_membase=ioremap(s3c_gpb_base, s3c_gpb_len)) )
/*用來將i/o記憶體資源的物理位址對映到cpu核心虛位址空間,因為cpu並不能直接使用硬體指定的實體地址直接訪問i/o。*/
for(i=0; i
/* 設定gpbcon埠為輸入或輸出模式 */
gpb_con = s3c_gpio_read(gpbcon_offset);
/*讀取gpbcon暫存器的各個位的狀態*/
gpb_con &= ~(0x3<<(2*led[i]));
/* 清零要修改的位*/
gpb_con |= gpio_output<<(2*led[i]);
/* 設定gpio為output模式 */
s3c_gpio_write(gpb_con, gpbcon_offset);
/*寫入暫存器*/
/ * gpbup暫存器設定,這裡用不到上拉電阻,所以我們禁用*/
gpb_up = s3c_gpio_read(gpbup_offset);
//gpb_up &= ~(0x1<
/* 設定gpio口的電平,來控制燈的亮滅,開始讓它滅*/
gpb_dat = s3c_gpio_read(gpbdat_offset);
//gpb_dat &= ~(0x1<
/*改變燈狀態的函式*/
static void turn_led(int which, unsigned int cmd)
static int led_release(struct inode *inode, struct file *file)/*如果在應用程式空間呼叫close函式,就會呼叫led_release,關閉節點*/
static void print_help(void)
/*沒什麼用列印一些資訊*/
static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return 0;
}static struct file_operations led_fops =;
static int __init s3c_led_init(void) /*led裝置的新增函式*/
if (0 != dev_major) /* 如果我們開始設定了主裝置號這裡就可以靜態使用了 */
else
/* 分配失敗 */
if (result < 0)
led_cdev->owner = this_module;
cdev_init(led_cdev, &led_fops); /*cdev_init()函式用於初始化cdev的成員,並建立cdev和file_operations之間的連線*/
result = cdev_add(led_cdev, devno, dev_count);/*向系統新增乙個cdev完成字元裝置的註冊*/
if (0 != result)
printk(kern_err "s3c %s driver[major=%d] version %d.%d.%d installed successfully!\n",
dev_name, dev_major, drv_major_ver, drv_minor_ver,drv_rever_ver);
return 0;
error:
printk(kern_err "s3c %s driver installed failure.\n", dev_name);
cdev_del(led_cdev);
unregister_chrdev_region(devno, dev_count);
return result;}
static void __exit s3c_led_exit(void) /*led裝置的解除安裝函式*/
/* these two functions defined in */
module_init(s3c_led_init);
module_exit(s3c_led_exit);
module_param(debug, int, s_irugo);
module_param(dev_major, int, s_irugo);
module_author(drv_author);
module_description(drv_desc);
module_license("gpl");
linux驅動之 led驅動
練手,第乙個字元驅動.用模組載入方法 華清遠見 嵌入式linux裝置驅動開發詳解 的 拿來改的.編譯過程發現很多錯誤.最後發現 這本書帶的驅動 都是基於linux2.4的.目前我用的linux2.6,部分需要做修改.我的板子是 友善之臂的 2410.vmware ubuntu nfs交叉編譯 首先 ...
(一)linux驅動之led
我採用的是正點原子的linux板子,覺得原子的板子還是很不錯的。由於正點原子使用的設計是通過電平拉低是點亮led,拉高則是關閉led。1.構建驅動載入和解除安裝函式 2.申請裝置號,裝置號可以指定,或者讓系統自動分配 3.初始化建立的cdev結構體。4.最後自動建立裝置節點 include incl...
Linux驅動學習之篇外
一些有用的tricks 隨時補充 sys firmware devicetree base,這個節點也會被鏈結到 proc device tree proc interrupts proc irq irq num sys class gpio 需要通過gpio export 或者gpio expor...