at91sam9260中断驱动

AT91SAM7S64入门笔记----中断实验(3) <br />        刚刚调了AT91SAM7S64的外部中断,其实只要掌握中断的基本原理,不同中断的处理都是同样的道理,在这个实验中对FIQ,IRQ0,IRQ1进行调试,通过LED来显示程序执行情况.<br />   <br />         以下代码我已经在AT91SAM7S64最小系统板调试通过.<br />//功能:外部中断测试 //作者:czleclub #include<at91sam7s64.h> #include "Mini_Board.h" #include "del 阅读详情
这个驱动中的程序,用到了按键中断、防抖动的定时器功能、队列等知识

一、各部分理解
1、定时器:

    // 初始化定时器,实现软件的去抖动
     /* 初始化定时器 */
    for(i = 0; i < KEY_NUM; i++)
    {        
        key_timer[i].function=key_timer_handler;     //定时器到时间后执行的函数
            key_timer[i].data=i;                 //data的值
        init_timer(&key_timer[i]);           //初始化
        printk("key_timer[i].data is %x ,i is %x ,KEY_NUM is %x \n", key_timer[i].data,i,KEY_NUM);  
    }
    at91sam9260_key_io_init();   // 初始化IO口  

// 定时器处理函数
static void key_timer_handler(unsigned long data)
{
    int key = data;
    //获取当前按键引脚上的电平值来判断按键是按下还是抬起
    int up = at91_get_gpio_value(key_info_tab[key].gpio_port);
    if (!up)
    {
        if (key_dev.keyStatus[key] == KEYSTATUS_DOWNX)          //按键不确定
        {
    //printk("+++key_dev.keyStatus[%d] == KEYSTATUS_DOWNX\n",key);
            key_dev.keyStatus[key] = KEYSTATUS_DOWN;
            key_timer[key].expires = jiffies + KEY_TIMER_DELAY2; //延迟           
            keyEvent(key);  //记录键值,唤醒等待队列
            add_timer(&key_timer[key]);
        }
        else                                                    //按键按下
        {

    //printk("***key_dev.keyStatus[%d] == KEYSTATUS_DOWN\n",key);
    key_dev.keyStatus[key] = KEYSTATUS_DOWN;
            key_timer[key].expires = jiffies + KEY_TIMER_DELAY2; //延迟
    keyEvent(key); //记录键值,唤醒等待队列
            add_timer(&key_timer[key]);//超时,再次执行此函数

        }

    }
    else       //键已抬起
    {
        key_dev.keyStatus[key] = KEYSTATUS_UP;
        enable_irq(key_info_tab[key].irq_no);
    }
}

2、中断

set_irq_type、irq_set_irq_type在下面代码中会出现两个接口,两个接口都是可以用的,但是针对版本的不同会出现莫名错误,所以在编译出错时可进行替换

   // 注册中断函数
 request_irqs()

  // 按键设备驱动的中断申请函数
// 申请系统中断,中断方式为下降沿触发
static int request_irqs(void)
{
    struct key_info *k;
    int i;
    int ret;

    for(i = 0; i < sizeof(key_info_tab)/sizeof(key_info_tab[1]); i++)  
    {
    //printk( "for is action %d\r\n",i);
        k = key_info_tab + i;
        //设置4个IO口为中断下降沿触发方式
        //set_irq_type(key_info_tab[i].irq_no,key_info_tab[i].irq_type);      // 设置中断类型
        irq_set_irq_type(key_info_tab[i].irq_no,key_info_tab[i].irq_type);
        printk(KERN_NOTICE "type key_info_tab[i].irq_type is %d\r\n",key_info_tab[i].irq_type);
        //申请中断(类型为快速中断,中断服务时屏蔽所有外部中断?)将按键序列号作为参数传入中断服务程序        

        ret=request_irq(k->irq_no,at91sam9260_enit_key,0,DEVICE_NAME,(void *)i);        
        if(ret)
        {
            printk(KERN_NOTICE "buttons:ret is %d\r\n",ret);
            return -1;
        }
        printk( "request_irq_%d is ok %x \r\n\n",i,k->irq_no);
    }
    return 0;
}



