mini2440按键驱动分析

c++驱动级模拟按键 vs2013编写 用wring0 做的模拟按键 必须以管理员启动vs 才能正常使用 本来想做一个连发的 ..可是这个模拟按键也会被钩子识取 不知道 有谁能提供下思路不 立即下载
DECLARE_WAIT_QUEUE_HEAD(name) -- 生成一个等待队列头
DECLARE_WAIT_QUEUE_HEAD(name) -- 生成一个等待队列头wait_queue_head_t,名字为name
-----------------------------------------------------------------
#define DECLARE_WAIT_QUEUE_HEAD(name)                             /
     wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)

#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {                     /
     .lock        = __SPIN_LOCK_UNLOCKED(name.lock),                /
     .task_list = { &(name).task_list, &(name).task_list } }

typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
     spinlock_t lock;
     struct list_head task_list;
};


下面开始分析:
/*mini2440_buttons_my.c*/
/*后面加了_my*/

/*按键驱动程序*/

/*mini2440所用到的按键资源*/
/**************************************************/
/* 按键          对应的IO寄存器     对应的中断引脚*/
/* K1             GPG0                 EINT8      */
/* K2             GPG3                 EINT11     */
/* K3             GPG5                 EINT13     */
/* K4             GPG6                 EINT14     */
/* K5             GPG7                 EINT15     */
/* K6             GPG11                EINT19     */
/**************************************************/

/*要搞清楚谁是输入*/
/*在这里,按键控制对应的中断引脚,从而控制对应的IO寄存器*/
/*相当于信息从外面输入*/
/*我们要做的是根据对应的输入信息,来采取相应的响应动作*/
/*这就达到了中断响应的目的*/
/*其核心就是要检测*/
/*那么,该如何去检测呢?*/
/*通过什么来检测呢?*/

/*如何得知一个设备究竟用到哪些资源呢?*/
/*这是个非常重要的问题*/
/*我想应该看具体的电路原理图*/
/*只有看图,才能了解具体的电路连接情况*/
/*从而得知设备所需的硬件资源*/
/*厂商的原理图通常给的都比较详细*/

/*引用的头文件*/

#include <linux/module.h> /*模块有关的*/

#include <linux/kernel.h> /*内核有关的*/

#include <linux/fs.h> /*文件系统有关的*/

#include <linux/init.h> /*init*/

#include <linux/delay.h> /*delay*/

#include <linux/poll.h> /*poll*/

#include <asm/irq.h> /*中断*/

#include <linux/interrupt.h> /*linux中断*/

#include <asm/uaccess.h> /*uaccess*/

#include <asm/arch/regs-gpio.h> /*寄存器设置*/

#include <asm/hardware.h> /*hardware*/

/*定义宏*/

#define BUTTON_MAJOR 221 /*主设备号,本来是232,我改为221*/

#define DEVICE_NAME "buttons_my" /*设备名,本来是buttons,我加上了_my*/

/*定义按钮中断的描述结构体*/
/*由它把按钮中断的信息综合起来*/
/*各个成员表示什么意思?*/

struct button_irq_desc
{
int irq; /*中断号*/
/*中断号唯一表示一个中断*/

int pin; /*中断控制的寄存器*/
/*该寄存器的值由中断引脚设置*/
/*我们希望从该寄存器读出控制信息*/

int pin_setting; /*中断的引脚*/
/*该引脚的电平由按键来控制*/
/*从而最终我们由按键控制了寄存器的值*/

int number; /*编号*/
char *name; /*名称*/
};

/*指定6个按键的信息*/

static struct button_irq_desc button_irqs [] =
{
{IRQ_EINT8,S3C2410_GPG0,S3C2410_GPG0_EINT8,0,"KEY1"}, /*K1*/
{IRQ_EINT11,S3C2410_GPG3,S3C2410_GPG3_EINT11,1,"KEY2"}, /*K2*/
{IRQ_EINT13,S3C2410_GPG5,S3C2410_GPG5_EINT13,2,"KEY3"}, /*K3*/
{IRQ_EINT14,S3C2410_GPG6,S3C2410_GPG6_EINT14,3,"KEY4"}, /*K4*/
{IRQ_EINT15,S3C2410_GPG7,S3C2410_GPG7_EINT15,4,"KEY5"}, /*K5*/
{IRQ_EINT19,S3C2410_GPG11,S3C2410_GPG11_EINT19,5,"KEY6"}, /*K6*/
}

