S3C6410实时时钟RTC 秒字符设备

2024-02-23 08:48

本文主要是介绍S3C6410实时时钟RTC 秒字符设备,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

/*《linux 设备驱动开发详解》

驱动程序

*/

 

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define SECOND_MAJOR 248    /*预设的second的主设备号*/                      
static int second_major = SECOND_MAJOR;                                     
/*second设备结构体*/                                                        
struct second_dev {                                                         
struct cdev cdev; /*cdev结构体*/                                          
atomic_t counter;/* 一共经历了多少秒?*/                                  
struct timer_list s_timer; /*设备要使用的定时器*/                         
};                                                                          
struct second_dev *second_devp; /*设备结构体指针*/                          
/*定时器处理函数*/                                                          
static void second_timer_handle(unsigned long arg)                          
{                                                                           
mod_timer(&second_devp->s_timer,jiffies + HZ);                            
atomic_inc(&second_devp->counter);                                        
printk(KERN_NOTICE "current jiffies is %ld\n", jiffies);                  
}                                                                           
/*文件打开函数*/                                                            
int second_open(struct inode *inode, struct file *filp)                     
{                                                                           
/*初始化定时器*/                                                          
init_timer(&second_devp->s_timer);                                        
second_devp->s_timer.function = &second_timer_handle;                     
second_devp->s_timer.expires = jiffies + HZ;                              
add_timer(&second_devp->s_timer); /*添加(注册)定时器*/                  
atomic_set(&second_devp->counter,0); //计数清0                            
return 0;                                                                 
}                                                                           
/*文件释放函数*/                                                            
int second_release(struct inode *inode, struct file *filp)                  
{                                                                           
del_timer(&second_devp->s_timer);                                         
return 0;                                                                 
}                                                                           
/*读函数*/                                                                  
static ssize_t second_read(struct file *filp, char __user *buf, size_t count,
loff_t *ppos)                                                             
{                                                                           
int counter;                                                              
counter = atomic_read(&second_devp->counter);                             
if(put_user(counter, (int*)buf))                                          
return - EFAULT;                                                        
else                                                                      
return sizeof(unsigned int);                                            
}                                                                           
/*文件操作结构体*/                                                          
static const struct file_operations second_fops = {                         
.owner = THIS_MODULE,                                                     
.open = second_open,                                                      
.release = second_release,                                                
.read = second_read,                                                      
};                                                                          
/*初始化并注册cdev*/                                                        
static void second_setup_cdev(struct second_dev *dev, int index)            
{                                                                           
int err, devno = MKDEV(second_major, index);                              
cdev_init(&dev->cdev, &second_fops);                                      
dev->cdev.owner = THIS_MODULE;                                            
err = cdev_add(&dev->cdev, devno, 1);                                     
if (err)                                                                  
printk(KERN_NOTICE "Error %d adding LED%d", err, index);                
}                                                                           
/*设备驱动模块加载函数*/                                                    
int second_init(void)                                                       
{                                                                           
int ret;                                                                  
dev_t devno = MKDEV(second_major, 0);                                     
/* 申请设备号*/                                                           
if (second_major)                                                         
ret = register_chrdev_region(devno, 1, "second");                       
else { /* 动态申请设备号 */                                               
ret = alloc_chrdev_region(&devno, 0, 1, "second");                      
second_major = MAJOR(devno);                                            
}                                                                         
if (ret < 0)                                                              
return ret;                                                             
/* 动态申请设备结构体的内存*/                                             
second_devp = kmalloc(sizeof(struct second_dev), GFP_KERNEL);             
if (!second_devp) {   /*申请失败*/                                        
ret =  - ENOMEM;                                                        
goto fail_malloc;                                                       
}                                                                         
memset(second_devp, 0, sizeof(struct second_dev));                        
second_setup_cdev(second_devp, 0);                                        
return 0;                                                                 
fail_malloc:
unregister_chrdev_region(devno, 1);
return ret;                          
}                                                                           
/*模块卸载函数*/                                                            
void second_exit(void)                                                      
{                                                                           
cdev_del(&second_devp->cdev);   /*注销cdev*/                              
kfree(second_devp);     /*释放设备结构体内存*/                            
unregister_chrdev_region(MKDEV(second_major, 0), 1); /*释放设备号*/       
}                                                                           
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");                            
MODULE_LICENSE("Dual BSD/GPL");                                             
module_param(second_major, int, S_IRUGO);                                   
module_init(second_init);                                                   
module_exit(second_exit);            

 

 

/*应用程序*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
main()
{
int fd;
int counter = 0;
int old_counter = 0;
/*打开/dev/second设备文件*/
fd = open("/dev/second", O_RDONLY);
if (fd != - 1) {
while (1) {
read(fd,&counter, sizeof(unsigned int));/* 读目前经历的秒数 */
if(counter!=old_counter) { 
printf("seconds after open /dev/second :%d\n",counter);
old_counter = counter;
} 
}   
} else {
printf("Device open failure\n");
}
}


这篇关于S3C6410实时时钟RTC 秒字符设备的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/738089

相关文章

SpringBoot+Vue3整合SSE实现实时消息推送功能

《SpringBoot+Vue3整合SSE实现实时消息推送功能》在日常开发中,我们经常需要实现实时消息推送的功能,这篇文章将基于SpringBoot和Vue3来简单实现一个入门级的例子,下面小编就和大... 目录前言先大概介绍下SSE后端实现(SpringBoot)前端实现(vue3)1. 数据类型定义2.

录音功能在哪里? 电脑手机等设备打开录音功能的技巧

《录音功能在哪里?电脑手机等设备打开录音功能的技巧》很多时候我们需要使用录音功能,电脑和手机这些常用设备怎么使用录音功能呢?下面我们就来看看详细的教程... 我们在会议讨论、采访记录、课堂学习、灵感创作、法律取证、重要对话时,都可能有录音需求,便于留存关键信息。下面分享一下如何在电脑端和手机端上找到录音功能

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字