首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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

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

基于i.MX6ULL平台设计实现掉电检测功能,首先选择一路IO,利用IO电平变化触发中断,在编写驱动时捕获该路GPIO的中断,然后在中断响应函数中发送信号通知应用程序掉电发生了。

掉电信号IO

图1.1掉电信号IO

驱动代码:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#definepower_MAJOR?200

staticstruct?class?*my_class;

staticstruct?fasync_struct?*fasync_queue;?//异步通知队列

#defineGPIO_NUM?1??//中断引脚为:GPIO1_1

staticunsigned?int?irq_num;

/*?打开?*/

intpower_open(struct?inode?*inode,struct?file?*filp){

return?0;

}

/*?关闭?*/

intpower_release(struct?inode?*inode,struct?file?*filp){

return?0;

}

ssize_tpower_read(struct?file?*filp,char?__user?*buf,size_t?count,loff_t?*f_pos){

return?count;

}

ssize_tpower_write(struct?file?*file,const?char?__user?*buf,size_t?count,loff_t*f_pos){

return?count;

}

staticint?my_fasync(int?fd,?struct?file?*?filp,?int?on)

{

int?retval;

retval=fasync_helper(fd,filp,on,&fasync_queue);

/*将该设备登记到fasync_queue队列中去*/

if(retval

return?retval;

return?0;

}

staticconst?struct?file_operations?simple_fops={

.owner=THIS_MODULE,

.open=power_open,

.release=power_release,

.read=power_read,

.write=power_write,

.fasync=my_fasync,

};

/*?在中断服务函数中向应用层发送消息-异步通知?*/

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;

}

intpower_init_module(void){

int?rtn;

int?ret;

/*?注册设备驱动?*/

ret?=register_chrdev(power_MAJOR,"power-detect-test",&simple_fops);

if(ret

printk("Unable?toregister?character?device?%d!/n",ret);

return?ret;

}

/*?自动创建设备节点?*/

my_class?=?class_create(THIS_MODULE,"my_class");

device_create(my_class,?NULL,MKDEV(power_MAJOR,?0),?NULL,"powerdetect");

/*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

printk("gpio_direction_input()failed?!\n");

}

/*获取gpio中断号*/

irq_num?=?gpio_to_irq(GPIO_NUM);

/*GPIO中断服务函数注册,*/????????????????????/*下降沿触发*/

rtn?=?request_irq(irq_num,irq_callback,IRQF_TRIGGER_FALLING,"my_irq",?NULL);

if?(rtn

printk("my_irq?requestirq?false\n");

}?else?{

printk("my_irq?requestirq?success:?%d\n",irq_num);

}

printk("module_initsucessful!!!\n");

return?0;

}

/*?卸载?*/

voidpower_cleanup_module(void){

/*?卸载相应的设备驱动?*/

unregister_chrdev(power_MAJOR,"power-detect-test");

device_destroy(my_class,MKDEV(power_MAJOR,0));

class_destroy(my_class);

/*释放GPIO*/

gpio_free(GPIO_NUM);

printk("module_exitsucessful!!!\n");

}

/*?宏实现?*/

module_init(power_init_module);

module_exit(power_cleanup_module);

/*?开源许可声明?*/

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Zou");

应用代码:

#include

#include

#include

#include

#include

#include

staticint?fd;

/*?内核产生异步通知,调用该应用层函数处理?*/

voidsigterm_handler(int?signo)

{

printf("app?irq?work?!!!\n");

}

intmain(void)

{

int?oflags;

fd=open("/dev/powerdetect",O_RDWR);??//打开设备文件

/*?启动异步通知信号驱动机制?*/

signal(SIGIO,?sigterm_handler);

fcntl(fd,?F_SETOWN,?getpid());

oflags?=?fcntl(fd,?F_GETFL);

fcntl(fd,?F_SETFL,?oflags?|?FASYNC);

/*建立一个死循环,防止程序结束?*/

while(1)

{

printf("sleep\n");

usleep(200000);??//2ms

}

close(fd);

return?0;

}

将驱动编译成模块,上电加载并执行应用程序后,将电压缓慢下调至掉电临界点。触发GPIO下降沿中断,并提供应用程序掉电信号。

?

图1..2掉电检测

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OOMx6uKw3Ah1VuN8gWK38CVA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com