找回密码
 注册
关于网站域名变更的通知
查看: 358|回复: 0
打印 上一主题 下一主题

基于i.MX6ULL的掉电检测设计与软件测试

[复制链接]

该用户从未签到

跳转到指定楼层
1#
 楼主| 发表于 2023-11-9 11:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
基于i.MX6ULL的掉电检测设计与软件测试
基于i.MX6ULL平台设计实现掉电检测功能,首先选择一路IO,利用IO电平变化触发中断,在编写驱动时捕获该路GPIO的中断,然后在中断响应函数中发送信号通知应用程序掉电发生了。
图1.1掉电信号IO
       驱动代码:
#include<linux/module.h>
#include<linux/init.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/mm.h>
#include<linux/cdev.h>
#include<linux/errno.h>
#include<linux/sched.h>
#include<linux/device.h>
#include<asm/io.h>
#include<asm/switch_to.h>
#include<asm/uaccess.h>

" @/ W$ a0 ^) P( Y
#include<asm/gpio.h>   
#include<linux/interrupt.h>
#include<linux/irq.h>
! v; w9 e( \+ S) c4 l! G( G& w3 N3 J0 d
8 |7 \+ o4 i3 _3 R# f# M" \3 F
#definepower_MAJOR 200
/ T% D: g' ^/ V' y! l$ @1 i  j
staticstruct class *my_class;
staticstruct fasync_struct *fasync_queue; //异步通知队列

5 Z! P% e6 L+ F1 B6 Y* i8 b$ @
#defineGPIO_NUM 1  //中断引脚为:GPIO1_1
staticunsigned int irq_num;

# ]  N& |% j" P
" B9 Z) F2 T2 U7 m. Q
/* 打开 */
intpower_open(struct inode *inode,struct file *filp){
         return 0;
4 W3 t5 k3 p7 N9 Z! R) I3 R
}
- x4 m4 M1 \$ s8 B( t
/* 关闭 */
intpower_release(struct inode *inode,struct file *filp){
         return 0;
}

) M$ `- v0 @+ _+ t" |
ssize_tpower_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos){

) o; Z' B- Z  u& X9 Z
         return count;
}
1 u- v, ^  H  f' m: U. ~( `) D
ssize_tpower_write(struct file *file,const char __user *buf,size_t count,loff_t*f_pos){
$ q7 q; e9 t" P7 ]8 F; J
         return count;
}

' g) s; D9 [' j8 X  X
staticint my_fasync(int fd, struct file * filp, int on)
{
    int retval;
   retval=fasync_helper(fd,filp,on,&fasync_queue);
    /*将该设备登记到fasync_queue队列中去*/
    if(retval<0)
      return retval;
    return 0;
}
* `7 Z/ M& l! j$ T; I- _$ o9 i
staticconst struct file_operations simple_fops={
         .owner=THIS_MODULE,
         .open=power_open,
         .release=power_release,
    .read=power_read,
         .write=power_write,
    .fasync=my_fasync,
};

  E+ r4 |' _) T6 @& V; @/ v/ N0 c
/* 在中断服务函数中向应用层发送消息-异步通知 */
staticirqreturn_t irq_callback (int irqno, void *dev_id){
                  printk("irq power-detectworking !\n");
                  if (fasync_queue) {
            kill_fasync(&fasync_queue, SIGIO,POLL_IN);
                  }
         return IRQ_HANDLED;
}

: [* X6 A( w: A( {  t
intpower_init_module(void){
         int rtn;
         int ret;
         /* 注册设备驱动 */
         ret =register_chrdev(power_MAJOR,"power-detect-test",&simple_fops);
         if(ret<0){
                  printk("Unable toregister character device %d!/n",ret);
                  return ret;
         }

* K5 o, C# Y3 o+ s3 I
         /* 自动创建设备节点 */
         my_class = class_create(THIS_MODULE,"my_class");
         device_create(my_class, NULL,MKDEV(power_MAJOR, 0), NULL,"powerdetect");

/ g# P! W( T. \
         /*gpio申请*/
         rtn = gpio_request(GPIO_NUM,"my_irq");
         if(rtn!=0){
                  printk("my_irq irq pinrequest io failed.\n");
         }
         rtn = gpio_direction_input(GPIO_NUM);
         if(rtn<0){
                  printk("gpio_direction_input()failed !\n");  
         }
         /*获取gpio中断号*/
         irq_num = gpio_to_irq(GPIO_NUM);

9 A5 u) l! k" q7 U
         /*GPIO中断服务函数注册,*/                    /*下降沿触发*/               
         rtn = request_irq(irq_num,irq_callback,IRQF_TRIGGER_FALLING,"my_irq", NULL);
         if (rtn<0) {
                  printk("my_irq requestirq false\n");
         } else {
                  printk("my_irq requestirq success: %d\n",irq_num);
         }

6 c* P% H* `, {0 X0 c  f$ _
    printk("module_initsucessful!!!\n");
         return 0;
}
8 b3 c6 N* }- ?
/* 卸载 */
voidpower_cleanup_module(void){
         /* 卸载相应的设备驱动 */
         unregister_chrdev(power_MAJOR,"power-detect-test");     
         device_destroy(my_class,MKDEV(power_MAJOR,0));
         class_destroy(my_class);

7 o: e& q! @: b( X2 \
         /*释放GPIO*/
         gpio_free(GPIO_NUM);
, _- r5 a. L; t; z" ]
    printk("module_exitsucessful!!!\n");
}
5 |% F/ ]" l+ E6 B" a
/* 宏实现 */
module_init(power_init_module);
module_exit(power_cleanup_module);

! h! q7 K( d: z$ w1 r& _; `  {
/* 开源许可声明 */  
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Zou");
应用代码:
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<fcntl.h>

0 f) m- D$ W! I8 _; I
staticint fd;

( g% K% f7 L# ^+ l3 M& I. r
/* 内核产生异步通知,调用该应用层函数处理 */
voidsigterm_handler(int signo)
{
         printf("app irq work !!!\n");
}
, W3 b1 M( ]5 _2 `3 |3 e1 n! x1 N
intmain(void)
{
    int oflags;
3 c5 ~$ M  }0 h. M* c
   fd=open("/dev/powerdetect",O_RDWR);  //打开设备文件
/ a0 F" z/ s* P
    /* 启动异步通知信号驱动机制 */
    signal(SIGIO, sigterm_handler);
    fcntl(fd, F_SETOWN, getpid());
    oflags = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, oflags | FASYNC);

& ^2 W) |, t6 f* a5 h3 E
    /*建立一个死循环,防止程序结束 */
    while(1)
    {
        printf("sleep\n");
        usleep(200000);  //2ms
    }

3 L' e, L$ L0 i; P: `
    close(fd);
    return 0;
}
将驱动编译成模块,上电加载并执行应用程序后,将电压缓慢下调至掉电临界点。触发GPIO下降沿中断,并提供应用程序掉电信号。
图1..2掉电检测

: R' c% {4 \( O8 i
/ v4 w2 H3 j6 D4 B7 ?% R3 R0 V" r! \- e* l5 \: z+ V
# y. z. [7 |2 X% V: `

' M1 h) U2 h& c! r  G; S
1 B7 ^6 X. G# t6 }# G" G* X+ w1 n- U' `/ Q, }! i( Y% o9 ?- s
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-23 13:25 , Processed in 0.140625 second(s), 22 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表