技术标签: 驱动 S3C2440 linux 嵌入式驱动开发 内核 JZ2440 嵌入式
模块名称:buttons_drv.c
开发环境:Ubuntu 16.04
编译环境:Linux 2.6.22.6
最后修改:2019.03.07
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>
static unsigned char key_val ;
static struct class *buttons_drv_class ;
static struct class_device *buttons_drv_dev ;
static volatile unsigned long *gpfcon ;
static volatile unsigned long *gpfdat ;
static volatile unsigned long *gpgcon ;
static volatile unsigned long *gpgdat ;
/* 等待队列:
* 当没有按键按下时,如果有应用程序调用buttons_drv_read()
* 它将休眠
*/
static DECLARE_WAIT_QUEUE_HEAD(button_wait);
/* 中断标记事件
* 中断服务程序将它置1
* buttons_drv_read()将它清除
*/
static volatile int ev_press = 0 ;
struct pin_desc {
unsigned char pin ;
unsigned char key_val ;
} ;
/* 按键描述结构体 引脚,按键值 */
static struct pin_desc pins_desc[4] = {
{S3C2410_GPF0, 0x01},
{S3C2410_GPF2, 0x02},
{S3C2410_GPG3, 0x03},
{S3C2410_GPG11, 0x04},
} ;
/* 按键中断处理函数 */
static irqreturn_t buttons_irq_handle(int irq, void *dev_id)
{
struct pin_desc *my_pin_desc = (struct pin_desc *)dev_id ;
unsigned int pin_val = 0 ;
/* 获取引脚电平值 */
pin_val = s3c2410_gpio_getpin(my_pin_desc->pin) ;
if(!pin_val)
{
key_val = my_pin_desc->key_val ;
}
else
{
key_val = my_pin_desc->key_val | 0x80 ;
}
ev_press = 1 ;
wake_up_interruptible(&button_wait) ;
return IRQ_HANDLED ;
}
/* 当应用程序open时,函数将向内核申请中断 */
static int buttons_drv_open(struct inode * inode, struct file * file)
{
/* 向内核请求外部中断 */
request_irq(IRQ_EINT0, buttons_irq_handle, IRQ_TYPE_EDGE_BOTH, "S2", &pins_desc[0]);
request_irq(IRQ_EINT2, buttons_irq_handle, IRQ_TYPE_EDGE_BOTH, "S3", &pins_desc[1]);
request_irq(IRQ_EINT11, buttons_irq_handle, IRQ_TYPE_EDGE_BOTH, "S4", &pins_desc[2]);
request_irq(IRQ_EINT19, buttons_irq_handle, IRQ_TYPE_EDGE_BOTH, "S5", &pins_desc[3]);
return 0 ;
}
/* 当应用程序read时,函数将按键值传到用户空间 */
static ssize_t buttons_drv_read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
{
if(bytes != 1)
return -EINVAL ;
wait_event_interruptible(button_wait, ev_press) ;
copy_to_user(userbuf, &key_val, 1) ;
ev_press = 0 ;
return 1 ;
}
static int buttons_drv_close(struct inode * inode, struct file * file)
{
/* 释放中断 */
free_irq(IRQ_EINT0, &pins_desc[0]) ;
free_irq(IRQ_EINT2, &pins_desc[1]) ;
free_irq(IRQ_EINT11, &pins_desc[2]) ;
free_irq(IRQ_EINT19, &pins_desc[3]) ;
return 0 ;
}
/* 驱动架构核心结构体 - file_operations */
static struct file_operations buttons_fops = {
.owner = THIS_MODULE,
.open = buttons_drv_open,
.read = buttons_drv_read,
.release = buttons_drv_close,
} ;
static int major = 0 ; //主设备号
/* 驱动入口函数 */
static int buttons_drv_init(void)
{
/* 注册字符设备 */
major = register_chrdev(0, "buttons_drv", &buttons_fops) ;
/* 自动创建设备节点 udev机制 */
buttons_drv_class = class_create(THIS_MODULE, "buttons_drv") ;
/* 创建设备节点 */
buttons_drv_dev = class_device_create(buttons_drv_class, NULL, MKDEV(major, 0), NULL, "buttons") ;
#if 0 //使用中断机制不需要映射虚拟地址
/* 虚拟地址映射 */
gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16) ;
gpfdat = gpfcon + 1 ;
gpgcon = (volatile unsigned long *)ioremap(0x56000060, 16) ;
gpgdat = gpgcon + 1 ;
#endif
return 0 ;
}
/* 驱动出口函数 */
static void buttons_drv_exit(void)
{
/* 卸载字符设备 */
unregister_chrdev(major, "buttons_drv") ;
/* 删除设备节点 */
class_device_unregister(buttons_drv_dev) ;
/* 销毁节点类 */
class_destroy(buttons_drv_class) ;
#if 0
/* 解除虚拟地址映射 */
iounmap(gpfcon) ;
iounmap(gpgcon) ;
#endif
return ;
}
/* 驱动入口:加载 */
module_init(buttons_drv_init) ;
/* 驱动出口:卸载 */
module_exit(buttons_drv_exit) ;
/* 许可 */
MODULE_LICENSE("GPL") ;
模块名称:buttons_test.c
开发环境:Ubuntu 16.04
编译环境:Linux 2.6.22.6
最后修改:2019.03.07
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main(int argv, char **argc)
{
int fd ;
unsigned char key_val ;
/* 以读写方式打开设备 */
fd = open("/dev/buttons", O_RDWR) ;
if(fd < 0)
{
printf("can't open!\n") ;
//return -1 ;
}
while(1)
{
/* 从驱动读取按键值到key_val */
read(fd, &key_val, 1) ;
/* 串口打印键值 */
printf("key_val = 0x%x\n", key_val) ;
}
}
模块对应于Python源代码文件多个功能相似的模块可以组织成一个包。Python中的模块包括系统模块、第三方模块和用户自定义模块。它们实质上是以.py为扩展名的Python文件通过导入模块,可以使用该模块中的变量、函数和类等。模块化程序设计的概念如果程序中包含多个可以复用的函数或类,则通常把相关的函数和类分组包含在单独的模块中。这些提供计算功能的模块称之为模块(或函数模块),导入并使...
【SpringBoot系列】SpringBoot注解详解一、注解(annotations)列表@SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中@ComponentScan让Spring Boot扫描到Configuration类...
2.4.1点睛Profile为在不同环境下使用不同的配置提供了支持(开发环境下的配置和生产环境下的配置肯定是不同的,例如,数据库的配置)。(1)通过设定Environment的 ActiveProfiles来设定当前context需要使用的配置环境。在开发中使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。(2)通过设定jvm的spring.profiles.ac...
每年的“双11”是阿里技术的大阅兵和创新能力的集中检阅。2016年的“双11”背后,更是蕴藏了异常丰富的技术实践与突破。 历经1个月的编写,最终27篇精华技术文章入册《不一样的技术创新-阿里巴巴2016双11背后的技术》(以下简称《不一样的技术创新》)一书。这27篇“24K纯度”的技术干货,是阿里“双11”八年来技术演进结果的最新展示,凝聚了阿里工程师...
20155333 《网络对抗》 Exp6 信息搜集与漏洞扫描基础问题哪些组织负责DNS,IP的管理?全球根服务器均由美国政府授权的ICANN统一管理,负责全球的域名根服务器、DNS和IP地址管理。全球根域名服务器:绝大多数在欧洲和北美(全球13台,用A~M编号),中国仅拥有镜像服务器(备份)。全球一共有5个地区性注册机构:ARIN主要负责北美地区业务,RIPE主要负责欧洲...
anyRTC提供全球领先的实时音视频云服务,客户涉及社交娱乐,金融保险,政企,安防等行业,累计帮助全球近千家企业客户获得音视频通讯能力。面对庞大客户音视频的需求,利用多中心化调度的服务架构,扛住了千万级的高并发,做到灵活调度,为广大客户带来优质的音视频体验。在客户请求量和流量暴增的情况下,我们的音视频服务无论何时都能做到零故障弹性的伸缩。我们的流媒体传输使用分层传输,而在这样的传输架构下,多中心化的调度服务的作用至关重要。单中心调度服务面临的问题和挑战:一、网络延时大。比如香港到西欧或者北美,物理距
3.1多了三个大包android.hardware.usb、android.mtp、 android.net.rtp !USB、mtp、rtp-------三个字眼,各个血淋淋,让人悲喜交加,Google你为何不早点发?android.mtp让连接的camera和其他设备,直接使用PTP(图像传输协议)的MTP(媒体传输协议)。...
有的时候需要对于一个Mysql数据库表添加个自动增长主键,刚开始的时候使用下面的语句:alter table taskinfoconfig add column id int(10) not null auto_increment ;alter table taskinfoconfig add primary key(id);可是在执行的时候发现报错,信息如下:In
ScalaAuthor: LijbEmail: [email protected]是一门多范式的编程语言,同时支持面向对象和面向函数编程风格。它以一种优雅的方式解决现实问题。虽然它是强静态类型的编程语言,但是它强大的类型推断能力,使其看起来就像是一个动态编程语言一样。Scala语...
以下只是一个最原始的方法,从执行效率的角度出发,如果一个场景里面同时包含了100个使用相同动画的sprit,每个 动画sprite都由下面的方法生成的话,有些代码:1.缓冲sprite帧和纹理;2.创建一个精灵节点;3.收集帧列表;这些个只需要执行一次的操作便被重复执行了 100次,浪费cpu,浪费电池电量。。所以说,还是存在相当大的优化空间。。。- (CCSp...
VB格式化小数,小数点后保留三位。一开始用Format(number, "0.000") 发现一个问题,有时小数点前面的0没有显示 解决的办法:改用FormatNumberFormatNumber(number, 3, vbTrue) 'vbTrue表示保留小数点前面的0 问题解决。...
第二次组会 10.26研究方向:知识表示学习两个重要的知识表示学习综述:知乎:1. KG笔记十、知识图谱嵌入(KG Embedding)https://zhuanlan.zhihu.com/p/3548671792. 刘知远大神《知识表示学习研究进展》的学习小结https://zhuanlan.zhihu.com/p/3561475383. 知识图谱最新权威综述论文解读:知识表示学习部分https://zhuanlan.zhihu.com/p/141396088下次讨论的论文:Interac