#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/atmel_pdc.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <linux/semaphore.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/input.h>
#include <linux/errno.h>
#include <linux/irq.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/list.h>


#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <mach/at91_pio.h>
#define DEVICE_NAME "key_driver"


#define KEY_TIMER_DELAY1    (HZ/25)             //按键按下去抖延时20毫秒        
#define KEY_TIMER_DELAY2    (HZ/5)             //按键抬起去抖延时100毫秒


#define KEYSTATUS_DOWN              0           //按键按下                    
#define KEYSTATUS_UP                1           //按键抬起                
#define KEYSTATUS_DOWNX             2           //按键不确定  
#define KEY_NUM                     6           // 6个按键


#define DP_MAJOR 0//主设备号
#define DP_MINOR 0  //次设备号
unsigned int key_major = DP_MAJOR;


static struct class *SAM9260_keytest_class = NULL; 
static volatile int ev_press = 0;  //等待队列的条件变量


// 按键驱动的设备结构体、定时器
#define MAX_KEY_BUF     16   // 按键缓存区大小
typedef unsigned char KEY_RET;
// 设备结构体
typedef struct
{
    unsigned int keyStatus[KEY_NUM];    // 6个按键的按键状态
    KEY_RET buf[MAX_KEY_BUF];           //缓存
    unsigned int head,tail;             // 按键缓存区头和尾
    wait_queue_head_t wq;               // 等待队列
    struct cdev cdev;                   //cdev 结构体
}KEY_DEV;
KEY_DEV key_dev,*key_devp;




#define BUF_HEAD (key_dev.buf[key_dev.head]) //缓冲头
#define BUF_TAIL (key_dev.buf[key_dev.tail]) //缓冲尾
#define INCBUF(x,mod)  ((++(x))&((mod)-1)) 
/* 
这个宏定义使得队列操作中指针始终能指到当前队列的头或尾。当队列满了后指重新回到᳔初位置。
比如我们有一个容量为8 的队列,当head 为0 时运算结果为1,head 为1时运算结果为2,当head 为
7 时运算结果为0。
有兴趣的读者自己可以取不同的数运算一次。
它在以后的两行代码中用到:
tedev.head=INCBUF(tsdev.head,MAX_TS_BUF); 和
tedev.tail=INCBUF(tsdev.tail,MAX_TS_BUF); 
*/



static struct timer_list key_timer[KEY_NUM]; // 6个按键去抖定时器


// 按键硬件资源、键值信息结构体
static struct key_info
{
    int irq_no;                         // 中断号
    int irq_type;                       // 中断类型
    unsigned int gpio_port;             // GPIO端口
    int key_no;                         // 键值

}key_info_tab[6]=
{
    // 按键所使用的CPU资源
    {
        //AT91_PIN_PB0,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB0,1      //中断类型为上升沿中断
        AT91_PIN_PB0,IRQF_TRIGGER_FALLING,AT91_PIN_PB0,1            //中断类型为下降沿中断
    },
    {
        //AT91_PIN_PB1,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB1,2
        AT91_PIN_PB1,IRQF_TRIGGER_FALLING,AT91_PIN_PB1,2
    },
    {
        //AT91_PIN_PB2,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB2,3
        AT91_PIN_PB2,IRQF_TRIGGER_FALLING,AT91_PIN_PB2,3
    },
    {
        //AT91_PIN_PB3,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB3,4
        AT91_PIN_PB3,IRQF_TRIGGER_FALLING,AT91_PIN_PB3,4
    },
    {
        //AT91_PIN_PB16,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB16,5
        AT91_PIN_PB16,IRQF_TRIGGER_FALLING,AT91_PIN_PB16,5
    },
    {
        //AT91_PIN_PB17,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB17,6
        AT91_PIN_PB17,IRQF_TRIGGER_FALLING,AT91_PIN_PB17,6
    },
};


