驱动程序设计 利用RTC显示年月日时分秒到终端 7.11

文章描述了如何编写一个RTC(实时时钟)驱动程序,该驱动用于控制RTC模块,实现年月日时分秒的显示。代码包括了设备映射、初始化、读取RTC数据以及在用户端的设备文件操作。示例代码使用了Linux内核的驱动模型,包括ioremap函数进行内存映射,以及定义了读取RTC数据的结构体和操作函数。
摘要由CSDN通过智能技术生成

驱动控制RTC

  1. 用户需求:写一个RTC时钟控制的驱动,实现RTC显示年月日时分秒到用户端

  2. 驱动需求:设备:RTC模块 功能:打印显示

  3. 寄存器操作:

    1. 原理图: 设备–>pin–>设备控制芯片

      ​ 驱动需求 --> 设备需求

    2. 芯片手册:设备控制芯片–>寄存器

驱动程序

/*===============================================
*   文件名称:modRtc.c
*   创 建 者: memories
*   创建日期:2023年07月10日
*   描    述:have a nice day
================================================*/
//头文件
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include "rtc.h"

#define MA 300
#define MI 0

static dev_t no = 0;
static unsigned count = 1;
static const char *name = "mydev";
static struct cdev mydev;
static int *rtccon     = NULL;
static int *bcdsec     = NULL;
static int *bcdmin     = NULL;
static int *bcdhour    = NULL;
static int *bcddayweek = NULL;
static int *bcdday     = NULL;
static int *bcdmon     = NULL;
static int *bcdyear    = NULL;

void addr_map(void)
{
    rtccon     = ioremap(RTCCON,4);
    bcdsec     = ioremap(BCDSEC,4);
    bcdmin     = ioremap(BCDMIN,4);
    bcdhour    = ioremap(BCDHOUR,4);
    bcddayweek = ioremap(BCDDAYWEEK,4);
    bcdday     = ioremap(BCDDAY,4);
    bcdmon     = ioremap(BCDMON,4);
    bcdyear    = ioremap(BCDYEAR,4);
}

void dev_init(void)
{
    writel(readl(rtccon)|(0x1),rtccon);
    writel(0x46,bcdsec);
    writel(0x23,bcdmin);
    writel(0x14,bcdhour);
    writel(0x1,bcddayweek);
    writel(0x11,bcdday);
    writel(0x4,bcdmon);
    writel(0x023,bcdyear);

}

void addr_unmap(void)
{
    iounmap(rtccon);
    iounmap(bcdsec);
    iounmap(bcdmin);
    iounmap(bcdhour);
    iounmap(bcddayweek);
    iounmap(bcdday);
    iounmap(bcdmon);
    iounmap(bcdyear);
}

struct RTC mydata(void)
{
    struct RTC rtc;
    rtc.sec     = readl(bcdsec);
    rtc.min     = readl(bcdmin);
    rtc.hour    = readl(bcdhour);
    rtc.dayweek = readl(bcddayweek);
    rtc.year    = readl(bcdyear);
    rtc.mon     = readl(bcdmon);
    rtc.day     = readl(bcdday);
    return rtc;
}

/*
时间设置之后会一直走,不用open和release
int myopen (struct inode *pi, struct file *pf)
{
    printk("open success\n");
    return 0;
}
int myrelease (struct inode *pi, struct file *pf)
{
    printk("release success\n");
    writel(readl(rtccon)&~(0x1),rtccon);
    return 0;
}
*/
ssize_t myread(struct file *pf, char __user *rbuf, size_t len, loff_t *poff)
{
    int ret = -1;
    struct RTC rtc = mydata();
    ret = copy_to_user(rbuf,&rtc,sizeof(struct RTC));
    if(ret !=0 )
    {
        printk("copy is failed\n");
        return -1;
    }
    return len;
}

static struct file_operations myfops={
   // .open = myopen,
   // .release = myrelease,
    .read = myread,
};
//初始化
int myinit(void)
{
    int ret;
    //向上内核
    no = MKDEV(MA,MI);
    //注册设备号
    ret = register_chrdev_region(no,count,name);
    if(ret !=0)
    {
        printk("reg is error\n");
        return -1;
    }
    //设备操作初始化
    cdev_init(&mydev,&myfops);
    //添加设备
    ret = cdev_add(&mydev,no,count);
    if(ret != 0)
    {
        unregister_chrdev_region(no,count);
        return -1;
    }
    //向下驱动
    //1.映射
    addr_map();
    //2.寄存器初始化
    dev_init();
    printk("my init is ok\n");
    return 0;
}
//退出
void myexit(void)
{
    //删除设备
    cdev_del(&mydev);
    //注销设备号
    unregister_chrdev_region(no,count);
    //解除映射
    addr_unmap();
    printk("my exit is ok\n");
    return ;
}
module_init(myinit);
module_exit(myexit);
//信息
MODULE_LICENSE("GPL");

应用程序

/*===============================================
*   文件名称:rtc.c
*   创 建 者: memories
*   创建日期:2023年07月10日
*   描    述:have a nice day
================================================*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include "rtc.h"

int main(int argc, char *argv[])
{ 
    int fd = open("/dev/mydev",O_RDWR);
    if(fd < 0)
    {
        printf("open is failed\n");
        return -1;
    }
    while(1)
    {
        int ret;
        struct RTC rtc;
        ret = read(fd,&rtc,sizeof(struct RTC));
        if(ret < 0)
        {
            perror("read");
            return -1;
        }
        printf("2%03x-%x-%x %x %x:%x:%x\n",rtc.year,rtc.mon,rtc.day,rtc.dayweek,rtc.hour,rtc.min,rtc.sec);
        sleep(1);
    }
    close(fd);
    return 0;
} 

/*===============================================
*   文件名称:rtc.h
*   创 建 者: memories
*   创建日期:2023年07月10日
*   描    述:have a nice day
================================================*/
#ifndef __rtc_H_
#define __rtc_H_

#define RTCCON     0x10070040
#define BCDSEC     0x10070070
#define BCDMIN     0x10070074
#define BCDHOUR    0x10070078
#define BCDDAYWEEK 0x10070080
#define BCDDAY     0x1007007C
#define BCDMON     0x10070084
#define BCDYEAR    0x10070088


struct RTC{
      int sec;
      int min;   
      int hour;  
      int dayweek; 
      int year;  
      int mon;
      int day;   
 };  


#endif
打开设备文件失败的原因:
1.文件没有创建  ls-l /dev/mydev 检查文件有没有和设备号
	open("/dev/mydev")
2.驱动没有加载  lsmod
	sys_open()   file-->no-->mydev
3.open(fops->open)返回失败

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独memories

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值