#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "stm32f4xx.h" #include "stm32f4xx_hal_gpio.h" #include "stm32f4xx_hal_cortex.h" static int major = 99; static int minor = 0; static dev_t devno; static struct cdev *test_cdev = NULL; static int count = 3; #define DEVNAME "test_module" //struct class *my_class = NULL; struct device *dev = NULL; static uint8_t PR_Reg; static DECLARE_WAIT_QUEUE_HEAD(wq); static volatile int ev_press = 0; static int test_open(struct inode *inode, struct file *filep); static int test_close(struct inode *inode, struct file *filep); static ssize_t test_read(struct file *filep, char __user *buf, size_t size, loff_t *offset); static ssize_t test_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset); static struct file_operations test_ops = { .owner = THIS_MODULE, .open = test_open, .release = test_close, .read = test_read, .write = test_write, }; static int test_open(struct inode *inode, struct file *filep) { printk("---> test open\n"); return 0; } static int test_close(struct inode *inode, struct file *filep) { printk("---> test close\n"); return 0; } static ssize_t test_read(struct file *filep, char __user *buf, size_t size, loff_t *offset) { // struct inode *inode = filep->f_path.dentry->d_inode; wait_event_interruptible(wq,ev_press); ev_press = 0; copy_to_user(buf, &PR_Reg, 1); printk("---> test read, PR_Reg = %#x\n", PR_Reg); return 0; } static ssize_t test_write(struct file *filep, const char __user *buf, size_t size, loff_t *offset) { printk("---> test write\n"); return 0; } irqreturn_t irq_handler(int irqno, void *dev_id) { /* EXTI line interrupt detected */ if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_4) != RESET) { PR_Reg = EXTI->PR; printk("EXTI->PR = %#x\n", PR_Reg); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4); ev_press = 1; wake_up_interruptible(&wq); } //printk("%#x\n", EXTI->PR); return IRQ_HANDLED; } static int __init test_init(void) { uint32_t start_jiffies, now_jiffies, tickRate; GPIO_InitTypeDef gpio_init_struct; uint32_t pre_priority, sub_priority; uint32_t priority_group; int ret; printk(KERN_ALERT"hello test module!\n"); test_cdev = cdev_alloc(); if(test_cdev == NULL){ return -ENOMEM; } cdev_init(test_cdev,&test_ops); devno = MKDEV(major,minor); ret = register_chrdev_region(devno, count, DEVNAME); if(ret){ goto ERR_STEP; } ret = cdev_add(test_cdev, devno, count); if(ret){ goto ERR_STEP1; } printk(KERN_INFO"(%s:pid=%d)major:%d,minor:%d\n",current->comm,current->pid,major,minor); /* GPIOI4 input interrupt */ __HAL_RCC_GPIOI_CLK_ENABLE(); gpio_init_struct.Pin = GPIO_PIN_4; gpio_init_struct.Mode = GPIO_MODE_IT_FALLING; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOI, &gpio_init_struct); // HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); priority_group = HAL_NVIC_GetPriorityGrouping(); HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0); HAL_NVIC_EnableIRQ(EXTI4_IRQn); HAL_NVIC_GetPriority(EXTI4_IRQn, priority_group, &pre_priority, &sub_priority); ret = request_irq( EXTI4_IRQn, irq_handler, IRQF_TRIGGER_FALLING, DEVNAME, &devno); if(ret){ printk("request_irq() failed ! %d\n", ret); goto ERR_STEP1; } start_jiffies = jiffies; // tickRate = sysconf(__SC_CLK_TCK); mdelay(100); printk("start: %lu, now %lu, rate %lu\n", start_jiffies, jiffies, HZ); printk("---> test module ok! priority_group = %d, pre_priority = %d, sub_priority = %d\n", priority_group, pre_priority, sub_priority); return 0; //device_err: // device_destroy(my_class, devno); //class_err: ERR_STEP1: unregister_chrdev_region(devno,count); ERR_STEP: cdev_del(test_cdev); return ret; } static void __exit test_exit(void) { printk(KERN_ALERT"exit test module!\n"); // device_destroy(my_class, devno); // class_destroy(my_class); unregister_chrdev_region(MKDEV(major,minor),count); cdev_del(test_cdev); // return 0; } module_init(test_init); module_exit(test_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jimbo"); MODULE_DESCRIPTION("this module just for test");