gpio映射哪個存儲空間
㈠ 嵌入式系統中的存儲器映射是怎麼回事,為什麼要映射
我是這樣理解的:
存儲器空間是和硬體相關聯的,可以對某些地址上寫數據來控制硬體,為了方便使用(總不可能都用地址來直接控制,那樣就工作量就太大了),將這些地址賦予了一些變數名,通過變數名來控制硬體(也就是寄存器的概念)。
㈡ 在C語言中GPIOB->ODR |= LED是什麼意思
這是stm32f10x系列的程序吧?固件庫?
就是GPIOB的ODR變數,或上LED
LED應該是0x01或0x02或0x03這樣的值,置1的位就是對應埠pin輸出高電平,也就是GPIO的B組IO口中的對應埠置高電平。
這個ODR什麼用途的忘了。
GPIOB指向了一個內存地址,映射到了寄存器,你現在是在修改配置寄存器。
㈢ 您好這是原程序,怎麼用它映射設備文件我想通過內存映射操作gpio寄存器,請幫忙,拜謝!
ioremap即可~ 詳情網路 ...
㈣ STM32的GPIO 7個寄存器地址是多少 映射地址怎麼設置
以GPIOA為例:
GPIOA 的基地址是怎麼算出來的呢?因為 GPIO 都是掛載在 APB2 匯流排
之上,所以它的基地址是由 APB2 匯流排的基地址+GPIOA 在 APB2 匯流排上的偏移地址決定
的。同理依次類推,我們便可以算出 GPIOA 基地址了。這里設計到匯流排的一些知識,我們
在後面會講到。下面我們打開 stm32f10x.h 定位到 GPIO_TypeDef 定義處:
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
然後定位到:
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
可以看出,GPIOA 是將 GPIOA_BASE 強制轉換為 GPIO_TypeDef 指針,這句話的意思是,
GPIOA 指向地址 GPIOA_BASE,GPIOA_BASE 存放的數據類型為 GPIO_TypeDef。然後雙
擊「GPIOA_BASE」選中之後右鍵選中「Go to definition of 」 ,便可一查看 GPIOA_BASE
的宏定義:
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
依次類推,可以找到最頂層:
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define PERIPH_BASE ((uint32_t)0x40000000)
所以我們便可以算出 GPIOA 的基地址位:
GPIOA_BASE= 0x40000000+0x10000+0x0800=0x40010800
這些都可以在《STM32開發指南-庫函數版本_V1.3》(P.123)4.6節【MDK 中寄存器地址名稱映射分析】中找到,《STM32 中文參考手冊 V10》中的寄存器地址映射表(P159)介紹的更詳細,我想你應該有這兩個手冊吧?沒有的話就下載吧,我已經上傳了,費用。。。就不收了。
不過話說回來啊,樓上的08274061 說的其實沒錯,不看手冊想學好32真的很難,我也在學32,剛好看到這一節,剛好碰見你的問題,就順便解答了~~好好學吧同學~~
㈤ 如何在文件系統中添加/sys/class/gpio
通過sysfs方式控制GPIO,先訪問/sys/class/gpio目錄,向export文件寫入GPIO編號,使得該GPIO的操作介面從內核空間暴露到用戶空間,GPIO的操作介麵包括direction和value等,direction控制GPIO方向,而value可控制GPIO輸出或獲得GPIO輸入。文件IO方式操作GPIO,使用到了4個函數open、close、read、write。
首先,看看系統中有沒有「/sys/class/gpio」這個文件夾。如果沒有請在編譯內核的時候加入 Device Drivers-> GPIO Support ->/sys/class/gpio/… (sysfs interface)。
/sys/class/gpio 的使用說明:
gpio_operation 通過/sys/文件介面操作IO埠 GPIO到文件系統的映射
◇ 控制GPIO的目錄位於/sys/class/gpio
◇ /sys/class/gpio/export文件用於通知系統需要導出控制的GPIO引腳編號
◇ /sys/class/gpio/unexport 用於通知系統取消導出
◇ /sys/class/gpio/gpiochipX目錄保存系統中GPIO寄存器的信息,包括每個寄存器控制引腳的起始編號base,寄存器名稱,引腳總數 導出一個引腳的操作步驟
◇ 首先計算此引腳編號,引腳編號 = 控制引腳的寄存器基數 + 控制引腳寄存器位數
◇ 向/sys/class/gpio/export寫入此編號,比如12號引腳,在shell中可以通過以下命令實現,命令成功後生成/sys/class/gpio/gpio12目錄,如果沒有出現相應的目錄,說明此引腳不可導出
◇ direction文件,定義輸入輸入方向,可以通過下面命令定義為輸出。direction接受的參數:in, out, high, low。high/low同時設置方向為輸出,並將value設置為相應的1/0
◇ value文件是埠的數值,為1或0
幾個例子:
1. 導出
/sys/class/gpio# echo 44 > export
2. 設置方向
/sys/class/gpio/gpio44# echo out > direction
3. 查看方向
/sys/class/gpio/gpio44# cat direction
4. 設置輸出
/sys/class/gpio/gpio44# echo 1 > value
5. 查看輸出值
/sys/class/gpio/gpio44# cat value
6. 取消導出
/sys/class/gpio# echo 44 > unexport
文件讀寫常式:
#include stdlib.h
#include stdio.h
#include string.h
#include unistd.h
#include fcntl.h //define O_WRONLY and O_RDONLY
//晶元復位引腳: P1_16
#define SYSFS_GPIO_EXPORT "/sys/class/gpio/export"
#define SYSFS_GPIO_RST_PIN_VAL "48"
#define SYSFS_GPIO_RST_DIR "/sys/class/gpio/gpio48/direction"
#define SYSFS_GPIO_RST_DIR_VAL "OUT"
#define SYSFS_GPIO_RST_VAL "/sys/class/gpio/gpio48/value"
#define SYSFS_GPIO_RST_VAL_H "1"
#define SYSFS_GPIO_RST_VAL_L "0"
int main()
{
int fd;
//打開埠/sys/class/gpio# echo 48 > export
fd = open(SYSFS_GPIO_EXPORT, O_WRONLY);
if(fd == -1)
{
printf("ERR: Radio hard reset pin open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_PIN_VAL ,sizeof(SYSFS_GPIO_RST_PIN_VAL));
close(fd);
//設置埠方向/sys/class/gpio/gpio48# echo out > direction
fd = open(SYSFS_GPIO_RST_DIR, O_WRONLY);
if(fd == -1)
{
printf("ERR: Radio hard reset pin direction open error.\n");
return EXIT_FAILURE;
}
write(fd, SYSFS_GPIO_RST_DIR_VAL, sizeof(SYSFS_GPIO_RST_DIR_VAL));
close(fd);
//輸出復位信號: 拉高>100ns
fd = open(SYSFS_GPIO_RST_VAL, O_RDWR);
if(fd == -1)
{
printf("ERR: Radio hard reset pin value open error.\n");
return EXIT_FAILURE;
}
while(1)
{
write(fd, SYSFS_GPIO_RST_VAL_H, sizeof(SYSFS_GPIO_RST_VAL_H));
usleep(1000000);
write(fd, SYSFS_GPIO_RST_VAL_L, sizeof(SYSFS_GPIO_RST_VAL_L));
usleep(1000000);
}
close(fd);
printf("INFO: Radio hard reset pin value open error.\n");
return 0;
}
另外參考網上一個網友的程序,這里做了驗證,並實現中斷檢測函數。如下:
#include stdlib.h
#include stdio.h
#include string.h
#include unistd.h
#include fcntl.h
#include poll.h
#define MSG(args...) printf(args)
//函數聲明
static int gpio_export(int pin);
static int gpio_unexport(int pin);
static int gpio_direction(int pin, int dir);
static int gpio_write(int pin, int value);
static int gpio_read(int pin);
static int gpio_export(int pin)
{
char buffer[64];
int len;
int fd;
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
MSG("Failed to open export for writing!\n");
return(-1);
}
len = snprintf(buffer, sizeof(buffer), "%d", pin);
if (write(fd, buffer, len) < 0) {
MSG("Failed to export gpio!");
return -1;
}
close(fd);
return 0;
}
static int gpio_unexport(int pin)
{
char buffer[64];
int len;
int fd;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0) {
MSG("Failed to open unexport for writing!\n");
return -1;
}
len = snprintf(buffer, sizeof(buffer), "%d", pin);
if (write(fd, buffer, len) < 0) {
MSG("Failed to unexport gpio!");
return -1;
}
close(fd);
return 0;
}
//dir: 0-->IN, 1-->OUT
static int gpio_direction(int pin, int dir)
{
static const char dir_str[] = "in\0out";
char path[64];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);
fd = open(path, O_WRONLY);
if (fd < 0) {
MSG("Failed to open gpio direction for writing!\n");
return -1;
}
if (write(fd, &dir_str[dir == 0 ? 0 : 3], dir == 0 ? 2 : 3) < 0) {
MSG("Failed to set direction!\n");
return -1;
}
close(fd);
return 0;
}
//value: 0-->LOW, 1-->HIGH
static int gpio_write(int pin, int value)
{
static const char values_str[] = "01";
char path[64];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
if (fd < 0) {
MSG("Failed to open gpio value for writing!\n");
return -1;
}
if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) {
MSG("Failed to write value!\n");
return -1;
}
close(fd);
return 0;
}
static int gpio_read(int pin)
{
char path[64];
char value_str[3];
int fd;
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (fd < 0) {
MSG("Failed to open gpio value for reading!\n");
return -1;
}
if (read(fd, value_str, 3) < 0) {
MSG("Failed to read value!\n");
return -1;
}
close(fd);
return (atoi(value_str));
}
// none表示引腳為輸入,不是中斷引腳
// rising表示引腳為中斷輸入,上升沿觸發
// falling表示引腳為中斷輸入,下降沿觸發
// both表示引腳為中斷輸入,邊沿觸發
// 0-->none, 1-->rising, 2-->falling, 3-->both
static int gpio_edge(int pin, int edge)
{
const char dir_str[] = "none\0rising\0falling\0both";
char ptr;
char path[64];
int fd;
switch(edge){
case 0:
ptr = 0;
break;
case 1:
ptr = 5;
break;
case 2:
ptr = 12;
break;
case 3:
ptr = 20;
break;
default:
ptr = 0;
}
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin);
fd = open(path, O_WRONLY);
if (fd < 0) {
MSG("Failed to open gpio edge for writing!\n");
return -1;
}
if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0) {
MSG("Failed to set edge!\n");
return -1;
}
close(fd);
return 0;
}
//GPIO1_17
int main()
{
int gpio_fd, ret;
struct pollfd fds[1];
char buff[10];
unsigned char cnt = 0;
//LED引腳初始化
gpio_export(115);
gpio_direction(115, 1);
gpio_write(115, 0);
//按鍵引腳初始化
gpio_export(49);
gpio_direction(49, 0);
gpio_edge(49,1);
gpio_fd = open("/sys/class/gpio/gpio49/value",O_RDONLY);
if(gpio_fd < 0){
MSG("Failed to open value!\n");
return -1;
}
fds[0].fd = gpio_fd;
fds[0].events = POLLPRI;
ret = read(gpio_fd,buff,10);
if( ret == -1 )
MSG("read\n");
while(1){
ret = poll(fds,1,0);
if( ret == -1 )
MSG("poll\n");
if( fds[0].revents & POLLPRI){
ret = lseek(gpio_fd,0,SEEK_SET);
if( ret == -1 )
MSG("lseek\n");
ret = read(gpio_fd,buff,10);
if( ret == -1 )
MSG("read\n");
gpio_write(115, cnt++%2);
}
usleep(100000);
}
return 0;
}
㈥ 嵌入式機:編寫函數使gpio.0和gpio.1置位
摘要 /sys/class/gpio 的使用說明:
㈦ 如何在linux系統中直接操作GPIO
方法/步驟
1
安裝SD Linux系統
如圖所示,先後將Arino Software 1.5.3 (Arino IDE)和SD-Card Linux Image下載到本機,Arino IDE在後面查找GPIO與Arino IO 之間的映射關系時需要用到。
如圖所示,將SDCard1.0.4.tar.bz2解壓後出現一個「image-full-galileo」的文件夾。
在MicroSD使用前需先將其以Fat32進行格式化,然後將「image-full-galileo」文件夾下地所有文件直接拷貝到microSD卡的根目錄下。
進入Galileo
將MicroSD插到Galileo中,在路由器頁面的已連接設備列表中會看到設備名稱為「clanton」有線連接設備,找到其IP地址,然後中
Terminal(Unix和Linux,Windows可用Putty)中通過ssh進入Galileo,「ssh
[email protected]」。
有意思的是,這個在MicroSD中運行的Linux系統開啟了ssh服務,並且root賬號沒有設置密碼,可以直接進入。如上圖所示,彈出一對話框後輸入 「yes」回車即可進入Galileo,出現下圖中的 「root@clanton」說明這一步成功完成了
到這里,可能會有疑問了,Galileo板載也是有一個操作系統的,microSD卡中也有一個Linux,如何保證現在進入的就是microSD卡中的系
統呢?在Terminal中輸入「cat/proc/version」即可查看Linux系統版本,顯示為「3.8.7-yocto-standard」,這就是前面下載的為Galileo定製的Linux操作系統,Yocto。
找到那個屬於你的GPIO
下面就要開始這篇文章中的核心部分,也是最難的一部。找Linux GPIO 與 Arino IO之間的映射關系!
如右圖所示,在「/sys/class/gpio/」中有多大60多個GPIO,如何找出右側GPIO與左側Arino IDE中對應的IO呢。
首先將0-13IO口全部設為「INPUT」輸入模式
voidsetup(){//putyoursetupcodehere,torunonce:
pinMode(0,INPUT); pinMode(1,INPUT); pinMode(2,INPUT); pinMode(3,INPUT);
pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,INPUT); pinMode(7,INPUT);
pinMode(8,INPUT); pinMode(9,INPUT); pinMode(10,INPUT);
pinMode(11,INPUT); pinMode(12,INPUT); pinMode(13,INPUT); } voidloop(){
//putyourmaincodehere,torunrepeatedly: }
如圖所示,左側"pinMode(13,OUTPUT)"將13引腳變為輸出模式,右側gpio7變成out模式,因此gpio7對應的就是Arino IO 13(pin13)
按照這種方法依次找出Arino IO與GPIO之間如下的對應關系
GPIODigitalI/Ogpio11pin0
gpio12pin1 gpio13pin2 gpio14pin3 gpio6pin4 gpio0pin5 gpio1pin6
gpio38pin7 gpio40pin8 gpio4pin9 gpio10pin10 gpio5pin11 gpio15pin12
gpio7pin13
下面就需要來對上面找到的gpio對應關系進行驗證了。「echo "out"
>/sys/class/gpio/gpio*/direction」為將gpio變為輸出模式,「echo "1"
>/sys/class/gpio/gpio*/value」為將gpio輸出高電平。然後就有了下面這段python程序,這段程序依次將
pin13,pin12,pin11,pin10四個引腳的LED點亮然後關閉,但由於python程序的執行效率問題,應該所有LED同時點亮有了延時
成為流水燈,如下圖所示效果。這段程序在Linux系統的任意文件夾內均可。
importos,timewhileTrue:os.system('echo"out">/sys/class/gpio/gpio7/direction')
os.system('echo"1">/sys/class/gpio/gpio7/value')
os.system('echo"out">/sys/class/gpio/gpio15/direction')
os.system('echo"1">/sys/class/gpio/gpio15/value')
os.system('echo"out">/sys/class/gpio/gpio5/direction')
os.system('echo"1">/sys/class/gpio/gpio5/value')
os.system('echo"out">/sys/class/gpio/gpio10/direction')
os.system('echo"1">/sys/class/gpio/gpio10/value') time.sleep(0.2)
os.system('echo"0">/sys/class/gpio/gpio5/value')
os.system('echo"0">/sys/class/gpio/gpio15/value')
os.system('echo"0">/sys/class/gpio/gpio7/value')
os.system('echo"0">/sys/class/gpio/gpio10/value') time.sleep(0.2)
㈧ 什麼是GPIO
嵌入式系統中常常有數量眾多,但是結構卻比較簡單的外部設備/電路,對這些設備/電路有的需要CPU為之提供控制手段,有的則需要被CPU用作輸入信號。而且,許多這樣的設備/電路只要求一位,即只要有開/關兩種狀態就夠了,比如燈亮與滅。對這些設備/電路的控制,使用傳統的串列口或並行口都不合適。所以在微控制器晶元上一般都會提供一個「通用可編程IO介面」,即GPIO。介面至少有兩個寄存器,即「通用IO控制寄存器」與「通用IO數據寄存器」。數據寄存器的各位都直接引到晶元外部,而對這種寄存器中每一位的作用,即每一位的信號流通方向,則可以通過控制寄存器中對應位獨立的加以設置。這樣,有無GPIO介面也就成為微控制器區別於微處理器的一個特徵。在實際的MCU中,GPIO是有多種形式的。比如,有的數據寄存器可以按照位定址,有些卻不能按照位定址,這在編程時就要區分了。比如傳統的8051系列,就區分成可位定址和不可位定址兩種寄存器。另外,為了使用的方便,很多mcu把glue logic等集成到晶元內部,增強了系統的穩定性能,比如GPIO介面除去兩個標准寄存器必須具備外,還提供上拉寄存器,可以設置IO的輸出模式是高阻,還是帶上拉的電平輸出,或者不帶上拉的電平輸出。這在電路設計中,外圍電路就可以簡化不少。另外需要注意的是,對於不同的計算機體系結構,設備可能是埠映射,也可能是內存映射的。如果系統結構支持獨立的IO地址空間,並且是埠映射,就必須使用匯編語言完成實際對設備的控制,因為C語言並沒有提供真正的「埠」的概念。如果是內存映射,那就方便的多了。GPIO優點GPIO的優點(埠擴展器)低功耗:GPIO具有更低的功率損耗(大約1μA,μC的工作電流則為100μA)。集成IIC從機介面:GPIO內置IIC從機介面,即使在待機模式下也能夠全速工作。小封裝:GPIO器件提供最小的封裝尺寸 ― 3mm x 3mm QFN!低成本:您不用為沒有使用的功能買單!快速上市:不需要編寫額外的代碼、文檔,不需要任何維護工作!靈活的燈光控制:內置多路高解析度的PWM輸出。可預先確定響應時間:縮短或確定外部事件與中斷之間的響應時間。更好的燈光效果:匹配的電流輸出確保均勻的顯示亮度。布線簡單:僅需使用2條就可以組成IIC匯流排或3條組成SPI匯流排。與ARM 的幾組GPIO引腳,功能相似,GPxCON 控制引腳功能,GPxDAT用於讀寫引腳數據。另外,GPxUP用於確定是否使用上拉電阻。
㈨ f28335dsp控制器的gpio寄存器映射到哪個存儲空間
設備驅動如果是:可以寫一個字元設備驅動實現。
驅動,最簡單的是:用ioremap(),把GPIO的地址映射到linux內核空間。
然後操作該gpio的寄存器。
之後很簡單,和裸板控制gpio的方法一樣。
只是字元設備方面的實現不一樣。
㈩ S5P4418晶元GPIO分幾個區,對應的物理地址
S5P4418核心板即三星S5P4418核心板,是一款三星四核4418核心板,型號為RP4418,搭配1GB DDR3內存,4GB
EMMC存儲,Android4.4操作系統。
S5P4418核心板即三星S5P4418核心板,是一款三星4418處理器評估板核心板,屬於四核cortex-a9核心板。型號為RP4418,搭配1GB
DDR3內存,4GB EMMC存儲,Android4.4操作系統。RP4418採用28 nm
製程工藝為Cortex-A9的4核處理器,CPU頻率為1.4GHz,支持MALI MP2 3D圖形加速器、1M byte
L2緩存;視頻解碼能力:支持(H.264.MPEG4-ASP H.263 VC-1 MPEG-1/2 VP8 AVS RV8/9/10
RV8/9/10)1080P解碼;視頻編碼能力:支持(H.264 MPEG4 H.263)1080P編碼。