在linux核心裡mmu已經啟用,不能直接訪問實體地址,必須要把物理位址對映到乙個虛擬位址上,然後通過該虛擬位址來訪問原實體地址。
void *ioremap(cookie, size) //用於把指定的物理位址對映到乙個虛擬位址上
//cookie用於指定要對映的實體地址,size表示對映的大小範圍
//返回值為對映得到的虛擬位址
iounmap(void *addr) //用於取消虛擬位址的對映關係
ioread8(位址)/readb() //讀位址上的8位值,readb是比較老的函式
ioread16(位址)/readw() //讀位址上的16位值
ioread32(位址)/readl() //讀32位值
iowrite8(值, 位址)/writeb //把8位的值寫到指定的位址上,writeb是比較老的函式
iowrite16(值, 位址)/writew //把16位的值寫到指定的位址上
iowrite32(值, 位址)/writel //把32位的值寫到指定的位址上
事例**(控制板子上的led燈亮滅)(***.c):
#include
#include
#include
#define base_ddr 0x01c20800 //基位址
#define pa_cfg1_offset 0x04 //pa組io口的功能配置暫存器1對基位址偏移為4位元組
#define pa_data_offset 0x10 //pa組io口的資料暫存器對基位址偏移為0x10位元組
u8 *vaddr;//用於記錄對映得到的虛擬位址
static
int __init myled_init(void)
static
void __exit myled_exit(void)
module_init(myled_init);
module_exit(myled_exit);
module_license("gpl");
linux核心裡有標準的gpio操作方法,其中有對晶元廠商的要求,晶元廠商需要在核心裡實現相關的gpio控制器的驅動配置,讓核心裡的gpiolib(drivers/gpio/目錄下)可以統一管理整個晶元的gpio口,讓我們驅動人員可以用核心提供的gpio標準操作函式,通過gpiolib來呼叫控制晶元的io口。
gpio提供io口的呼叫函式包括:
#include //裡面宣告io口的操作函式
int gpio_request(unsigned gpio, const
char *label);//每個io只能被請求一次,可防止多個驅動來控制同乙個io口
void gpio_free(unsigned gpio);//釋放已請求的io口
int gpio_direction_input(unsigned gpio);//把指定的io口作輸入功能,gpio用於指定具體哪個io口
int gpio_direction_output(unsigned gpio, int value);//作輸出功能,並根據value的值輸出高低電平
int gpio_get_value(unsigned gpio);//獲取指定io口的電平
void gpio_set_value(unsigned gpio, int value);//設定io口的電平為value(0/1)
int gpio_to_irq(unsigned gpio);//根據io口,獲取到它對應的中斷號(io口大都有外部中斷功能)
一般情況下,io口的定義是在核心原始碼的arch/arm/mach-***x/include/mach/gpio.h
orange pi(h3)io口定義是在核心原始碼的arch/arm/mach-sunxi/include/mach/gpio.h
包括以下的巨集(n表示這組裡的第幾個io口):
#define gpioa(n) (sunxi_pa_base + (n))
#define gpiob(n) (sunxi_pb_base + (n))
#define gpioc(n) (sunxi_pc_base + (n))
#define gpiod(n) (sunxi_pd_base + (n))
#define gpioe(n) (sunxi_pe_base + (n))
#define gpiof(n) (sunxi_pf_base + (n))
#define gpiog(n) (sunxi_pg_base + (n))
#define gpioh(n) (sunxi_ph_base + (n))
#define gpioi(n) (sunxi_pi_base + (n))
#define gpioj(n) (sunxi_pj_base + (n))
#define gpiok(n) (sunxi_pk_base + (n))
#define gpiol(n) (sunxi_pl_base + (n))
#define gpiom(n) (sunxi_pm_base + (n))
#define gpion(n) (sunxi_pn_base + (n))
#define gpioo(n) (sunxi_po_base + (n))
#define gpio_axp(n) (axp_pin_base + (n))
使用gpio實現在驅動模組初始化時led亮燈,解除安裝時滅燈(***.c):
#include
#include
#include //晶元io口的巨集定義
#include //io口的呼叫函式
#define led_gpio gpioa(15) //pa15
static
int __init test_init(void)
static
void __exit test_exit(void)
module_init(test_init);
module_exit(test_exit);
module_license("gpl");
makefile檔案:
obj-m
+= ***.o
ksrc :=
/目錄路徑/orangepi_sdk/source/linux-
3.4.112
/export arch := arm
export cross_compile := arm-linux
-gnueabihf
-all :
make -c $(ksrc) modules m=
`pwd`
.phony : clean
clean :
make -c $(ksrc) modules clean m=
`pwd`
微控制器I O口控制實驗
實驗內容 利用p1口做輸出口,接八隻發光二極體,編寫程式是發光二極體迴圈點亮或者具有一定的花樣。1.第乙個發光二極體以間隔200ms閃爍 2.8個發光二極體由上至下間隔,1s流動,其中每個管亮500ms,滅500ms,亮時蜂鳴器響,滅時關閉蜂鳴器,一直重複下去 3.8個發光二極體來回流動,每個管亮1...
01 TI cc2530的IO口控制
乙個io口就是相當於從cpu晶元裡引出的一根導線,用於連線輸入輸出裝置,由 來控制 獲取它的電平。也就是說我們可以通過 控制乙個io口是高電平還是低電平 io作輸出功能 還是通過 來判斷io口是處於高 低電平狀態 io作輸入功能 cc2530裡共分成三組io口 p0,p1,p2 p0組和p1組裡都有...
Linux核心中流量控制 15
msn yfydz no1 hotmail.com 5.15.qdisc的netlink控制 各網絡卡的qdisc的使用者層操作控制是通過rtnetlink介面實現使用者空間和核心之間的通訊的 rtnetlink link,rtnetlink是專門針對路由控制的netlink介面.include l...