// 初始化
static void at91sam9260_key_io_init(void)
{
    at91_set_gpio_input(AT91_PIN_PB0, 1);        
    at91_set_deglitch(AT91_PIN_PB0, 1);

    at91_set_gpio_input(AT91_PIN_PB1, 1);        
    at91_set_deglitch(AT91_PIN_PB1, 1);


    at91_set_gpio_input(AT91_PIN_PB2, 1);        
    at91_set_deglitch(AT91_PIN_PB2, 1);

    at91_set_gpio_input(AT91_PIN_PB3, 1);        
    at91_set_deglitch(AT91_PIN_PB3, 1);

    at91_set_gpio_input(AT91_PIN_PB16, 1);        
    at91_set_deglitch(AT91_PIN_PB16, 1);

    at91_set_gpio_input(AT91_PIN_PB17, 1);        
    at91_set_deglitch(AT91_PIN_PB17, 1);

}



/* 记录键值并唤醒等待队列 */
static void keyEvent(unsigned int key)
{
    //printk("keyEvent is action \n");
    //printk("key_info_tab[key].key_no is %x \n",key_info_tab[key].key_no);
    //printk("BUF_HEAD is %x \n",BUF_HEAD);

    BUF_HEAD = key_info_tab[key].key_no;                  // 记录键值
    //printk("BUF_HEAD is %x \n",BUF_HEAD);

    key_dev.head = INCBUF(key_dev.head,MAX_KEY_BUF);      // 调整缓冲区头指针
    wake_up_interruptible(&(key_dev.wq));                 // 唤醒等待队列
    //zmz
}



// 按键设备的中断处理
// 键被按下后,将发生中断,在中断处理程序中,应该关闭中断进入查询模式,延迟20ms以实现去抖动
// 这个中断处理过程只包含顶半部,无底半部
static irqreturn_t at91sam9260_enit_key(int irq,void *dev_id)//,struct pt_regs *reg
{
    int key = (int)dev_id;
    int found = 0;
    int i;
    //ARRAY_SIZE 球设备结构体的设备个数
    //printk(KERN_NOTICE"\n ARRAY_SIZE(key_info_tab)  is %d in button\n", ARRAY_SIZE(key_info_tab));


    for (i = 0; i < ARRAY_SIZE(key_info_tab); i++)   // 查找产生中断的按键
    {
        if (key_info_tab[i].irq_no == irq) 
        {
            printk(KERN_NOTICE"irq %d in button\n", irq);
            found = 1;
            break;
        }
    }
    if (!found)                                     // 没找到
    {
        printk(KERN_NOTICE"bad irq %d in button\n", irq);
        return IRQ_NONE;   //错误的中断
    }

    disable_irq_nosync(key_info_tab[key].irq_no);          // 找到,关闭对应中断    

    //printk(KERN_NOTICE"close irq  in button\n");

    key_dev.keyStatus[key] = KEYSTATUS_DOWNX;  // 不确定是否为按下
    key_timer[key].expires = jiffies + KEY_TIMER_DELAY1;// 延迟
    add_timer(&key_timer[key]);  // 启动定时器  

    //printk(KERN_NOTICE"will return IRQ_HANDLED\n");

    return IRQ_HANDLED;   //正确的中断
}


// 定时器处理函数
static void key_timer_handler(unsigned long data)
{
    int key = data;
    //获取当前按键引脚上的电平值来判断按键是按下还是抬起
    int up = at91_get_gpio_value(key_info_tab[key].gpio_port);
    if (!up)
    {
        if (key_dev.keyStatus[key] == KEYSTATUS_DOWNX)          //按键不确定
        {
            //printk("+++key_dev.keyStatus[%d] == KEYSTATUS_DOWNX\n",key);
            key_dev.keyStatus[key] = KEYSTATUS_DOWN;
            key_timer[key].expires = jiffies + KEY_TIMER_DELAY2; //延迟           
            keyEvent(key);  //记录键值,唤醒等待队列
            add_timer(&key_timer[key]);
        }
        else                                                    //按键按下
        {

            //printk("***key_dev.keyStatus[%d] == KEYSTATUS_DOWN\n",key);
            key_dev.keyStatus[key] = KEYSTATUS_DOWN;
            key_timer[key].expires = jiffies + KEY_TIMER_DELAY2; //延迟
            keyEvent(key); //记录键值,唤醒等待队列
            add_timer(&key_timer[key]);

        }

    }
    else       //键已抬起
    {
        key_dev.keyStatus[key] = KEYSTATUS_UP;
        enable_irq(key_info_tab[key].irq_no);
    }
}