/*这样,资源就组织起来了*/
/*事实上,在这里我们不仅组织起了硬件资源*/
/*我们也把一定的软件资源也糅合进去了*/
/*像中断号*/


/*key_values数组*/
/*存放各个按键在发生中断情况下的值*/
/*volatile是什么意思呢?*/
/*这个数组是我们存放按键操作结果的,因此非常重要*/

static volatile int key_values [] = {0,0,0,0,0,0};


/*宏DECLARE_WAIT_QUEUE_HEAD(),是干什么的呢?*/
/*该宏应该是创建了一个等待队列*/
/*等待队列,是进程调度的一种重要方法*/
/*等待队列也很有意思,button_waitq,表示按键等待的队列*/
/*就是说,按键一按下,就会激活其等待队列里的进程,来做相应的处理*/
/*因此,按键的等待队列,或者说中断所设置的等待队列,*/
/*是中断处理中非常重要的资源,它大大扩展了中断处理的能力*/


static DECLARE_WAIT_QUEUE_HEAD(button_waitq); /*button_waitq是什么呢?*/
/*应该是等待队列的名称*/


/*key_values数组中是否有数据的标志,0表示无数据可读,1表示有数据可读*/

static volatile int ev_press = 0; /*初始为0*/

/*中断服务程序buttons_interrupt()的申明*/
/*即当检测到有中断时,就会执行该中断服务程序*/
/*那么如何检测到有中断发生呢?*/
/*并且中断发生了,知道发生了什么样的中断呢?*/
/*中断有很多种,该中断服务程序究竟该服务于哪一个中断呢?*/
/*显然,要把中断号与中断服务程序联结起来,构成一个整体*/
/*这个工作可以在open函数里做*/

/*参数irq---中断号*/
/*中断服务程序应该是与中断号一一对应的*/
/*对应于某个中断号的中断一发生,就会调用该中断号对应的服务程序*/
/*那么,检测中断的发生,就成了先决条件*/
/*参数dev_id ---具体是哪一个按钮*/

static irqreturn_t buttons_interrupt(int irq,void *dev_id);

/*mini2440_buttons_open()函数申明*/
/*驱动函数open调用的具体函数*/
/*由open函数具体实现硬件的初始化工作*/
/*以及软件的初始化工作*/
/*为我们的键盘设备的运行创造好环境*/

static int mini2440_buttons_open(struct inode *inode,struct file  *file);

/*mini2440_buttons_close()函数的申明*/
/*release调用的具体函数*/
/*设备软件环境的拆卸*/
/*具体就是中断的释放工作*/
/*因为中断资源,也是系统宝贵的资源,所以不用的时候,要释放*/

static int mini2440_buttons_close(struct inode *inode,struct file *file);

/*mini2440_buttons_read()函数的申明*/
/*read调用的具体函数*/
/*由它读取键盘输入的结果*/
/*实质上就是读取key_values数组的值*/
/*它完成了键盘作为输入设备的核心功能*/
/*数组是否可读,要根据标志位ev_press来判断*/
/*如果数组可读,则读取数据到用户buffer中*/
/*如果数组不可读,则进程进入等待队列,等待到数组可读为止*/
/*等待队列机制,是中断管理中常用到的机制*/
/*因为有些进程经常需要等待某一事件的发生*/

static int mini2440_buttons_read(struct file *filp,char __user  *buff,size_t count,loff_t *offp);
/*注意__user,指的是用户空间*/
/*即要把键盘的输入结果读取到用户空间去*/

/*mini2440_buttons_poll()函数的申明*/
/*poll调用的具体函数*/
/*poll实质上是select的调用函数*/
/*如果有按键数据,则select会立刻返回*/
/*如果没有按键数据,则等待*/
/*实质上这是键盘等待输入的机制*/

static unsigned int mini2440_buttons_poll(struct file *file,struct  poll_table_struct *wait);


/*file_operations结构体*/
/*驱动函数的设置*/
/*分别将前面的驱动函数设置进来*/

