15 核心裡控制IO口

2021-08-15 21:16:37 字數 3524 閱讀 8419

在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...