【linux】gpio子系統
- 2020 年 11 月 18 日
- 筆記
- /label/linux, /label/lzm, /study/linux/app, C語言, linux
前言
- 目前不涉及驅動源碼
- 參考鏈接
linux子系統
- 在 Linux 系統中
- 絕大多數硬體設備都有非常成熟的驅動框架
- 驅動工程師使用這些框架添加與板子相關的硬體支援
- 建立硬體與Linux內核的聯繫
- 內核再通過統一文件系統介面呈現給用戶
- 用戶通過對應的設備文件控制硬體。
gpio子系統
- gpio子系統相關描述可在內核源碼 Documentation/gpio 了解。
- 但是新版本(linux4.19左右)不再維護這個路徑的ABI
- ABI文檔已經移動到 Documentation/ABI/obsolete/sysfs-gpio
- gpio子系統 ,在目錄
/sys/class/gpio
下展示該子系統設備。-
-
export 和 unexport:把某個GPIO導出用戶空間和取消導出用戶空間
echo 19 > export
- 就把gpio19導出到用戶空間
-
gpioN:GPIOs 本身,N為索引號,根據不同的開發晶片而有不同的計算
- 例子:N = index = GPIO1_19 = (1-1)*32 +19 = 19
- 一組埠有 32 個gpio
- 該目錄下有三個屬性文件
- direction
- gpio埠的方向,內容可以是 in 或者 out
- 讀取
- 寫入
- 例子:
echo out > /sys/class/gpio/gpio19/direction
- 例子:
- 如果寫入 low 或者 hight,則不僅設置為輸出,還同時設置了輸出電平(本小點要了解當前內核是否支援)
- gpio埠的方向,內容可以是 in 或者 out
- value
- gpio引腳的電平
- 0:低電平
- 非0:高電平(高電平建議使用 1)
- 如果配置為輸入,則該文件可寫
- 如果配置為中斷,則可以調用poll(2)函數監聽該中斷,中斷觸發後poll(2)函數就會返回。
- gpio引腳的電平
- edge
- 中斷的觸發方式,該文件有4個值
- none:輸入,非中斷
- rising:中斷輸入,上升沿觸發
- falling:中斷輸入,下降沿觸發
- both:中斷輸入,邊沿觸發
- 中斷的觸發方式,該文件有4個值
- active_low
- direction
- 例子:N = index = GPIO1_19 = (1-1)*32 +19 = 19
-
GPIO控制器(「gpio_chip」instances)(此處沒有體現)。
-
- gpio子系統與led子系統是不同,但是類似
- led只能輸出,gpio能輸出也能輸入
- gpio輸入還支援中斷功能
- 使用gpio前,需要從內核空間暴露到用戶空間
- led只能輸出,gpio能輸出也能輸入
- 注意
- 在用戶空間控制使用gpio時,注意不要濫用和內核一些綁定好、已經有合適內核啟動的引腳衝突。
- 參考 Documentation/driver-api/gpio/drivers-on-gpio.rst
- 在用戶空間控制使用gpio時,注意不要濫用和內核一些綁定好、已經有合適內核啟動的引腳衝突。
gpio子系統實戰-系統調用
- 源碼簡單,下面貼出野火的源碼僅做參考
- main.c
/** @file main.c
* @brief 簡要說明
* @details 詳細說明
* @author
* @date 2020-11-11 19:18:20
* @version v1.0
* @copyright Copyright By , All Rights Reserved
*
**********************************************************
* @LOG 修改日誌:
**********************************************************
*/
#include <stdio.h>
#include <unistd.h>
#include "bsp_beep.h"
/**
* @brief 主函數
* @param 無
* @retval 無
*/
int main(int argc, char *argv[])
{
char buf[10];
int res;
printf("This is the beep demo\n");
res = beep_init();
if(res){
printf("beep init error,code = %d",res);
return 0;
}
while(1){
printf("Please input the value : 0--off 1--on q--exit\n");
scanf("%10s", buf);
switch (buf[0]){
case '0':
beep_off();
break;
case '1':
beep_on();
break;
case 'q':
beep_deinit();
printf("Exit\n");
return 0;
default:
break;
}
}
}
- bsp_beep.c
/** @file bsp_beep.c
* @brief 簡要說明
* @details 詳細說明
* @author
* @date 2020-11-11 13:57:52
* @version v1.0
* @copyright Copyright By , All Rights Reserved
*
**********************************************************
* @LOG 修改日誌:
**********************************************************
*/
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "bsp_beep.h"
int beep_init(void)
{
int fd;
fd = open("/sys/class/gpio/export",O_WRONLY);
if(fd < 0)
{
return 1;
}
write(fd, BEEP_GPIO_INDEX, strlen(BEEP_GPIO_INDEX));
close(fd);
//direction config
fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/direction", O_WRONLY);
if(fd < 0)
return 2;
write(fd, "out", strlen("out"));
close(fd);
return 0;
}
int beep_deinit(void)
{
int fd;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if(fd < 0)
return 1;
write(fd, BEEP_GPIO_INDEX, strlen(BEEP_GPIO_INDEX));
close(fd);
return 0;
}
int beep_on(void)
{
int fd;
fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/value", O_WRONLY);
if(fd < 0)
return 1;
write(fd, "1", 1);
close(fd);
return 0;
}
int beep_off(void)
{
int fd;
fd = open("/sys/class/gpio/gpio" BEEP_GPIO_INDEX "/value", O_WRONLY);
if(fd < 0)
return 1;
write(fd, "0", 1);
close(fd);
return 0;
}
- bsp_beep.h
/** @file bsp_beep.h
* @brief 簡要說明
* @details 詳細說明
* @author
* @date 2020-11-11 19:13:47
* @version v1.0
* @copyright Copyright By , All Rights Reserved
*
**********************************************************
* @LOG 修改日誌:
**********************************************************
*/
#ifndef __bsp_beep__
#define __bsp_beep__
//蜂鳴器的GPIO引腳號
//imx6的計算方式,GPIOn_IOx = (n-1)*32 + x
//如GPIO1_IO19 = (1-1)*32 + 19 = 19
#define BEEP_GPIO_INDEX "19"
/**
* @brief 初始化蜂鳴器gpio相關
* @return
* @arg 0,正常
* @arg 1,export文件打開錯誤
* @arg 2,direction文件打開錯誤
*/
extern int beep_init(void);
/**
* @brief 關閉蜂鳴器gpio的export輸出
* @return 0正常,非0,value文件打開錯誤
*/
extern int beep_deinit(void);
/**
* @brief 蜂鳴器響
* @return 0正常,非0,value文件打開錯誤
*/
extern int beep_on(void);
/**
* @brief 關閉蜂鳴器gpio的export輸出
* @return 0正常,非0,unexport文件打開錯誤
*/
extern int beep_off(void);
#endif /* Head define end*/