static struct file_operations mini2440_buttons_fops =
{
.owner = THIS_MODULE,

.open = mini2440_buttons_open, /*open()*/

.release = mini2440_buttons_close, /*release()*/

.read = mini2440_buttons_read, /*read()*/

.poll = mini2440_buttons_poll /*poll()*/
};

/*mini2440_buttons_init()函数的申明*/
/*module_init调用的具体函数*/
/*模块创建时的初始化函数*/
/*主要做的工作是注册设备和创建设备*/
/*而具体的硬件初始化工作,它可以不做*/
/*而把它留给fops里的函数来做*/

static int __init mini2440_buttons_init(void);

/*mini2440_buttons_exit()函数的申明*/
/*模块卸载时的扫尾工作*/
/*主要是设备的卸载工作*/

static void __exit mini2440_buttons_exit(void);

/*模块创建时的入口点*/

module_init(mini2440_buttons_init);


/*模块卸载时的入口点*/

module_exit(mini2440_buttons_exit);

/*驱动程序的一些信息*/

MODULE_AUTHOR("http://www.arm9.net"); /*驱动程序的作者*/

MODULE_DESCRIPTION("S3C2410/S3C2440 BUTTON Driver"); /*描述信息*/

MODULE_LICENSE("GPL"); /*遵循的协议*/

/********************************************************************/
/*********************下面是前面申明函数的实现***********************/
/********************************************************************/


/**********************mini2440_buttons_init()***********************/

static int __init mini2440_buttons_init(void)
{
int ret; /*设备注册的返回值*/

/*注册设备驱动程序*/
/*设备号,设备名,和驱动函数*/

ret =  register_chrdev(BUTTON_MAJOR,DEVICE_NAME,&mini2440_buttons_fops);

/*对注册失败的处理*/

if(ret < 0)
{
printk(DEVICE_NAME " can't register major number/n");
return ret;
}

/*创建设备*/
/*devfs_mk_cdev()函数是内核态的设备创建函数*/
/*而mknod是用户态的设备创建函数*/

devfs_mk_cdev(MKDEV(BUTTON_MAJOR,0),S_IFCHR | S_IRUSR | S_IWUSR |  S_IRGRP,DEVICE_NAME);

printk(DEVICE_NAME " initialized/n");

return 0;
}


/******************mini2440_buttons_exit()****************************/

static void __exit mini2440_buttons_exit(void)
{
/*移除设备*/

devfs_remove(DEVICE_NAME);

/*注消设备驱动*/

unregister_chrdev(BUTTON_MAJOR,DEVICE_NAME);
}


/*****************mini2440_buttons_open()******************************/

static int mini2440_buttons_open(struct inode *inode,struct file  *file)
{
int i;    /*循环变量,因为有6个按钮*/

int err; /*中断注册函数的返回值*/

/*对每个按钮分别处理,用for循环来做*/
/*具体地是要联结寄存器和相应的引脚*/
/*联结中断号和相应的中断服务程序*/
/*这一步类似于前面所说的驱动的注册*/
/*我们可以成功称作中断的注册*/

for(i = 0;i < sizeof(button_irqs)/sizeof(button_irqs[0]);i++)
{
/*寄存器与中断引脚的联结*/

   s3c2410_gpio_cfgpin(button_irqs[i].pin,button_irqs[i].pin_setting);

   /*中断的注册*/
/*request_irq()函数*/
/*要注意其输入参数*/
/*&button_irqs[i]是该中断享有的资源*/
/*会被传入buttons_interrupt,进行处理*/

   err =  request_irq(button_irqs[i].irq,buttons_interrupt,NULL,button_irqs[i].name,(void *)&button_irqs[i]);

   /*中断类型的设置*/
/*set_irq_type()函数*/
/*IRQT_BOTHEDGE的中断类型代表什么样的中断呢?*/

   /*有几个非常重要的问题*/
/*中断注册后,并设置好其中断类型之后,当有中断发生时,*/
/*即按下某个按钮时,系统能够自动检测到有中断发生吗?*/
/*检测到有中断发生,它能够自动辨别是几号中断吗?*/
/*知道了是几号中断,那么它能自动调用其中断服务程序吗?*/
/*对这几个问题的解答,够成了linux系统中断处理机制的核心*/

   set_irq_type(button_irqs[i].irq,IRQT_BOTHEDGE);

   /*注册失败的处理*/

   if(err)
break; /*跳出循环*/
}

/*若有一个按钮中断注册失败*/
/*则还需把前面注册成功的中断给拆了*/

if(err)
{
i--; /*回到前面一个按钮的处理*/

   for(;i >=0; i--) /*依此拆除*/
{
/*使中断不起作用*/

    disable_irq(button_irqs[i].irq);

    /*释放中断资源*/

    free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);
}

   return -EBUSY; /*中断注册没成功的最终的返回值*/
}

