Linux驱动分析之RTC驱动

简介: 前面《Linux驱动分析之RTC框架》分析了RTC的基本框架,接下来拿个RTC驱动实例来分析一下。

前言

前面《Linux驱动分析之RTC框架》分析了RTC的基本框架,接下来拿个RTC驱动实例来分析一下。



RTC驱动分析

Linux版本:5.11

RTC设备: DS1302


(1) 加载和卸载函数

//DTS匹配staticconststructof_device_idds1302_dt_ids[] = {
  { .compatible="maxim,ds1302", },
  { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
staticstructspi_driverds1302_driver= {
  .driver.name="rtc-ds1302",
  .driver.of_match_table=of_match_ptr(ds1302_dt_ids),
  .probe=ds1302_probe,
  .remove=ds1302_remove,
};
//封住了module_init()和module_exit()module_spi_driver(ds1302_driver);

ds1302是一个SPI接口的RTC芯片。所以它的module_init是按照SPI接口框架实现的。


(2) probe()函数

staticintds1302_probe(structspi_device*spi)
{
structrtc_device*rtc;
u8addr;
u8buf[4];
u8*bp;
intstatus;
//检查SPI参数设置if (spi->bits_per_word&& (spi->bits_per_word!=8)) {
dev_err(&spi->dev, "bad word length\n");
return-EINVAL;
  } elseif (spi->max_speed_hz>2000000) {
dev_err(&spi->dev, "speed is too high\n");
return-EINVAL;
  } elseif (spi->mode&SPI_CPHA) {
dev_err(&spi->dev, "bad mode\n");
return-EINVAL;
  }
//省略ds1302的初始化spi_set_drvdata(spi, spi);
//注册RTC设备rtc=devm_rtc_device_register(&spi->dev, "ds1302",
&ds1302_rtc_ops, THIS_MODULE);
//.....return0;
}

probe()主要就是ds1302的初始化,我们省略掉这部分,它其实就是通过spi接口去设置ds1302的寄存器。

初始化完成之后就是调用  devm_rtc_device_register   进行rtc设备的注册,这个我们在前面的RTC框架中讲过。注册的函数中有一个 ds1302_rtc_ops 参数,它包含了操作RTC的接口函数。


(3)RTC操作函数

staticconststructrtc_class_opsds1302_rtc_ops= {
  .read_time=ds1302_rtc_get_time, //获取时间  .set_time=ds1302_rtc_set_time,  //设置时间};
  • ds1302_rtc_set_time
staticintds1302_rtc_set_time(structdevice*dev, structrtc_time*time)
{
structspi_device*spi=dev_get_drvdata(dev);
u8buf[1+RTC_CLCK_LEN];
u8*bp;
intstatus;
/* 使能写 */bp=buf;
*bp++=RTC_ADDR_CTRL<<1|RTC_CMD_WRITE;
*bp++=RTC_CMD_WRITE_ENABLE;
status=spi_write_then_read(spi, buf, 2,
NULL, 0);
if (status)
returnstatus;
/*设置寄存器地址和写入的数据 */bp=buf;
*bp++=RTC_CLCK_BURST<<1|RTC_CMD_WRITE;
*bp++=bin2bcd(time->tm_sec);
*bp++=bin2bcd(time->tm_min);
*bp++=bin2bcd(time->tm_hour);
*bp++=bin2bcd(time->tm_mday);
*bp++=bin2bcd(time->tm_mon+1);
*bp++=time->tm_wday+1;
*bp++=bin2bcd(time->tm_year%100);
*bp++=RTC_CMD_WRITE_DISABLE;
//使用SPI写入时间数据returnspi_write_then_read(spi, buf, sizeof(buf),
NULL, 0);
}
  • ds1302_rtc_get_time
