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

相关文章

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

如何编写Linux PCIe设备驱动器 之二

如何编写Linux PCIe设备驱动器 之二 功能(capability)集功能(capability)APIs通过pci_bus_read_config完成功能存取功能APIs参数pos常量值PCI功能结构 PCI功能IDMSI功能电源功率管理功能 功能(capability)集 功能(capability)APIs int pcie_capability_read_wo

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。