return 0; /*正常返回*/
}


/**************************buttons_interrupt()*****************************/
/*此中断服务程序,在每中断一次,就要对key_values数组设一下值*/
/*并对数组可读标志位ev_press设一下值*/
/*并唤醒在等待队列里的进程*/
/*这是中断处理经常要做的事情*/
/*在这里,等待队列button_waitq里经常等待的进程是数组的读取进程*/
/*就是说,读取进程在没有读到数据的时候就一直在等待,等待按键的输入*/
/*读取进程在等待,并不代表所有进程在等待,其它进程该干啥干啥去*/

static irqreturn_t buttons_interrupt(int irq,void *dev_id)
{
/*button_irq_desc结构体变量*/
/*对传入的资源进行处理*/

struct button_irq_desc *button_irqs = (struct button_irq_desc  *)dev_id;

/*获取寄存器的值*/
/*这一步至关重要*/
/*s3c2410_gpio_getpin()函数直接获取寄存器的值*/

/*要注意,按一下按钮,会发生两次中断*/

/*即按下是一次中断,放开又是一次中断*/

int up = s3c2410_gpio_getpin(button_irqs->pin);

/*通过电路原理图,可以知道没按下的时候,中断引脚应该是高电平*/
/*从而寄存器的值应该是1*/
/*变量取up也是有意义的,表示默认状态是弹起的状态*/
/*当按下按钮的状态下,寄存器的值就应该是0*/

/*下面对up的值进行处理*/
/*即是要把数据经过一定的变换存入key_values数组中*/

if(up)   /*如果是弹起的状态*/
/*那么就要在key_values数组的相应位存入很大的一个值*/
/*同时又要能从值里辨别出是哪个按键*/

   key_values[button_irqs->number] = (button_irqs->number + 1) + 0x80;
/*比如K1键开启的状态下,key_values[0]被置为(0+1)+0x80,即为129*/

else /*如果按键是闭合的状态*/
/*那么就要在key_values数组的相应位存入一个很小的数*/
/*同时又要能从值中辨别出是哪个键*/

   key_values[button_irqs->number] = (button_irqs->number +  1);
/*比如K1键闭合,则key_values[0]被置为(0+1),即为1*/

/*对数组可读标志位进行设置*/

ev_press = 1; /*表示数组已经可读了*/

/*唤醒休眠的进程?*/
/*button_waitq队列里存放有相应的处理进程*/
/*如读取数组的值的进程*/
/*要注意wake_up_interruptible()这些函数的用法*/

wake_up_interruptible(&button_waitq);

/*返回*/

return IRQ_RETVAL(IRQ_HANDLED); /*?*/
}

/**********************mini2440_buttons_close()*****************************/

static int mini2440_buttons_close(struct inode *inode,struct file  *file)
{
int i; /*循环变量,要操作好几个按键*/

/*for循环,对各个按键依此释放中断*/

for(i = 0;i < sizeof(button_irqs)/sizeof(button_irqs[0]);i++)
{
/*使中断失效*/

   disable_irq(button_irqs[i].irq);

   /*释放资源*/

   free_irq(button_irqs[i].irq,(void *)&button_irqs[i]);
}

/*返回*/

return 0;
}


/**********************mini2440_buttons_read()***************************/

/*要注意,该read函数,只读取一次中断的值,而不是连续地读入*/
/*要做到连续地读入,则需要做一个循环,不断地调用该read函数,但那不是驱动程序里该做的事情*/