staticintds1302_rtc_get_time(structdevice*dev, structrtc_time*time)
{
structspi_device*spi=dev_get_drvdata(dev);
u8addr=RTC_CLCK_BURST<<1|RTC_CMD_READ;
u8buf[RTC_CLCK_LEN-1];
intstatus;
//从寄存器中读取时间值status=spi_write_then_read(spi, &addr, sizeof(addr),
buf, sizeof(buf));
if (status<0)
returnstatus;
//转成结构体保存time->tm_sec=bcd2bin(buf[RTC_ADDR_SEC]);
time->tm_min=bcd2bin(buf[RTC_ADDR_MIN]);
time->tm_hour=bcd2bin(buf[RTC_ADDR_HOUR]);
time->tm_wday=buf[RTC_ADDR_DAY] -1;
time->tm_mday=bcd2bin(buf[RTC_ADDR_DATE]);
time->tm_mon=bcd2bin(buf[RTC_ADDR_MON]) -1;
time->tm_year=bcd2bin(buf[RTC_ADDR_YEAR]) +100;
return0;
}

读写函数都比较简单,就是操作寄存器即可。



总结

RTC的驱动其实很简单,就是总线(I2C, SPI等)加上RTC驱动框架,其他的就是芯片寄存器的操作了,这部分只需要根据芯片手册来实现即可。

相关文章
|
1月前
|
Linux API 调度
Linux系统驱动跟裸机驱动的区别
Linux系统驱动跟裸机驱动的区别
29 0
|
1月前
|
Linux Android开发
嵌入式linux中Framebuffer 驱动程序框架分析
嵌入式linux中Framebuffer 驱动程序框架分析
27 0
|
1月前
|
监控 Shell Linux
【Shell 命令集合 网络通讯 】Linux 分析串口的状态 statserial命令 使用指南
【Shell 命令集合 网络通讯 】Linux 分析串口的状态 statserial命令 使用指南
33 0
|
1月前
|
存储 缓存 Linux
【Shell 命令集合 磁盘维护 】Linux 设置和查看硬盘驱动器参数 hdparm命令使用教程
【Shell 命令集合 磁盘维护 】Linux 设置和查看硬盘驱动器参数 hdparm命令使用教程
36 0
|
12天前
|
Linux Go
Linux命令Top 100驱动人生! 面试必备
探索Linux命令不再迷茫!本文分10部分详解20个基础命令,带你由浅入深掌握文件、目录管理和文本处理。 [1]: <https://cloud.tencent.com/developer/article/2396114> [2]: <https://pan.quark.cn/s/865a0bbd5720> [3]: <https://yv4kfv1n3j.feishu.cn/docx/MRyxdaqz8ow5RjxyL1ucrvOYnnH>
64 0
|
25天前
|
Prometheus 监控 数据可视化
linux分析方法与技巧
【4月更文挑战第3天】在Linux环境中,进行日志分析和系统性能分析的关键方法包括:使用`cat`, `less`, `tail`查看和过滤日志,`logrotate`管理日志文件,`rsyslog`或`syslog-ng`聚合日志,以及通过`top`, `mpstat`, `pidstat`, `free`, `iostat`, `netstat`, `strace`, `sar`, `dstat`等工具监控CPU、内存、磁盘I/O和网络。对于高级分析,可利用Brendan Gregg的性能工具,以及Grafana、Prometheus等可视化工具。
19 2
linux分析方法与技巧
|
26天前
|
Linux
Linux驱动运行灯 Heartbeat
Linux驱动运行灯 Heartbeat
12 0
|
1月前
|
监控 Linux Shell
Linux 进程问题调查探秘:分析和排查频繁创建进程问题
Linux 进程问题调查探秘:分析和排查频繁创建进程问题
39 0
|
1月前
|
消息中间件 存储 网络协议
Linux IPC 进程间通讯方式的深入对比与分析和权衡
Linux IPC 进程间通讯方式的深入对比与分析和权衡
69 0
|
1月前
|
存储 监控 Linux
Linux 使用getrusage系统调用获取cpu信息:一个C++实例分析
Linux 使用getrusage系统调用获取cpu信息:一个C++实例分析
50 0