通過字元裝置檔案控制gpio電平通知微控制器訊號。
獲取gpio號
notify_gpio = of_get_named_gpio(pdev->dev.of_node, "notify_gpio", 0);
if((ret = gpio_init()) < 0)
註冊字元裝置
#define gpio_major 199 // major device no.
#define gpio_minor 0 // minor device no.
#define device_name "gpio_notify" //driver device node.
static const struct file_operations gpio_fops =
;static int gpio_init(void)
cdev_init(gpio_cdev,&gpio_fops);
gpio_cdev->owner=this_module;
ret = alloc_chrdev_region(&my_dev_no,0,1,device_name);
if(ret < 0)
ret=cdev_add(gpio_cdev,my_dev_no,1);
ret = register_chrdev(gpio_major, device_name, &gpio_fops);
if(ret < 0)
gpio_class = class_create(this_module, device_name);
device_create(gpio_class, null, mkdev(gpio_major, gpio_minor), null, device_name);
printk("[gale] %s: ok ###############################\n", __func__);
return ret;
request_failed:
return ret;
}
ioctl函式實現如下:收到訊號設定對應的高低電平
static int gpio_ioctl(struct file *filp,unsigned int cmd)
case set_output_high://1
case get_value://2
case set_input://3
default:
}return 0;
}
非同步通知函式初始化,用於指定kill_fasync函式的目標程序id
static int gpio_fasync (int fd, struct file *filp, int mode)
指定資料內容儲存檔案位置,位置在:/sys/devices/soc:quec,quectel-low-consume/irq_edge
static volatile char edge[8] = "rising";
static ssize_t irq_edge_show(struct device* dev, struct device_attribute *attr, char* buf)
static device_attr(irq_edge, s_irugo, irq_edge_show, null);
分2個部分:gpio中斷函式裡面使用kill_fasync發訊號給字元裝置;其他地方使用ioctl給字元裝置發命令;
1、gpio中斷函式裡面使用kill_fasync發訊號給字元裝置;
static irqreturn_t quectel_wakeup_irq_func(void)
else if(value == high_value)
return irq_handled;
}
2、其他地方收到訊號並獲取資料內容,然後使用ioctl給字元裝置發命令;
#define wakeup_io "/dev/gpio_notify"
pm_register(wakeup_io, pm_handle);
static int pm_register(char *path, void (*handle)(int signal))
訊號處理函式
#define irq_edge "/sys/devices/soc:quec,quectel-low-consume/irq_edge"
#define active 0
static void pm_handle(int signal)
; fd = open(irq_edge, o_rdonly | o_nonblock);
if (fd < 0)
return "null";
count = read(fd, edge, sizeof(edge)); //讀取資料內容
printf("%s:%s(%d)\n", irq_edge, edge, count);
close(fd);
if (strncmp(edge, "falling", 7) == 0) else if (strncmp(edge, "rising", 6) == 0)
這樣的gpio方式需防止gpio衝突導致訊號傳送不成功的偶現低概率問題。 Linux 字元裝置控制技術
字元裝置控制技術 一。字元裝置控制理論 1.作用 大部分裝置除了具有 讀寫裝置 的能力,還應該有 控制裝置 的能力。比如改變 波特率 2.應用程式介面 在使用者空間中使用 ioctl系統來控制裝置,原型如下 int ioctl int fd,unsigned long cmd,fd 控制的裝置檔案描...
Linux字元裝置檔案
申請字元裝置 第一種方法 檢視系統中哪個裝置號屬於空閒 我們可以檢視字元裝置,塊裝置 int register chrdev region dev t from,unsigned count,const char name from 待申請的裝置號 count 待申請的裝置號數目 次裝置號 name...
字元裝置控制
大部分驅動程式除了讀寫功能外,還需要具備控制裝置的能力,比如對於串列埠,需要具備修改波特率的功能。在使用者空間,使用ioctl 函式作為系統呼叫來控制裝置 原型 int ioctl int fd,unsigned long cmd,標頭檔案 功能 字元裝置控制函式 引數 fd 要控制的裝置檔案描述符...