// 按键设备驱动的中断申请函数
// 申请系统中断,中断方式为下降沿触发
static int request_irqs(void)
{
    struct key_info *k;
    int i;
    int ret;


    for(i = 0; i < sizeof(key_info_tab)/sizeof(key_info_tab[1]); i++)  
    {
        //printk( "for is action %d\r\n",i);
        k = key_info_tab + i;
        //设置4个IO口为中断下降沿触发方式
        //set_irq_type(key_info_tab[i].irq_no,key_info_tab[i].irq_type);      // 设置中断类型
        irq_set_irq_type(key_info_tab[i].irq_no,key_info_tab[i].irq_type);
        printk(KERN_NOTICE "type key_info_tab[i].irq_type is %d\r\n",key_info_tab[i].irq_type);
        //申请中断(类型为快速中断,中断服务时屏蔽所有外部中断?)将按键序列号作为参数传入中断服务程序        

        ret=request_irq(k->irq_no,at91sam9260_enit_key,0,DEVICE_NAME,(void *)i);        
        if(ret)
        {
            printk(KERN_NOTICE "buttons:ret is %d\r\n",ret);
            return -1;
        }
        printk( "request_irq_%d is ok %x \r\n\n",i,k->irq_no);
    }
    return 0;
}
// 释放中断
static void free_irqs(void)
{
    struct key_info *k;
    int i;


    for(i = 0; i < sizeof(key_info_tab)/sizeof(key_info_tab[1]); i++)
    {
        k = key_info_tab + i;
        free_irq(k->irq_no,(void *)i);
    }

}


// 按键设备驱动的打开、释放函数
static int at91sam9260_key_open(struct inode *inode, struct file *filp)
{
    key_dev.head = key_dev.tail = 0; //清空按键动作缓冲区
    //keyEvent = keyEvent_raw; //函数指针指向按键处理函数keyEvent_raw

    return 0;
}


static int at91sam9260_key_release(struct inode *inode, struct file *filp)
{
    //keyEvent = keyEvent_dummy; //函数指针指向空函数

    return 0;
}




// 按键设备驱动读函数
static ssize_t at91sam9260_key_read(struct file *filp,char __user *buf,ssize_t count,loff_t*ppos)
{
    unsigned int key_ret;
    unsigned long flags;
retry:
    //printk( "1 key_dev.head  is  %x  ,  \r\n",key_dev.head);
    //printk( "1 key_dev.tail  is  %x  ,  \r\n",key_dev.tail);
    if (key_dev.head != key_dev.tail)                         // 缓冲区有数据?
    {
        local_irq_save(flags);                                      // 进入临界区 ,关中断       
        key_ret = BUF_TAIL;         // 读出键值
        key_dev.tail = INCBUF(key_dev.tail, MAX_KEY_BUF);     // 调整缓冲区尾指针
        local_irq_restore(flags);       // 退出临界区,开中断        
        printk( "**********copy_to_user *********\r\n");
        //printk( "sizeof(unsigned int)  is  %x\r\n",sizeof(unsigned int));
        //printk( "(void *)&key_ret  is  %x\r\n",key_ret);
        //if(copy_to_user(buf, (void *)&key_ret, sizeof(unsigned int)))
        if(copy_to_user(buf, (void *)&key_ret, sizeof(unsigned int)))       // 拷贝到用户空间    
        {
            printk( "copy_to_user is  EFAULT\r\n");
            return -EFAULT;
        }
        else
        {
            //key_dev.head = 0;    zmz
            //key_dev.tail = 0;    zmz
            //printk( "copy_to_user is  SUCCEES\r\n");
            return sizeof(unsigned int);
        }

    }
    else   // 缓冲区没数据
    {
        if (filp->f_flags & O_NONBLOCK)                             // 若采用非阻塞方式读取则返回错误
        {
            return -EAGAIN;
        }
        else  
        {
            interruptible_sleep_on(&(key_dev.wq));                   // 使进程睡眠
            //zmz
        }
        if (signal_pending(current))                               //在这里等中断 
        {   // 如果是信号中断
            return -ERESTARTSYS;
        }
        goto retry;
    }

    return sizeof(unsigned int);
}


