歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> S3C2440開發板LED驅動——ioremap 映射

S3C2440開發板LED驅動——ioremap 映射

日期:2017/3/1 10:05:16   编辑:Linux編程

剛開始學字符設備驅動,感覺最難的是驅動和底層硬件的連接。linux上的驅動程序,是基於操作系統之上的,他並不直接和底層的硬件打交道,但是我們寫的驅動必須能使硬件“跑”起來,即與硬件緊密相連。

就拿最簡單的LED驅動來說,我們的驅動程序是在虛擬的內存上面跑的,但是最終,LED的點亮還是必須靠GPIO管腳的高低電平來控制。那麼,我們的虛擬的內存怎麼才能和實際的硬件上面的寄存器對應起來呢?

這篇要寫的就是ioremap這個映射函數,他可以將我們硬件上面的寄存器,映射為虛擬的內存,從而使驅動程序在我們的虛擬的內存中運行。

void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)

入口: phys_addr:要映射的起始的IO地址,即:物理地址

size:要映射的空間的大小;

flags:要映射的IO空間的和權限有關的標志;

下面是我用ioremap函數寫的第一個LED 的驅動:(硬件是S3C2440的開發板)

/***************************************************************/
//file name: ioremap_driver.c
#include <linux/module.h>
#include <linux/init.h>
#include <asm/io.h>
volatile unsigned long virt, phys;//用於存放虛擬地址和物理地址
volatile unsigned long *GPBCON, *GPBDAT, *GPBUP;//用與存放三個寄存器的地址
void led_device_init(void)
{
// 0x56000010 + 0x10 包攬全所有的IO引腳寄存器地址
phys = 0x56000010; // 0x56000010=GPBCON
//在虛擬地址空間中申請一塊長度為0x10的連續空間
//這樣,物理地址phys到phys+0x10對應虛擬地址virt到virt+0x10
virt =(unsigned long)ioremap(phys, 0x10);
GPBCON = (unsigned long *)(virt + 0x00);//指定需要操作的三個寄存器的地址
GPBDAT = (unsigned long *)(virt + 0x04);
GPBUP = (unsigned long *)(virt + 0x08);
}
//led配置函數,配置開發板的GPIO的寄存器
void led_configure(void)
{
*GPBCON &= ~(3 << 10)&~(3<<12)&~(3 << 16)&~(3<<20);//GPB12 defaule 清零
*GPBCON |= (1 << 10)|(1<<12)|(1<<16)|(1<<20); //output 輸出模式
*GPBUP |= (1 << 5)|(1 <<6)|(1 <<8)|(1 <<10); //禁止上拉電阻
}
void led_on(void) //點亮led
{
*GPBDAT &= ~(1 << 5)&~(1 << 6)&~(1 << 8)&~(1 << 10);
}
void led_off(void) //滅掉led
{
*GPBDAT |= (1 << 5)|(1 << 6)|(1 << 8)|(1 << 10);
}
static int __init led_init(void) //模塊初始化函數
{
led_device_init(); //實現IO內存的映射
led_configure(); //配置GPB5 6 8 10為輸出
led_on();
printk("hello ON!\n");
return 0;
}
static void __exit led_exit(void) //模塊卸載函數
{
led_off();
iounmap((void *)virt); //撤銷映射關系
printk("led OFF!\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("hurryliu<>");
MODULE_VERSION("2012-8-5.1.0");
/*************************************************************************/

實驗現象:

啟動開發板,在命令行模式下將編譯好的ioremap_driver.ko模塊加載到內核中

# insmod ioremap_driver.ko

這時,我們可以看到,開發板上面的LED4個燈全亮了。

# rmmod ioremap_driver 卸載模塊

這時,我們的LED燈就滅了。

Copyright © Linux教程網 All Rights Reserved