static int mini2440_buttons_read(struct file *filp,char __user  *buff,size_t count,loff_t *offp)
{
unsigned long err;   /*copy_to_user()函数的返回值*/

/*如果key_values 数组里没有值,则会此进程会休眠*/
/*一直到中断来临之后,中断服务程序会唤醒此休眠进程从而继续读取值*/
/*key_values数组里有没有值,是靠ev_press标志位来判断的*/
/*有值,就是1,无值,就是0*/

/*进程等待队列的机制,是进程调度的一种方法*/

if(!ev_press) /*标志位为0,即无数据时*/
{
if(filp->f_flags & O_NONBLOCK) /*??*/
return -EAGAIN;
else /*进程休眠,放进button_waitq等待队列*/
/*这里,把ev_press标志位设成了休眠进程的标志位了?*/
/*这是为了便于利用poll_wait函数*/
/*也就是利于select函数*/
wait_event_interruptible(button_waitq,ev_press);
/*在中断处理函数中,此进程会被唤醒*/
/*唤醒前,ev_press 已被置1了*/
/*唤醒后的执行点从这里开始*/
}

/*下面就是标志位为1,即有数据可读的的处理情况*/

/*那就开始往用户空间读数据呗*/

err = copy_to_user(buff,(const void  *)key_values,min(sizeof(key_values),count));
/*copy_to_user()函数的使用*/

/*对key_values数组清零*/

memset((void *)key_values,0,sizeof(key_values));

/*对标志位置0*/
/*表示读取过了*/

ev_press = 0;

/*对err的处理*/

if(err) /*读取错误*/
return -EFAULT;
else /*读取正确*/
/*则返回读取到的字节数*/
return min(sizeof(key_values),count);
}

/************************mini2440_buttons_poll()***********************/

static unsigned int mini2440_buttons_poll(struct file *file,struct  poll_table_struct *wait)
{
unsigned int mask = 0; /* */

/*poll_wait()函数*/
/*会监测进程队列button_waitq里的进程*/
/*例如,如果mini2440_button_read所在的进程的标志位ev_press置为1了*/
/*那么就不会再等待了*/
/*这实质上就是select函数的运行机制*/

poll_wait(file,&button_waitq,wait);

if(ev_press)
mask |= POLLIN | POLLRDNORM; /*??*/

return mask;
}

==================================================================================

下面是测试代码:
/*按键测试程序*/

#include <stdio.h> /*标准输入输出头文件*/

#include <stdlib.h> /*标准库*/

#include <unistd.h> /*一些宏的定义在这里*/

#include <sys/ioctl.h> /*设备的控制*/

#include <sys/types.h> /*定义了一些类型*/

#include <sys/stat.h> /*状态*/

#include <fcntl.h> /*文件控制*/

#include <sys/select.h> /*选择?*/

#include <sys/time.h> /*时间方面的函数*/

#include <errno.h> /*有关错误方面的宏*/

/*主函数入口*/

int main(void)
{
int i; /*键盘输出时用到的循环变量*/

int buttons_fd; /*buttons设备号*/

int key_value[4]; /*四个按键的取值*/

/*打开键盘设备文件*/

buttons_fd = open("/dev/buttons",0); /*以0方式打开*/

/*打开出错处理*/

if(buttons_fd < 0) /*打开出错就会返回一个负值*/
{
perror("open device buttons"); /*perror函数?*/

   exit(1); /*返回1*/
}

/*for无限循环,等待用户输入*/
/*这是很典型的程序执行方式*/

for(;;)
{
fd_set rds; /*fd_set是types.h中定义的类型,实质上是int型*/
/*rds用来存储设备号*/

   int ret; /*for循环内定义的局部变量ret*/

   FD_ZERO(&rds); /*rds初始化*/
/*FD_ZERO是哪里定义的呢?*/

   FD_SET(buttons_fd,&rds); /*将buttons设备号赋给rds*/
/*FD_SET是哪里定义的呢?*/

   /*使用系统调用select检查是否能够从/dev/buttons设备读取数据*/
/*select函数是干什么的呢?*/

   ret = select(buttons_fd + 1,&rds,NULL,NULL,NULL);
/*返回值ret*/
/*返回值的具体意义是什么呢?*/

   /*对ret的处理*/

   if(ret < 0) /*当ret小于0*/
{
perror("select");
exit(1);
}   

   if(ret == 0) /*当ret等于0*/
{
printf("Timeout./n");
}
else /*能够读到数据*/
if(FD_ISSET(buttons_fd,&rds)) /*??*/
{
/*读取键盘驱动发出的数据*/
/*key_value和键盘驱动中定义一致*/

     int ret = read(buttons_fd,key_value,sizeof(key_value));  /*注意此处的ret和前面的ret有何不同*/
/*注意键盘设备读取的特点*/

     /*对ret的处理*/
if(ret != sizeof(key_value)) /*没有接收够*/
{
if(errno != EAGAIN)   /*???*/
perror("read buttons/n");
continue;
}
else /*正确接收,则打印到标准终端*/
{
for(i = 0;i < 4;i++) /*最开始定义的循环变量i*/
printf("K%d %s, key value = 0x%02x/n",i,(key_value[i] & 0x80) ?  "released" : key_value[i] ? "pressed down" : "",key_value[i]);
/*这一连串的输出,要注意格式*/
}
}
}

/*关闭设备*/

close(buttons_fd);

return 0; /*主函数返回*/
}
USB键盘驱动(C++) 可以修改下。得到很多启发。可以看下怎么工作的。 立即下载