// 按键设备驱动文件操作结构体,主要实现打开、释放和读函数
static struct file_operations at91sam9260_key_fops = 
{
    .owner = THIS_MODULE,
    .open = at91sam9260_key_open,            // 启动设备
    .release = at91sam9260_key_release,      // 关闭设备
    .read = at91sam9260_key_read,            // 读取按键的键值
};

// 模块加载函数包括:设备号申请、cdev的添加,另:申请中断、初始化定时器和队列;
// 模块卸载函数恰好相反
static int __init at91sam9260_key_init(void)
{
    int i,err,result;


    // 申请设备号       
    dev_t dev = MKDEV(key_major, 0);  


    /* 申请设备号 */
    if (key_major)
        result = register_chrdev_region(dev, 1, DEVICE_NAME);
    else    /* 动态申请设备号 */
    {
        result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
        key_major = MAJOR(dev);
        printk(KERN_INFO "Todo: mknod /dev/%s c %d 0\n", DEVICE_NAME, key_major);
    }

    if (result < 0)  
    {  
        printk(DEVICE_NAME " can't register major number\n");  
        return result;  
    }  
    printk("register SAM9260_keytest Driver OK! Major = %d\n", key_major);  


    // 分配设备结构体的内存
    //zmz
    key_devp = kmalloc(sizeof(key_dev),GFP_KERNEL);

    //key_devp = kmalloc(sizeof(key_dev),GFP_ATOMIC);
    if(!key_devp)
    {
        result =-ENOMEM;
        goto fail_malloc;
    }
    // 添加cdev
    memset(key_devp,0,sizeof(key_dev));



    cdev_init(&key_dev.cdev, &at91sam9260_key_fops);
    key_dev.cdev.owner=THIS_MODULE;  
    key_dev.cdev.ops=&at91sam9260_key_fops; 

    //err=cdev_add(&key_dev.cdev, dev, 1)
    err=cdev_add(&key_dev.cdev, MKDEV(key_major, 0), 1);
    if(err)
    {
        printk(KERN_ALERT"Add char dev error!\n");
    } 

    /**自动创建设备文件**/  
    SAM9260_keytest_class=class_create(THIS_MODULE,DEVICE_NAME);  
    if(IS_ERR(SAM9260_keytest_class))  
    {  
        printk("Err: failed in SAM9260_ledtest class. \n");  
        //goto fail_create_class;  
    }  
    device_create(SAM9260_keytest_class, NULL, MKDEV(key_major, 0), NULL, DEVICE_NAME);  


    key_dev.head = key_dev.tail = 0;             // 初始化结构体
    for(i = 0; i < KEY_NUM; i++)
    {
        key_dev.keyStatus[i] = KEYSTATUS_UP;
    }
    init_waitqueue_head(&(key_dev.wq));  // 等待队列




    printk("\n");  
    printk("init  timer \n");  
    // 初始化定时器,实现软件的去抖动
     /* 初始化定时器 */
    for(i = 0; i < KEY_NUM; i++)
    {        
        key_timer[i].function=key_timer_handler;
        key_timer[i].data=i;       
        init_timer(&key_timer[i]);
        printk("key_timer[i].data is %x ,i is %x ,KEY_NUM is %x \n", key_timer[i].data,i,KEY_NUM);  
    }
    at91sam9260_key_io_init();   // 初始化   




    printk("\n");  
    printk("request  irq  action   \n\n");  
     // 注册中断函数
    if(-1 == request_irqs())
    {
        printk(KERN_NOTICE "request_irqs failed!\r\n");
    }
    else
    {
        printk(KERN_NOTICE "request_irqs success!\r\n");
    }

    fail_malloc:unregister_chrdev_region(dev,1);
    //fail_create_class:class_destroy(SAM9260_keytest_class);
    printk(KERN_NOTICE "init  success!\r\n");
    return result;

}


