共2条
1/1 1 跳转至页
smartarm2200 请教在smartarm2200上写外部中断的问题
问
我目前在smartARM2200上的uclinux下写了一个用KEY1来触发外部中断,并用中断处理函数处理后将按键值返回给用户空间应用程序的驱动。但是发觉在asm/arch/irqs.h中定义的IRQ_EXT3与板子上的eth0的中断号一样都为17。驱动无法加载。若改变中断号,虽可以加载驱动,但按KEY1之后无任何反映,而且还出现IRQ17 is locking the system ,disable的消息。所以将程序贴出来大家帮我看看应该怎么办。我第一次写带中断的驱动,大家多多指点一下。
#include "config.h"
static int request_irqs(void);
static void free_irqs(void);
static int matrix4_buttons_open(struct inode *inode, struct file *filp);
static int matrix4_buttons_release(struct inode *inode, struct file *filp);
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg);
int read_gpio_bit(unsigned int gpio_port);
static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos);
static unsigned int matrix4_buttons_select(struct file *file,struct poll_table_struct *wait);
static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
//unsigned int GPIO_F3=20;
int num;
//#define IRQ_EXT3 19
#define GPIO_ADDR_BASE 0xE0028000
#define GPIO_PIN_OFFSET 0x00000000
#define GPIO_SET_OFFSET 0x00000001
#define GPIO_DIR_OFFSET 0x00000002
#define GPIO_CLR_OFFSET 0x00000003
#define GPIO_PORT_ADD 0x00000010
static struct key_info {
int irq_no;
unsigned int gpio_port;
int key_no;
}key_info_tab={IRQ_EXT3,20,1};
static int ready = 0;
static int key_value = 0;
static u32 RunTime;
static u32 PinSel0Save, PinSel1Save;
static unsigned int usage;
static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);
static int request_irqs(void)
{
struct key_info *k;
k = &key_info_tab;
if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) {
return -1;
}
printk("request_irq successful\n");
return 0;
}
static void free_irqs(void)
{
struct key_info *k;
k = &key_info_tab ;
free_irq(k->irq_no, buttons_irq);
}
static int matrix4_buttons_open(struct inode *inode, struct file *filp)
{
unsigned long flag;
int ret;
if(usage==0)
{
ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " CAN't request irqs\n");
return ret;
}
printk("open successful\n");
local_irq_save(flag);
PinSel0Save = inl(PINSEL0) & 0xfc00f;
PinSel1Save = inl(PINSEL1) & (0x03 << 10);
outl(3<<8,PINSEL1);
outl(1<<7,IO0DIR);
outb(0x00,EXTMODE);
printk("EXTMODE=0x%x",EXTMODE);
outb(1<<3,EXTINT);
// CLEAR_PEND_INT(IRQ_EXT3);
printk("EXTINT=0x%x",EXTINT);
RunTime=0;
local_irq_restore(flag);
enable_irq(IRQ_EXT3);
}
num = MINOR(inode->i_rdev);
printk("num=%d",num);
usage++;
MOD_INC_USE_COUNT;
return 0; /* success */
}
static int matrix4_buttons_release(struct inode *inode, struct file *filp)
{
unsigned long flag;
MOD_DEC_USE_COUNT;
usage--;
if(usage==0)
{
local_irq_save(flag);
outl(PinSel0Save | (inl(PINSEL0) & (~0xfc00f)), PINSEL0);
outl(PinSel1Save | (inl(PINSEL1) & (~(0x3 << 10))), PINSEL1);
local_irq_restore(flag);
free_irqs();
}
return(0);
}
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
struct key_info *k;
int found = 0;
int up;
int flags;
k = &key_info_tab ;
if (k->irq_no == irq) {
found = 1;
}
if (!found) {
printk("bad irq %d in button\n", irq);
return;
}
save_flags(flags);
disable_irq(IRQ_EXT3);
up = read_gpio_bit(k->gpio_port);
outb(1<<3,EXTINT);
enable_irq(IRQ_EXT3);
restore_flags(flags);
if (up) {
key_value = k->key_no + 0x80;
} else {
key_value = k->key_no;
}
ready = 1;
wake_up_interruptible(&buttons_wait);
RunTime++;
}
int read_gpio_bit(unsigned int gpio_port)
{
volatile u32 *Reg;
u32 temp1;
Reg = (volatile u32 *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * num);
temp1 = Reg[GPIO_PIN_OFFSET] & (1u << gpio_port);
if (temp1 != 0)
{
temp1 = GPIO_PIN_HIGH;
}
else
{
temp1 = GPIO_PIN_LOW;
}
return temp1;
}
static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
static int key;
int flags;
int repeat;
if (!ready)
return -EAGAIN;
if (count != sizeof key_value)
return -EINVAL;
save_flags(flags);
if (key != key_value) {
key = key_value;
repeat = 0;
} else {
repeat = 1;
}
restore_flags(flags);
if (repeat) {
return -EAGAIN;
}
copy_to_user(buffer, &key, sizeof key);
ready = 0;
return sizeof key_value;
}
static unsigned int matrix4_buttons_select(
struct file *file,
struct poll_table_struct *wait)
{
if (ready)
return 1;
poll_wait(file, &buttons_wait, wait);
return 0;
}
static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
default:
return -EINVAL;
}
}
static struct file_operations matrix4_buttons_fops = {
owner: THIS_MODULE,
ioctl: matrix4_buttons_ioctl,
poll: matrix4_buttons_select,
read: matrix4_buttons_read,
open: matrix4_buttons_open,
release:matrix4_buttons_release,
};
static int __init matrix4_buttons_init(void)
{
int ret;
ready = 0;
ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops);
if (ret < 0) {
printk(DEVICE_NAME " CAN't register major number\n");
return ret;
}
printk("Init ok\n");
/*************************************
ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " CAN't request irqs\n");
return ret;
}
***************************************/
return 0;
}
static void __exit matrix4_buttons_exit(void)
{
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
}
module_init(matrix4_buttons_init);
module_exit(matrix4_buttons_exit);
MODULE_LICENSE("GPL");
答 1: 奇怪怎么就没人回应呢 答 2: hihi.doya.问个问题,你是用仿真器下载的吗? 答 3: no我是在uclinux上用NFS下载到板子上然后用ismod加载的。
我不知道是不是能用EXTMODE=0X00来设置中断模式,应该如何清除中断。这些操作在uclinux下的接口是什么?希望大家教教我 答 4: 要注册中断要用request_irq()函数注册中断,还有,要注意中断的触发模式,是否与你要求的一致,可读相应寄存器的值出来看看对不对.看看<LINUX设备驱动程序>吧,中断那章有详细说明. 答 5: 写程序一个注释都没有~
#include "config.h"
static int request_irqs(void);
static void free_irqs(void);
static int matrix4_buttons_open(struct inode *inode, struct file *filp);
static int matrix4_buttons_release(struct inode *inode, struct file *filp);
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg);
int read_gpio_bit(unsigned int gpio_port);
static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos);
static unsigned int matrix4_buttons_select(struct file *file,struct poll_table_struct *wait);
static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
//unsigned int GPIO_F3=20;
int num;
//#define IRQ_EXT3 19
#define GPIO_ADDR_BASE 0xE0028000
#define GPIO_PIN_OFFSET 0x00000000
#define GPIO_SET_OFFSET 0x00000001
#define GPIO_DIR_OFFSET 0x00000002
#define GPIO_CLR_OFFSET 0x00000003
#define GPIO_PORT_ADD 0x00000010
static struct key_info {
int irq_no;
unsigned int gpio_port;
int key_no;
}key_info_tab={IRQ_EXT3,20,1};
static int ready = 0;
static int key_value = 0;
static u32 RunTime;
static u32 PinSel0Save, PinSel1Save;
static unsigned int usage;
static DECLARE_WAIT_QUEUE_HEAD(buttons_wait);
static int request_irqs(void)
{
struct key_info *k;
k = &key_info_tab;
if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)) {
return -1;
}
printk("request_irq successful\n");
return 0;
}
static void free_irqs(void)
{
struct key_info *k;
k = &key_info_tab ;
free_irq(k->irq_no, buttons_irq);
}
static int matrix4_buttons_open(struct inode *inode, struct file *filp)
{
unsigned long flag;
int ret;
if(usage==0)
{
ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " CAN't request irqs\n");
return ret;
}
printk("open successful\n");
local_irq_save(flag);
PinSel0Save = inl(PINSEL0) & 0xfc00f;
PinSel1Save = inl(PINSEL1) & (0x03 << 10);
outl(3<<8,PINSEL1);
outl(1<<7,IO0DIR);
outb(0x00,EXTMODE);
printk("EXTMODE=0x%x",EXTMODE);
outb(1<<3,EXTINT);
// CLEAR_PEND_INT(IRQ_EXT3);
printk("EXTINT=0x%x",EXTINT);
RunTime=0;
local_irq_restore(flag);
enable_irq(IRQ_EXT3);
}
num = MINOR(inode->i_rdev);
printk("num=%d",num);
usage++;
MOD_INC_USE_COUNT;
return 0; /* success */
}
static int matrix4_buttons_release(struct inode *inode, struct file *filp)
{
unsigned long flag;
MOD_DEC_USE_COUNT;
usage--;
if(usage==0)
{
local_irq_save(flag);
outl(PinSel0Save | (inl(PINSEL0) & (~0xfc00f)), PINSEL0);
outl(PinSel1Save | (inl(PINSEL1) & (~(0x3 << 10))), PINSEL1);
local_irq_restore(flag);
free_irqs();
}
return(0);
}
static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)
{
struct key_info *k;
int found = 0;
int up;
int flags;
k = &key_info_tab ;
if (k->irq_no == irq) {
found = 1;
}
if (!found) {
printk("bad irq %d in button\n", irq);
return;
}
save_flags(flags);
disable_irq(IRQ_EXT3);
up = read_gpio_bit(k->gpio_port);
outb(1<<3,EXTINT);
enable_irq(IRQ_EXT3);
restore_flags(flags);
if (up) {
key_value = k->key_no + 0x80;
} else {
key_value = k->key_no;
}
ready = 1;
wake_up_interruptible(&buttons_wait);
RunTime++;
}
int read_gpio_bit(unsigned int gpio_port)
{
volatile u32 *Reg;
u32 temp1;
Reg = (volatile u32 *)(GPIO_ADDR_BASE + GPIO_PORT_ADD * num);
temp1 = Reg[GPIO_PIN_OFFSET] & (1u << gpio_port);
if (temp1 != 0)
{
temp1 = GPIO_PIN_HIGH;
}
else
{
temp1 = GPIO_PIN_LOW;
}
return temp1;
}
static int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos)
{
static int key;
int flags;
int repeat;
if (!ready)
return -EAGAIN;
if (count != sizeof key_value)
return -EINVAL;
save_flags(flags);
if (key != key_value) {
key = key_value;
repeat = 0;
} else {
repeat = 1;
}
restore_flags(flags);
if (repeat) {
return -EAGAIN;
}
copy_to_user(buffer, &key, sizeof key);
ready = 0;
return sizeof key_value;
}
static unsigned int matrix4_buttons_select(
struct file *file,
struct poll_table_struct *wait)
{
if (ready)
return 1;
poll_wait(file, &buttons_wait, wait);
return 0;
}
static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd) {
default:
return -EINVAL;
}
}
static struct file_operations matrix4_buttons_fops = {
owner: THIS_MODULE,
ioctl: matrix4_buttons_ioctl,
poll: matrix4_buttons_select,
read: matrix4_buttons_read,
open: matrix4_buttons_open,
release:matrix4_buttons_release,
};
static int __init matrix4_buttons_init(void)
{
int ret;
ready = 0;
ret = register_chrdev(BUTTON_MAJOR, DEVICE_NAME, &matrix4_buttons_fops);
if (ret < 0) {
printk(DEVICE_NAME " CAN't register major number\n");
return ret;
}
printk("Init ok\n");
/*************************************
ret = request_irqs();
if (ret) {
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
printk(DEVICE_NAME " CAN't request irqs\n");
return ret;
}
***************************************/
return 0;
}
static void __exit matrix4_buttons_exit(void)
{
unregister_chrdev(BUTTON_MAJOR, DEVICE_NAME);
}
module_init(matrix4_buttons_init);
module_exit(matrix4_buttons_exit);
MODULE_LICENSE("GPL");
答 1: 奇怪怎么就没人回应呢 答 2: hihi.doya.问个问题,你是用仿真器下载的吗? 答 3: no我是在uclinux上用NFS下载到板子上然后用ismod加载的。
我不知道是不是能用EXTMODE=0X00来设置中断模式,应该如何清除中断。这些操作在uclinux下的接口是什么?希望大家教教我 答 4: 要注册中断要用request_irq()函数注册中断,还有,要注意中断的触发模式,是否与你要求的一致,可读相应寄存器的值出来看看对不对.看看<LINUX设备驱动程序>吧,中断那章有详细说明. 答 5: 写程序一个注释都没有~
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |