关于按键,在DVK521上为:
我又从一份数据手册中看到,PI7,PI8,PI9是没有外部中断功能的。如下图所示:
还好,目前的按键是通过短接帽来连接PI7 PI9的,那么可以将短接帽拿掉,使用杜邦线连接PI10 PI12。
现在我将Key2连接到PI10上。那么KEY2的中断引脚为EINT22。
配置sys_config.fex文件:
现在使用的树莓派A20,是一个双核A7的芯片,而这个属于SMP架构,中断处理方式也已经和原先的理念大有不同。所以还是要知道关于linux的中断原理,可以从网络中获取相关历史性技术知识。
从A20的数据手册中,可以看到外部中断数到了EINT31。也就是说PIO中断功能有32个。
下面列出的API函数是在 \linux-sunxi\arch\arm\plat-sunxi\Sys_config.c中。
1.gpio_request_ex(),获取sys_config.fex中设置的中断IO口。
2.gpio_set_one_pin_io_status(),设置为输入状态。
3.gpio_set_one_pin_pull(),设置输入引脚的上下拉状态。
4.request_irq()注册中断函数。
request_irq()函数:
第一个参数为SW_INT_IRQNO_PIO,表示是外部并尺端口的中断号。
第二个参数为中断处理函数名。
第三个参数为中断方式,如IRQ_TYPE_EDGE_RISING,上升沿触发,而IRQ_TYPE_EDGE_FALLING则是下降沿触发,IRQF_SHARED为共享。
第四个参数为中断名。
第五个参数为中断传递的数据。
1.获取IO中断源信息
由于内核使用的是虚拟地址寻址硬件地址,获取中断源就需要将IO硬件地址空间映射到虚拟地址上。可以使用ioremap(PIO_BASE_ADDRESS, PIO_RANGE_SIZE)进行映射。
2.屏蔽中断源
a.读取中断源寄存器的状态,可以使用readl(映射的IO地址 + PIO_INT_STAT_OFFSET)
b.判断对应的中断,使用writel(reg_val&(1<<(CTP_IRQ_NO)),映射的IO地址 + PIO_INT_STAT_OFFSET)清除状态位。
写到这里,本应该很顺利,可是,在驱动程序加载进内核的时候,明显是报错。错误我就不贴出来了,可是我可以将中断信息附上:
从这里,可以看出来,PIO中断号60已经注册进内核了。我们现在使用的一个IO中断是被包含在里面的。所以,需要在内核中找到sunxi-gpio是怎么去注册中断,而我们就需绝兆高要将我们的中断程序内容附加到已经注册的中断上去。
在 marsboard\marsboard-a20-linux-sdk-v1.2\linux-sunxi\drivers\gpio\Gpio-sunxi.c中我们可以找到函数:
里面最重要的函数是:
最终调用的是:
然而,它又被赋值了:
在一定程度的意义上,gpio-sunxi.c已经猜御将中断基本处理做好了,我们要做的只是和它共享中断。
sys_config.fex文件配置如下:
从上面的实验中,已经发现在request_irq中设置边沿等等触发,在安装ko文件的时候,都会报错,从这里看出,在共享中断的时候,是不允许设置其他的内容的。那么,只能去找A20寄存器中关于io口中断的设置。在这些设置已经设置好的情况下,中断应该就能响应了。这里贴出一个比较简单的驱动程序:
int main(int argc,char *argv[])
{
int fd
int val
fd = open("/dev/key_device",O_RDWR)
if(fd <0){
printf("---open file error----\r\n")
return -1
}
}
ifeq ($(KERNELRELEASE),)
KERNEL_DIR=/home/wityuan/Downloads/MarsBoard-A20-Linux-SDK-V1.2/linux-sunxi
PWD=$(shell pwd)
modules:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
arm-linux-gnueabihf-gcc -o key key.c
modules_install:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
clean:
rm -rf *.ko *.o .tmp_versions .mod.c modules.order Module.symvers . .cmd
else
obj-m:=key.o
endif
root@marsboard:~# ./key_test
---script.bin key get ok,value:1----
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
key irq Interrupt
==IRQ_EINT22=
^Ckey irq Interrupt
Other Interrupt
----key close----
root@marsboard:~#
root@marsboard:~#
/* EINT type PIO controller registers */
/* EINT type defines */
static int int_cfg_addr[] = {PIO_INT_CFG0_OFFSET,
PIO_INT_CFG1_OFFSET,
PIO_INT_CFG2_OFFSET,
PIO_INT_CFG3_OFFSET}
/* Setup GPIO irq mode (FALLING, RISING, BOTH, etc */
})
/* Enable GPIO interrupt for pin */
})
/* Disable GPIO interrupt for pin */
})
/* Set GPIO pin mode (input, output, etc) /
/ GPIO port has 4 cfg 32bit registers (8 pins each) /
/ First port cfg register addr = port_num * 0x24*/
})
static script_gpio_set_t info
static unsigned key_handler1
static unsigned key_handler2
static struct class *key_class
static struct device *key_device
static unsigned int key_major
static unsigned int key_value
static void *__iomem gpio_addr = NULL
static int key_open(struct inode *inode, struct file *filp)
static ssize_t key_read (struct file *, char __user *, size_t, loff_t *)
static ssize_t key_write (struct file *filp, const char __user *buf, size_t len, loff_t *off)
static int key_close(struct inode *inode, struct file *filp)
struct file_operations key_operations = {
.owner = THIS_MODULE,
.open= key_open,
.read= key_read,
.write = key_write,
.release = key_close,
}
struct key_str{
char *name
int val
}
struct key_str g_key_str[2]={{"key1",0x1},{"key2",2}}
static irqreturn_t key_irq_handler1(int irq, void *dev_id)
{
int err
int reg_val = 0
int ret_val = 0
}
static irqreturn_t key_irq_handler2(int irq, void *dev_id)
{
}
static ssize_t key_read (struct file *file, char __user *buf, size_t len, loff_t *off)
{
unsigned int value = 0
value = copy_to_user(buf,&key_value,4)
}
static int key_open(struct inode *inode, struct file *filp)
{
int err = 0
int key_test_enabled = 0
int ret = 0
}
static ssize_t key_write (struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
}
static int key_close(struct inode *inode, struct file *filp)
{
SUNXI_MASK_GPIO_IRQ(gpio_addr,IRQ_EINT22)
SUNXI_MASK_GPIO_IRQ(gpio_addr,IRQ_EINT23)
}
static int __init key_init(void)
{
key_major = register_chrdev(0, "key_chrdev", &key_operations)
}
static void __exit key_exit(void)
{
if (gpio_addr) {
iounmap(gpio_addr)
}
}
module_init(key_init)
module_exit(key_exit)
MODULE_DESCRIPTION("Driver for key")
MODULE_AUTHOR("wit_yuan")
MODULE_LICENSE("GPL")
ifeq ($(KERNELRELEASE),)
KERNEL_DIR=/home/wityuan/Downloads/MarsBoard-A20-Linux-SDK-V1.2/linux-sunxi
PWD=$(shell pwd)
modules:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
arm-linux-gnueabihf-gcc -o key key.c
modules_install:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
clean:
rm -rf *.ko *.o .tmp_versions .mod.c modules.order Module.symvers . .cmd
else
obj-m:=key.o
endif
int main(int argc,char *argv[])
{
int fd
int val
fd = open("/dev/key_device",O_RDWR)
if(fd <0){
printf("---open file error----\r\n")
return -1
}
}
/* EINT type PIO controller registers */
/* EINT type defines */
static wait_queue_head_tkey_data_avail
static unsigned int key_done = 0
static int int_cfg_addr[] = {PIO_INT_CFG0_OFFSET,
PIO_INT_CFG1_OFFSET,
PIO_INT_CFG2_OFFSET,
PIO_INT_CFG3_OFFSET}
/* Setup GPIO irq mode (FALLING, RISING, BOTH, etc */
})
/* Enable GPIO interrupt for pin */
})
/* Disable GPIO interrupt for pin */
})
/* Set GPIO pin mode (input, output, etc) /
/ GPIO port has 4 cfg 32bit registers (8 pins each) /
/ First port cfg register addr = port_num * 0x24*/
})
static script_gpio_set_t info
static unsigned key_handler1
static unsigned key_handler2
static struct class *key_class
static struct device *key_device
static unsigned int key_major
static unsigned int key_value
static void *__iomem gpio_addr = NULL
static int key_open(struct inode *inode, struct file *filp)
static ssize_t key_read (struct file *, char __user *, size_t, loff_t *)
static ssize_t key_write (struct file *filp, const char __user *buf, size_t len, loff_t *off)
static int key_close(struct inode *inode, struct file *filp)
struct file_operations key_operations = {
.owner = THIS_MODULE,
.open= key_open,
.read= key_read,
.write = key_write,
.release = key_close,
}
struct key_str{
char *name
int val
}
struct key_str g_key_str[2]={{"key1",0x1},{"key2",2}}
static irqreturn_t key_irq_handler1(int irq, void *dev_id)
{
int err
int reg_val = 0
int ret_val = 0
}
static irqreturn_t key_irq_handler2(int irq, void *dev_id)
{
}
static ssize_t key_read (struct file *file, char __user *buf, size_t len, loff_t *off)
{
unsigned int value = 0
}
static int key_open(struct inode *inode, struct file *filp)
{
int err = 0
int key_test_enabled = 0
int ret = 0
}
static ssize_t key_write (struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
}
static int key_close(struct inode *inode, struct file *filp)
{
SUNXI_MASK_GPIO_IRQ(gpio_addr,IRQ_EINT22)
SUNXI_MASK_GPIO_IRQ(gpio_addr,IRQ_EINT23)
}
static int __init key_test_init(void)
{
key_major = register_chrdev(0, "key_chrdev", &key_operations)
}
static void __exit key_test_exit(void)
{
if (gpio_addr) {
iounmap(gpio_addr)
}
}
module_init(key_test_init)
module_exit(key_test_exit)
MODULE_DESCRIPTION("Driver for key")
MODULE_AUTHOR("wit_yuan")
MODULE_LICENSE("GPL")
ifeq ($(KERNELRELEASE),)
KERNEL_DIR=/home/wityuan/Downloads/MarsBoard-A20-Linux-SDK-V1.2/linux-sunxi
PWD=$(shell pwd)
modules:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
arm-linux-gnueabihf-gcc -o key key.c
modules_install:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules_install
clean:
rm -rf *.ko *.o .tmp_versions .mod.c modules.order Module.symvers . .cmd
else
obj-m:=key.o
endif
int main(int argc,char *argv[])
{
int fd
int val
fd = open("/dev/key_device",O_RDWR)
if(fd <0){
printf("---open file error----\r\n")
return -1
}
}
看这个图文教程http://jingyan.baidu.com/article/6c67b1d69365b72787bb1e34.html
首先打开Qtcreator。
点击new 新建一个行誉qt应用程序。
输入名称。
选择embedded 。
提示要设置options。
添加编译路径如下图。
点击next,如图。
点击finish,则建好了一个工程。
点击图中的ui部分。
将控件点击拖到界面上。
为或型按键控件添加槽。
选择第一个,点击确定。
然后再button的回调函数中写上ui->label->setText("helloworld")
保存,然后点击菜单栏的build,点第一个build选项。
保存的工程路径下找到可执行文档团段件,点击执行。
大功告成!
树莓派使用python编程。树莓派项目的一个核心思想就是Python编程语言的使用。Python允许树莓派的拥有者将项目扩展到令人难以置信的规模。树莓派是一个非派银常廉价的、只有手掌大小的完全可编程的计算机。虽然树莓派的体积小,但是它的潜力无限。你可以像使用常规台式计算机一样在树莓派上创建一个非常酷的工程。例如,你可以用树莓派搭建你自己的家用云存储服务器。
树莓派用python来进行编程。树莓派项目的一个核心思想是Python编程语言的使源数用。Python允许树莓派的拥有雹羡首者将项目扩展到令人难以置信的规模。
Python是一个解释型的面向对象的、跨平台的编程语言。良好的可靠性、清晰的语法和易用性,使它成为最流行的编程语言之一。Python是一个优雅的、功能强大的语言。
树莓派为Python编程提供了一个便宜到令人难以置信的开发平台。Python被认为是一种“教学”语言,是因为它很容易学习,但绝不表示Python羸弱。
有了树莓派和Python,唯一限制你的就是想象力了。你可以用Python编写游戏并将其运行在树莓派控制的游戏机上。你可以编写程序来控制连接到树莓派上的机器人。或者你可以像Dave Akerman一样将你的树莓派发送到39000千米的地球上空拍摄令人难以置信的照片
推荐课程:数据挖掘基础(黑马程序员)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)