// 按键设备驱动的模块卸载函数
static void __exit at91sam9260_key_exit(void)
{
    free_irqs();    // 注销中断
    // 释放设备号,删除cdev
    cdev_del(&key_dev.cdev);   // 删除字符设备结构体
    kfree(key_devp);
    unregister_chrdev_region(MKDEV(key_major,DP_MINOR),1);  // 删除字符设备
    del_timer(&key_timer[0]);
    del_timer(&key_timer[1]);
    del_timer(&key_timer[2]);
    del_timer(&key_timer[3]);
    del_timer(&key_timer[4]);
    del_timer(&key_timer[5]);

}



MODULE_LICENSE("GPL");
module_init(at91sam9260_key_init);
module_exit(at91sam9260_key_exit); 
at91sam9260串口驱动 serial.c是串口的驱动程序,是经过测试的。 立即下载

相关推荐

AT91SAM7SXX的USART_PDC通信

实现了ARM上的USART通过PDC方式进行收发,很快掌握USART和基本PDC的使用方法

驱动程序开发--AT91SAM9260的GPIO驱动笔记

驱动学习,字符驱动例程。在AT91SAM9260开发板上的驱动开发 1 驱动编写 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #in

走走看看 4817

Claude Skills:不是更聪明,而是更“像专家”的 Agent 养成方法

Claude Skills 不是在告诉 Agent“你能做什么”, 而是在约束它“你应该如何思考、如何判断、如何给结论”。

测试者家园 1293

AT91SAM7SE应用 - IRQ

最近在使用 ATMEL 的AT91SAM7SE256 来处理FPGA 输出的数据,然后再把数据发送到PC机端。 既利用了FPGA 高速数字信号处理的优势,又发挥了ARM处理器对控制类信号的简洁处理。。 在使用的过程中,感觉AT91SAM7SE256的资料比较少,所以在这里我把自己测试过的代码放上来,提供下载。。 开发环境如下所示: IDE-Version:μVision V4.23...

weixin_33806914的博客 234

【OpenCV】背景替换(opencv、python),照片、证件照的背景替换(抠图)

目录步骤:导入库1、读入将要抠图的图片2、create一个带颜色域的mask3、通过mask使得原图只显示汽车,即抠出所需要的部分4、将要替换掉的图像resize或裁剪到和上述图片一样的大小5、将该图片预留出将要重叠上的部分,即将mask部分改为(0,0,0)6、通过和运算使得两部分图片mask部分替换7、最后保存图片 步骤: 导入库 import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np imp

weixin_41729258的博客 4362

光学系统设计:波段、光源、光纤与探测器匹配指南

在光学测量和光纤通信系统中,波段、光源、光纤和探测器的匹配关系是系统设计的核心基础。波段指电磁波谱中的特定波长范围,光源负责产生特定波长的光信号,光纤作为传输介质需要与波长匹配以降低损耗,探测器则负责将光信号转换为电信号。理解各组件的光谱特性对于系统性能至关重要,例如在850nm短波长多模光纤系统中,VCSEL激光器与PIN光电二极管的组合能提供最佳性价比。典型应用场景包括生物医学成像、光纤通信和气体传感,其中光谱重叠优化、模场直径匹配和偏振特性协调是关键技术要点。通过实测数据对比不同组合的传输性能,可以为

weixin_33812433的博客 338

SPI设备的驱动

SPI设备的驱动 主要包括两个SPI设备,at45db321d和mcp2515,一个是串行的dataflash,一个是can总线设备芯片。前者对于我们来说非常重要,我们可以借助该设备对uboot和kernel以及根文件系统进行更新。    预备知识:设备和驱动是如何匹配的?系统的热插拔是如何实现的?    首先一点,设备和驱动是严格区分的,设备是设备,驱动是驱动,设备通过structdevice

EMMA3SLP的专栏 1738

山景BP10_128DBG开发板通过蓝牙连接手机放歌实验回顾

最近在学习上海山景公司的BP10_128DBG的开发板,因为网上关于BP10开发板的帖子也比较少,在学习的时候也没有太多的参考资料,基本上都是官方的历程。蓝牙放歌这个demo对我来说也比较复杂,特写下此博客进行记录、总结,大家有需要的可以参考。

weixin_56646002的博客 2020

RTEMS 的 AT91SAM9260 移植(4): 中断驱动

中断驱动AT91rm9200和AT9260差别不大,主要要修改的地方是个别的中断向量号,另外就是最大中断向量号。我所作的修改:c/src/lib/libcpu/arm/at91sam9260/irq/irq.h删除了相关的9200的定义,定义了AT9260中断的最大数量。/* * Interrupt handler Header file * * Bacon Xu */ #ifndef __IRQ_H__ #define __IRQ_H__ #ifdef __cplusplus ex

雪松's RTEMS 4374

18650电池组流体直冷热管理仿真:COMSOL多物理场耦合建模路线与实战策略

在动力电池与储能系统的热管理设计中,多物理场耦合仿真已成为平衡性能与成本的关键工具。液冷方案的换热极限促使行业转向制冷剂直冷技术,而两相流与电池产热的强耦合特性,使得基于COMSOL的数值建模成为评估系统温升与流动分配的重要手段。工程实践中,电化学-热-流场全耦合模型与集总电池-流场简化模型各有适用场景,前者揭示电池内部微观机理,后者则以高计算效率支撑包级方案迭代。通过合理简化几何、标定内阻与熵热系数、设置等效换热边界,仿真能够准确预测直冷系统在快充或大倍率放电下的温度均匀性与压降特性,从而指导流道优化与制

weixin_33585822的博客 314

利用DRONEKIT-SITL + MAVPROXY + QGroundControl模拟飞行

dronekit: 一种用于无人机控制的python库。 dronekit-sitl:一种本地仿真工具,相当于本地虚拟化了一个无人机。 mavproxy:数据转发软件(类似于插线板的感觉,一个输入,多个相同的输出)。打开一个Anaconda prompt 首先激活相应的环境 然后运行如下命令: 保持2中的Anaconda prompt处于运行状态,另打开一个Anaconda prompt窗口,运行如下命令: tcp:127.0.0.1:5760: SITL默认端口,作为mavproxy的输入,把输入数据转发

Done___的博客 4344

arm linux gpio 中断,ARM-Linux下的GPIO中断程序

为了调试ARM板上的GPIO引脚中断效果,以便在后续项目使用ARM与ZLG7290按键LED中断芯片连接中随意选择空闲的GPIO引脚来作为ZLG7290的中断信号线,特意编写了一个小的Linux GPIO中断驱动程序下载到开发板上做实验。经验证,这种软件中断方式也还差强人意。下面贴出自己编写的不成熟的代码,见笑(实验的硬件电路为ARM GPIO的PB17连接一个共阴LED,PB18与PB19连接,...

weixin_35819549的博客 318

GameFramework 框架详解之 Network网络模块 工具链

GameFramework(下面简称GF)Demo中,已经给我们提供了Network模块使用的protobuf使用的动态链接库protobuf-net.dll,但是GF并没有给我们提供protobuf相关的工具链,比如:1.proto文件自动导出对应c#的Packet类和PacketHandler类2.导出Packet类继承IReference以便使用引用池。3.自动生成Packet类和PacketHandler的Id,且保持和服务器Id一一对应。

TxNet 2903

Linux gpio 中断应用(转载)

今日为了调试ARM板上的GPIO引脚中断效果,以便在后续项目使用ARM与ZLG7290按键LED中断芯片连接中随意选择空闲的GPIO引脚来作为ZLG7290的中断信号线,特意编写了一个小的Linux GPIO中断驱动程序下载到开发板上做实验。经验证,这种软件中断方式也还差强人意。下面贴出自己编写的不成熟的代码,见笑()。        实验的硬件电路为ARM GPIO的PB17连接一个共阴L

wangsh217的专栏 1559

基于 YOLOv26 的遥感图像目标检测系统:从原理到模型

本文介绍了基于YOLOv26的遥感图像目标检测系统。YOLOv26凭借端到端设计、轻量化架构和小目标优化能力,有效解决了遥感图像中多尺度目标、复杂背景、小目标检测等挑战。系统采用CSPDarknet骨干网络和FPN+PAN特征融合模块,通过MuSGD优化器和改进损失函数提升训练效果。文章详细阐述了数据预处理、模型训练流程和优化技巧,包括Tile推理和混合精度训练。系统支持多种部署方式,在CPU上推理速度提升43%,能实现高精度、实时性的遥感目标检测,适用于城市规划、农业监测等场景。

一键难忘的博客 568

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ARM-Linux下的GPIO中断程序

今日为了调试ARM板上的GPIO引脚中断效果,以便在后续项目使用ARM与ZLG7290按键LED中断芯片连接中随意选择空闲的GPIO引脚来作为ZLG7290的中断信号线,特意编写了一个小的Linux GPIO中断驱动程序下载到开发板上做实验。经验证,这种软件中断方式也还差强人意。下面贴出自己编写的不成熟的代码,见笑()。       实验的硬件电路为ARM GPIO的PB17连接一个共阴LED,PB18与PB19连接,PB18由中断驱动设置为低电平触发,PB19由GPIO驱动程序控制,上层应用程序通过驱动控

寸先生的AI道路 1万+

深度学习工具包 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")

at91sam9260驱动

RT-Thread for AT91SAM9260 移植手记 需要实现的函数 rt_base_t rt_hw_interrupt_disable(void); 关中断,并返回之前的中断状态 void rt_hw_interrupt_enable(rt_base_t level); 开中断,参数为中断状态,一般为rt_hw_i

wangsh217的专栏 1664

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

ARM7键盘工作原理及中断方式实现(C语言)

一般键盘结构如图所示. 图中的每个行列交叉处为一个按键。当键盘上没有任何按键动作,整个行列线均处于断开状态,此时列线输出为高电平,当某个按键被按下,则与此按键相连的行线被连通,此时对应列线电平输出则取决于行线的电平。如果将所有列线设置为输出,对应行线设置为输入,则可通过程序控制行线的电平状态,如,首先将第一行设置为低电平,其余行为高电平,此时依次检测列线电平输出状态,若第一列电平输出为低

grow_mature的专栏 3863

AT91的中断处理机制

 1、所有编程为边沿触发的中断源(包括源0中的FIQ)可通过写AIC_ISCR与AIC_ICCR寄存器来设置与清零。2、当读AIC_IVR( 中断向量寄存器) 时,AIC 自动清除当前中断。只有当该操作影响当前中断时,AIC才会检测该中断源。自动清除降低中断服务程序入口代码读AIC_IVR 的请求操作。3、当读AIC_FVR 时执行自动清除中断源0。4、高级中断控制器(AIC) 用

suifengwyq的专栏 1998

AT9G45的pwm驱动有问题,快来解救小弟.

AT9G45的pwm,头文件 #ifndef AT91_PWM_H #define AT91_PWM_H #define PWMC_BASE 0xfffb8000 /**************** pwm模式寄存器偏移0x00 *****************/ #define PWM_MR_OFF 0x00000000 ///< PWM Mode

浮华若水 1893

关于sam9x5移植遇到的一些问题

最近弄sam9x5,核心芯片型号是at91sam9x25,遇到很多问题,郁闷了好几天。所遇到的问题解决的,没解决的如下: 一:板子bootload和以前用的mini2440不太一样,此板bootload分为三级引导程序,分别是Romboot,bootstrap和u-boot。因为出厂时自带了bootload,开发是对其要求也不是很大,所以就用现成的,只移植内核和跟文件系统即可。按照说明使用tft

qzs_13933908434的专栏 3192

AT91 GPIO Interrupt

Linux: 2.6.31Processor: AT91SAM9XE There are two types of interrupts you can create for an AT91. An external interrupt or a GPIO interrupt. An external interrupt does not have the addition...

weixin_34332905的博客 216
下一篇: svn连接linux svn 服务器(SVN Unable to connect to a repository at URL)
FDmitnick
博客等级 码龄10年 8粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值