相关推荐

虚拟键盘驱动

虚拟键盘驱动,驱动级模拟键盘按键,没有物理键盘时也可以使用

转:一个相当详细的MINI2440按键驱动详解

/*mini2440_buttons_my.c*//*后面加了_my*//*按键驱动程序*//*mini2440所用到的按键资源*//**************************************************//* 按键          对应的IO寄存器     对应的中断引脚*//* K1             GPG0                 EI

yrqing718的专栏 857

mini2440按键驱动及测试程序

mini2440的按键驱动, 展示了input子系统和platform driver的编写方法, 浓缩了kernel自带的gpio-keys驱动, 更清楚得展示驱动的编写过程, 并附带了测试程序, 最适合学习是借鉴。 测试信息: Type is 1, code is 59, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 59, value is 0. Type is 0, code is 0, value is 0. Type is 1, code is 60, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 60, value is 0. Type is 0, code is 0, value is 0. Type is 1, code is 61, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 61, value is 0. Type is 0, code is 0, value is 0. Type is 1, code is 63, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 63, value is 0. Type is 0, code is 0, value is 0. Type is 1, code is 116, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 116, value is 0. Type is 0, code is 0, value is 0. Type is 1, code is 64, value is 1. Type is 0, code is 0, value is 0. Type is 1, code is 64, value is 0. Type is 0, code is 0, value is 0.

mini2440按键驱动程序分析

先说明一下按键与S3C2440芯片的连接方式: KEY1 <----> EINT8 <----> GPG0 KEY2 <----> EINT11 <----> GPG3 KEY3 <----> EINT13 <----> GPG5 KEY4 <----> EINT14 <----> GPG6 KEY5 ...

Yfw的博客 283

描边盛开火玫瑰

python描边盛开火玫瑰 代码如下 import turtle as t t.setup(800,800) t.hideturtle() t.speed(11) t.penup() t.goto(50,-450) t.pensize(5) t.pencolor("black") t.seth(140) t.pendown() t.speed(10) t.circle(-300,60) t.fd(100) #jiaodu80 #1ye t.seth(10) t.fd(50) t.fillcolor("gr

weixin_50973371的博客 2062

别再只用GPS了!用Android手机传感器实现室内步行轨迹记录(避坑指南)

本文详细介绍了如何利用Android手机传感器(如加速度计、陀螺仪和磁力计)实现室内步行轨迹记录,克服GPS在室内的局限性。通过传感器数据采集、步态检测、航向估计和轨迹绘制等步骤,结合避坑指南和优化技巧,帮助开发者高效构建室内定位应用。

weixin_26821003的博客 274

mini2440按键驱动及详细解释(转)

mini2440按键驱动及详细解释(转) 经过为期一周左右的时间,参考《linux设备驱动开发详解》把mini2440开发板的按键驱动完成了。   程序可以分成两部分来看: 第一部分:按键侦测,主要包括中断的初始化、中断处理、按键去抖、等待按键松开,侦测 完成返回按键键值。 第二部分:按键事件处理,主要包括,将案件事件保存至循环链表(其实就是一个数组,可 以循环保存数据)、将

shangyaowei的专栏 544

【Godot】实现对话系统

在 Godot 中实现对话系统(Dialogue System)是游戏开发中的常见需求。Godot本身自带的的灵活性和轻量级脚本语言 GDScript 使得实现对话系统变得相对简单。以下是实现一个基础对话系统的示例。(语言为GDScript但高亮选择Python因为类似)通过 Godot 和 GDScript,我们可以给我们的游戏实现一个对话系统。从简单的文本显示到复杂的分支对话,Godot 提供了足够的灵活性来满足我们的需求。如果需要更高级的功能,可以尝试使用现成的插件如 Dialogic。

Octopus2077的博客 2519

RTD2660H/RTD2668驱动板实战:从选板到OSD only排查

显示器驱动板是连接信号源与液晶屏的核心部件,其工作原理涉及信号解码、缩放引擎和LVDS输出。理解这些基础概念,对DIY改屏和显示器维修至关重要。RTD2660H和RTD2668是经典的驱动板方案,广泛应用于显示器、电视和广告机中。掌握这类板卡的选型要点、硬件信号链路、屏参烧录流程及OSD菜单调校,能大幅提升改装成功率。在实际使用中,常会遇到屏幕只能显示OSD菜单而无法显示画面的情况,即“OSD only”状态。本文以工程实践视角,系统梳理从电源树到LVDS链路的排查方法,并结合按键板、固件、EDID等细节,

weixin_33895516的博客 222

2021-10-29 atcoder ABC157——B - Bingo

B - Bingo 先标记,然后暴力判断,这样最清晰最好想。 #include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; int a[110][110],b[110]; int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>a[i]

honeistbutter的博客 337

Opencv计算相机响应函数(Camera Response Function)与Radiance

本文主要用于记录自己在学习CRF过程中遇到的一些问题。 CRF模型 I=f(V(t⋅L))I=f(V( t\cdot L))I=f(V(t⋅L)) 其中III为相机灰度值Intensity,LLL为环境中irradiance,ttt为曝光时间,VVV为相机镜头参数,fff为相机响应函数CRF。 有些论文中认为相机镜头参数是线性的不考虑,但有些考虑了衰减即靠近图像边缘亮度会暗一些,但没有看到二者同时计算的,如果同时计算两个非线性的函数,我觉得可能会有不确定性,在这里还请教一下了解的朋友。 控制

larrydong的博客 5999

基于mini2440的按键驱动分析与总结

编写按键驱动的方法很多,这里我仅仅列举用中断法加上简单地字符设备注册来编写,并没有采用misc设备来注册。(这里的注册函数都是相对古老,以后不推荐使用!)首先编写一个设备驱动程序头文件先定义了,这很容易,照搬别人的就行了。接着确定你的设备驱动程序会用到的数据结构,这里会用到一个重要的数据结构,struct button_irqs,用来表征按键的状态以及按键的标识。接着确定file_operatio

嵌入式世界的专栏 800

初学者入门YOLO目标检测:从懵圈到上手,这篇文章讲透所有核心(附学习路径+避坑指南)

目标:比如训练一个“检测苹果和橘子”的模型,或者“检测人脸”的模型;任务:学会用LabelImg标注数据,制作YOLO格式的数据集,用命令行训练模型;关键:不用追求高精度,能训练出一个能检测出目标的模型就行。很多初学者卡在入门阶段,不是因为智商不够,而是因为“想太多,做太少”——总觉得要把所有原理搞懂才能动手,结果越想越怕,最后放弃。先动手,再动脑。先跑通一个案例,获得成就感;再制作自定义数据集,训练简单模型;最后再回头去理解原理,优化模型。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 688

mini2440按键驱动分析(转载)

DECLARE_WAIT_QUEUE_HEAD(name) -- 生成一个等待队列头DECLARE_WAIT_QUEUE_HEAD(name) -- 生成一个等待队列头wait_queue_head_t,名字为name ----------------------------------------------------------------- #define DECLARE_WAIT_QUEUE_HEAD (name)                           

Hacktao的专栏 1137

第六天 界面操作及美化(6.4 使用GUI 套件)

本文介绍如何使用VIPM工具安装DMC GUI套件:首先打开VIPM并连接网络,搜索"UI"找到DMCGUI套件后下载安装;安装完成后即可在VIPM中添加控件并预览效果。该方法同样适用于下载其他UI套件,用户可根据需求设计个性化界面。整个流程包括搜索、下载、安装和使用四个简单步骤,适合快速搭建GUI界面。

weixin_38637405的博客 407

Android功耗系列专题理论之一:功耗优化分析思路简介

本文系统介绍了电子系统功耗分析方法,涵盖静态与动态功耗原理、电流波形分析技术和模块化拆解策略。重点阐述了PMIC与CPU协同管理机制、DVFS动态调节技术,以及通过示波器捕获波形特征定位异常的方法。针对亮屏等典型场景,提出三阶段对比分析法,并详细说明硬件/软件拆解方案及混合验证策略。文章还总结了常见问题模块(CPU、多媒体、外设)的排查流程,强调需结合日志分析、温度控制及重复测试确保数据可靠性,为功耗优化提供系统化解决方案。

1459

学习笔记 --- MINI2440 linux按键驱动代码分析

分析MINI2440按键驱动代码: #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DE

忧郁天蝎 971

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

MINI2440 按键输入子系统 驱动及测试代码分析

按键输入子系统驱动: #include #include #include #include #include #include /* for -EBUSY */ #include /* for request_region */ #include

RopenYuan的专栏 5867

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

基于platform驱动模型-mini2440按键驱动(完美支持防抖动)

一、开发环境 主  机:ubuntu10.04 开发板:Mini2440--256MB Nand, Kernel:2.6.32.2 编译器:arm-linux-gcc-4.3.2 二、实现步骤 1. 硬件原理图分析。由原理图可知每个按键所用到的外部中断分别是EINT8、EINT11、EINT13、EINT14、EINT15、EINT19,所对应的IO口分别是GPG

hktkfly6的专栏 858

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

linux 内核按键抖动,嵌入式Linux之我行——按键驱动在2440上的实例开发(带去抖动)...

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。一、开发环境主 机:VMWare--Fedora 9开发板:Mini2440--64MB Nand, Kernel:2.6.30.4编译器:arm-linux-gcc-4.3.2二、实现步骤1. 硬件原理图分析。由原理图可知每个按键...

weixin_33737110的博客 309

LED控制按键实验

基于ARM9开发板mini2440原理图,分析LED、按键、蜂鸣器硬件连接情况,结合设备驱动相关知识,实现了按键控制流水灯、蜂鸣器设备,编写相应的驱动程序,实现一定的功能。 本文是我实现的其中的一个功能:其中一个按键驱动LED亮,一个按键驱动LED全灭。 一、实验分析 由下面两图可以看出每个按键所用到的外部中断分别是EINT8、EINT11、EINT13、EINT14、EINT15、EINT19,所对应的IO口分别是GPG0、GPG3、GPG5、GPG6、GPG7、GPG11。按键对应的CPU管脚GPF0-

weixin_45590050的博客 2056

Linux设备驱动开发基础---字符设备驱动程序开发之基于中断的按键驱动

二、硬件原理分析 Mini2440 具有6 个用户测试按键,它们都是连接到CPU 的中断引脚。如图: 由原理图可知,这些引脚在按键没有按下的情况下被上拉为高电平,按键被按下的时候变为低电平。 三、实现方式 1、在/linux-2.6.32.2/drivers/buttons目录下创建一个新的驱动程序文件mini2440_buttons.c,内容及详细注释如下: #include

DreamCatcher100的专栏 1279

linux驱动移植-输入子系统设备驱动

在上一节我们介绍了linux系统的输入子系统的基本框架,并进行了源码分析。 这一节我们将尝试向input子系统注册设备驱动,这里我们编写按键驱动,通过MIni2440上的6个按键来模拟键盘中的A、B、C、D、E、F。 一、按键硬件资源 1.1 硬件接线 查看Mini2440原理图、S3C2440数据手册,了解如何读取按键的状态。这里粗略介绍一下Mini2440 K1~K6的接线方式,以及寄存器的...

Graceful_scenery的博客 125

wince 5.0 按键驱动问题 (mini2440的5.0的bsp包) ---关于KEY3 KEY4 KEY5 不能用 解决方法

  wince 5.0 按键驱动问题 (mini2440的5.0的bsp包) ---关于KEY3 KEY4 KEY5 不能用 解决方法//==================================//lyx_wq//layueliuhuo@163.com//=================================在C:/WINCE500/PLATFORM/mini2440/Sr

636
上一篇: NAND_flash与NOR_flash
下一篇: 基于mini2440的mp3播放器
zhouxf_cn
博客等级 码龄14年 54粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值