当前位置:网站首页>Openwrt adds RTC (mcp7940 I2C bus) drive details
Openwrt adds RTC (mcp7940 I2C bus) drive details
2022-07-27 16:01:00 【xhoufei2010】
One 、 Hardware platform
1.1 controller :MT7620(A9 kernel )1.2 RTC chip :MCP7940(I2C Bus )
Two 、 software platform
2.1、 development environment :Ubuntu12.04
2.2、 Software version :openwrt official 15.05 edition SDK Development kit (CHAOS CALMER 15.05 edition )
3、 ... and 、 Functional specifications
The target chip selected in this article is MT7620,profile The choice is “Xiaomi MiWiFi Mini ”.
3.1、 stay openwrt On the system , transplant mcp7940 Of rtc Chip driver .
3.2、 stay openwrt On the system , Add to i2c Bus support .
matters needing attention :openwrt The system is strange , stay menuconfig Configuration in progress , Configured with i2c, Still can't support . Additional modifications are required “*.dts” file , Ability to support i2c Bus .
Four 、 Operation steps
4.1 Add system for i2c Bus support
For the system, add i2c Bus support , Need modification 2 A place to
1、openwrt Add to i2c Support .
2、 modify dts file , Add to i2c Support .
[ 18.100000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.110000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.120000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.130000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.140000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.150000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.160000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)
[ 18.170000] i2c_core: exports duplicate symbol __i2c_transfer (owned by kernel)4.1.1 To configure openwrt Of I2C
stay openwrt Under the table of contents , perform “make menuconfig” command .
Enter menu Kernel modules --->I2C support --->, In the menu options , Configuration is shown in figure 4-1 Shown .

chart 4-1 I2C support
4.1.2 Configure the target chip I2C
stay openwrt Under the table of contents , perform "make kernel_menuconfig" command , Configure the target chip kernel .
Enter menu , Device Drivers ---> I2C support --->, Pictured 4-2 Shown .

chart 4-2 Target chip I2C Bus configuration
In the figure 4-2 in , choice “I2C Hardware Bus support ---> ”, To configure I2C Hardware bus support , choice “Ralink I2C Controller”, Pictured 4-3 Shown .

chart 4-3 I2C Hardware Bus support
4.1.3 modify DTS The configuration file
default openwrt System , No, right I2C Bus support , I need to modify myself DTS The configuration file . Because the chip selected in this article is MT7620A, The goal is profile The choice is “Xiaomi MiWiFi Mini”, Therefore, the document to be modified is “XIAOMI-MIWIFI-MINI.dts”
The path of the file is “openwrt/target/linux/ramips/dts/XIAOMI-MIWIFI-MINI.dts”
Before modification DTS file :
[email protected] {
gpio0: [email protected] {
status = "okay";
};
gpio1: [email protected] {
status = "okay";
};
gpio2: [email protected] {
status = "okay";
};
[email protected] {
status = "okay";
[email protected] {
stay palmbus In nodes , increase MT7620A Yes I2C Bus and RTC Chip support , Modified DTS file :
[email protected] {
gpio0: [email protected] {
status = "okay";
};
gpio1: [email protected] {
status = "okay";
};
gpio2: [email protected] {
status = "okay";
};
[email protected] {
compatible ="ralink,mt7620a-i2c", "ralink,rt2880-i2c";
reg= <0x900 0x100>;
resets = <&rstctrl 16>;
reset-names= "i2c";
#address-cells = <1>;
#size-cells= <0>;
status= "okay";
[email protected] {
compatible = "mcp,mcp7940";
reg = <0x6f>;
};
};
[email protected] {
status = "okay";
[email protected] {
1、[email protected] by MT7620A Of I2C node ;
2、 about MCP7940 chip , By looking up the chip manual , Know that its mailing address is 0x6f. If you need to change to another chip , Then the corresponding address 0x6f Change it to its corresponding address .
3、 about RTC The name description of also needs attention ,compatible = "mcp,mcp7940", among mcp7940 Corresponding to this article 5.1 chapter , The driver rtc_mcp7940.c pass the civil examinations 93 That's ok ,“struct i2c_device_id” in The name of . If the names don't match , Will cause the driver to execute to probe Function failed , Lead to rtc Drive load loss Defeat .
static const struct i2c_device_id mcp7940_id[] = {
{ "mcp7940", mcp7940 },
{ }
};4、 If I2C The pin of , No settings , By default, it may work in GPIO Pattern , Particular attention ! In this paper RTC The driver , take I2C The pin of is set to I2C Pattern , So in DTS In file , No more settings I2C The working mode of the pin . If your own RTC In driver , No settings I2C Pin , Please be there. DTS Set its working as I2C Pattern , Lest it work by default GPIO In the pattern !
[email protected] {
compatible ="ralink,mt7620a-i2c", "ralink,rt2880-i2c";
reg= <0x900 0x100>;
resets = <&rstctrl 16>;
reset-names= "i2c";
#address-cells = <1>;
#size-cells= <0>;
status= "okay";
[email protected] {
compatible = "mcp,mcp7940";
reg = <0x6f>;
};
};
If necessary, change to ds1307 chip , You just need to put rtc Address and comatible You can modify it. .ds1307 The mailing address of is 0x68, Then modify as follows :
[email protected] {
compatible = "dallas,ds1307";
reg = <0x68>;
};4.2 Add to RTC Support for
4.2.1 modify target file
The system is in ./scripts/medatata.pl Judge and deal with RTC_SUPPORT switch , After analysis , It turned out to be target/linux/ramips/mt7620/target.mk in , Put the original content :
FEATURES+=usbIt is amended as follows :
FEATURES+=usb rtcYou can open mt7620 Yes rtc Support for . After the modification ,target.mk The contents are as follows :
#
# Copyright (C) 2009 OpenWrt.org
#
SUBTARGET:=mt7620
BOARDNAME:=MT7620 based boards
ARCH_PACKAGES:=ramips_24kec
FEATURES+=usb rtc
CPU_TYPE:=24kec
CPU_SUBTYPE:=dsp
DEFAULT_PACKAGES += kmod-rt2800-pci kmod-rt2800-soc
define Target/Description
Build firmware images for Ralink MT7620 based boards.
endef
4.2.2 Configure the kernel RTC
1、 stay openwrt Of SDK In the development package , perform “make kernel_menuconfig” command .
In the pop-up menu “Linux/mips 3.18.29 Kernel Configuration” in , choice “Device Drivers ---> Real Time Clock --->”, Turn on RTC Function options , Pictured 4-4 Shown .

chart 4-4 Turn on RTC function
2、 Get into “ Real Time Clock--->”, Yes RTC To configure
Configuration is shown in figure 4-5 Shown , among :
(1) Remove options “Set system time from RTC on startup and resume”, Don't start it when you start it RTC drive . Because in this article , Plan to start after , Then mount by yourself RTC drive . If it is not mounted at the beginning RTC drive , Turn on this option , An error message will appear “drivers/rtc/hctosys.c: unable to open rtc device (rtc0)”.
(2) about “RTC debug support”, It depends on personal preference , After opening , You can see RTC Debugging information for .

chart 4-5 RTC To configure
5、 ... and 、RTC Program
5.1 RTC The driver
The file name corresponding to the driver is :rtc_mcp7940.c, The procedure is as follows :
/*
* rtc-mcp7940.c - RTC driver for some mostly-compatible I2C chips.
*
* Copyright (C) 2005 James Chapman (ds1337 core)
* Copyright (C) 2006 David Brownell
* Copyright (C) 2009 Matthias Fuchs (rx8025 support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/string.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#define RALINK_SYSCTL_BASE 0xB0000000
#define RALINK_TIMER_BASE 0xB0000100
#define RALINK_INTCL_BASE 0xB0000200
#define RALINK_SYSCTL_ADDR RALINK_SYSCTL_BASE // system control
#define RALINK_REG_GPIOMODE (RALINK_SYSCTL_ADDR + 0x60) // GPIO MODE
#define __devexit
#define __devinitdata
#define __devinit
#define __devexit_p
/* We can't determine type by probing, but if we expect pre-Linux code
* to have set the chip up as a clock (turning on the oscillator and
* setting the date and time), Linux can ignore the non-clock features.
* That's a natural job for a factory or repair bench.
*/
enum ds_type
{
mcp7940,
};
/* RTC registers don't differ much, except for the century flag */
#define MCP7940_REG_SECS 0x00 /* 00-59 */
#define MCP7940_BIT_CH 0x80
#define MCP7940_BIT_ST 0x80
#define MCP7940_REG_MIN 0x01 /* 00-59 */
#define MCP7940_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
#define MCP7940_BIT_12HR 0x40 /* in REG_HOUR */
#define MCP7940_BIT_PM 0x20 /* in REG_HOUR */
#define MCP7940_REG_WDAY 0x03 /* 01-07 */
#define MCP7940_REG_MDAY 0x04 /* 01-31 */
#define MCP7940_REG_MONTH 0x05 /* 01-12 */
#define MCP7940_REG_YEAR 0x06 /* 00-99 */
#define MCP7940_BIT_VBATEN 0x08
/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
* start at 7, and they differ a LOT. Only control and status matter for
* basic RTC date and time functionality; be careful using them.
*/
#define MCP7940_REG_CONTROL 0x07
#define MCP7940_BIT_OUT 0x80
#define MCP7940_BIT_SQWE 0x10
#define MCP7940_BIT_RS1 0x02
#define MCP7940_BIT_RS0 0x01
struct mcp7940 {
u8 offset; /* register's offset */
u8 regs[11];
enum ds_type type;
unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
#define HAS_ALARM 1 /* bit 1 == irq claimed */
struct i2c_client *client;
struct rtc_device *rtc;
struct work_struct work;
s32 (*read_block_data)(struct i2c_client *client, u8 command,
u8 length, u8 *values);
s32 (*write_block_data)(struct i2c_client *client, u8 command,
u8 length, const u8 *values);
};
struct chip_desc {
unsigned nvram56:1;
unsigned alarm:1;
};
static const struct i2c_device_id mcp7940_id[] = {
{ "mcp7940", mcp7940 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp7940_id);
/*----------------------------------------------------------------------*/
#define BLOCK_DATA_MAX_TRIES 10
static s32 mcp7940_read_block_data_once(struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
s32 i, data;
for (i = 0; i < length; i++) {
data = i2c_smbus_read_byte_data(client, command + i);
if (data < 0)
return data;
values[i] = data;
}
return i;
}
static s32 mcp7940_read_block_data(struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
s32 ret;
int tries = 0;
dev_dbg(&client->dev, "mcp7940_read_block_data (length=%d)\n", length);
ret = mcp7940_read_block_data_once(client, command, length, values);
if (ret < 0)
return ret;
do {
if (++tries > BLOCK_DATA_MAX_TRIES) {
dev_err(&client->dev,
"mcp7940_read_block_data failed\n");
return -EIO;
}
memcpy(oldvalues, values, length);
ret = mcp7940_read_block_data_once(client, command, length,
values);
if (ret < 0)
return ret;
} while (memcmp(oldvalues, values, length));
return length;
}
static s32 mcp7940_write_block_data(struct i2c_client *client, u8 command,
u8 length, const u8 *values)
{
u8 currvalues[I2C_SMBUS_BLOCK_MAX];
int tries = 0;
dev_dbg(&client->dev, "mcp7940_write_block_data (length=%d)\n", length);
do
{
s32 i, ret;
if (++tries > BLOCK_DATA_MAX_TRIES) {
dev_err(&client->dev,
"mcp7940_write_block_data failed\n");
return -EIO;
}
for (i = 0; i < length; i++) {
ret = i2c_smbus_write_byte_data(client, command + i,
values[i]);
if (ret < 0)
return ret;
}
ret = mcp7940_read_block_data_once(client, command, length,
currvalues);
if (ret < 0)
return ret;
} while (memcmp(currvalues, values, length));
return length;
}
static int mcp7940_get_time(struct device *dev, struct rtc_time *t)
{
struct mcp7940 *mcp7940 = dev_get_drvdata(dev);
int tmp;
/* read the RTC date and time registers all at once */
tmp = mcp7940->read_block_data(mcp7940->client,
mcp7940->offset, 7, mcp7940->regs);
if (tmp != 7) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
}
dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
"read",
mcp7940->regs[0], mcp7940->regs[1],
mcp7940->regs[2], mcp7940->regs[3],
mcp7940->regs[4], mcp7940->regs[5],
mcp7940->regs[6]);
t->tm_sec = bcd2bin(mcp7940->regs[MCP7940_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(mcp7940->regs[MCP7940_REG_MIN] & 0x7f);
tmp = mcp7940->regs[MCP7940_REG_HOUR] & 0x3f;
t->tm_hour = bcd2bin(tmp);
t->tm_wday = bcd2bin(mcp7940->regs[MCP7940_REG_WDAY] & 0x07) - 1;
t->tm_mday = bcd2bin(mcp7940->regs[MCP7940_REG_MDAY] & 0x3f);
tmp = mcp7940->regs[MCP7940_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
t->tm_year = bcd2bin(mcp7940->regs[MCP7940_REG_YEAR]) + 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"read", t->tm_sec, t->tm_min,
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
/* initial clock setting can be undefined */
return rtc_valid_tm(t);
}
static int mcp7940_set_time(struct device *dev, struct rtc_time *t)
{
struct mcp7940 *mcp7940 = dev_get_drvdata(dev);
int result;
int tmp;
u8 *buf = mcp7940->regs;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
"write", t->tm_sec, t->tm_min,
t->tm_hour, t->tm_mday,
t->tm_mon, t->tm_year, t->tm_wday);
buf[MCP7940_REG_SECS] = bin2bcd(t->tm_sec);
buf[MCP7940_REG_MIN] = bin2bcd(t->tm_min);
buf[MCP7940_REG_HOUR] = bin2bcd(t->tm_hour);
buf[MCP7940_REG_WDAY] = bin2bcd(t->tm_wday + 1);
buf[MCP7940_REG_MDAY] = bin2bcd(t->tm_mday);
buf[MCP7940_REG_MONTH] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
buf[MCP7940_REG_YEAR] = bin2bcd(tmp);
buf[MCP7940_REG_SECS] |= MCP7940_BIT_ST;
buf[MCP7940_REG_WDAY] |= MCP7940_BIT_VBATEN;
dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x\n",
"write", buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6]);
result = mcp7940->write_block_data(mcp7940->client,
mcp7940->offset, 7, buf);
if (result < 0)
{
dev_err(dev, "%s error %d\n", "write", result);
return result;
}
return 0;
}
static int mcp7940_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rtc_time time;
void __user *uarg = (void __user *) arg;
switch (cmd)
{
case RTC_RD_TIME:
mcp7940_get_time(dev, &time);
if (copy_to_user(uarg, &time, sizeof(time)))
{
printk("RTC_RD_TIME error, can not copy to user\n");
return -EFAULT;
}
break;
case RTC_SET_TIME:
if (copy_from_user(&time, uarg, sizeof(time)))
{
printk("RTC_SET_TIME error, can not copy from user\n");
return -EFAULT;
}
mcp7940_set_time(dev, &time);
break;
default:
return -ENOIOCTLCMD;
}
return 0;
}
static const struct rtc_class_ops mcp7940_rtc_ops =
{
.read_time = mcp7940_get_time,
.set_time = mcp7940_set_time,
.ioctl = mcp7940_ioctl,
};
/*----------------------------------------------------------------------*/
static struct i2c_driver mcp7940_driver;
static int __devinit mcp7940_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct mcp7940 *mcp7940;
int err = -ENODEV;
int tmp;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
unsigned char *buf;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
if (!(mcp7940 = kzalloc(sizeof(struct mcp7940), GFP_KERNEL)))
return -ENOMEM;
i2c_set_clientdata(client, mcp7940);
mcp7940->client = client;
mcp7940->type = id->driver_data;
mcp7940->offset = 0;
buf = mcp7940->regs;
if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
mcp7940->read_block_data = i2c_smbus_read_i2c_block_data;
mcp7940->write_block_data = i2c_smbus_write_i2c_block_data;
} else {
mcp7940->read_block_data = mcp7940_read_block_data;
mcp7940->write_block_data = mcp7940_write_block_data;
}
read_rtc:
/* read RTC registers */
tmp = mcp7940->read_block_data(mcp7940->client, 0, 8, buf);
if (tmp != 8)
{
pr_debug("read error %d\n", tmp);
err = -EIO;
goto exit_free;
}
/* minimal sanity checking; some chips (like DS1340) don't
* specify the extra bits as must-be-zero, but there are
* still a few values that are clearly out-of-range.
*/
tmp = mcp7940->regs[MCP7940_REG_SECS];
/* make sure that the backup battery is enabled */
if (!(mcp7940->regs[MCP7940_REG_WDAY] & MCP7940_BIT_VBATEN)) {
i2c_smbus_write_byte_data(client, MCP7940_REG_WDAY,
mcp7940->regs[MCP7940_REG_WDAY]
| MCP7940_BIT_VBATEN);
}
/* clock halted? turn it on, so clock can tick. */
if (!(tmp & MCP7940_BIT_ST)) {
i2c_smbus_write_byte_data(client, MCP7940_REG_SECS,
MCP7940_BIT_ST);
dev_warn(&client->dev, "SET TIME!\n");
goto read_rtc;
}
tmp = mcp7940->regs[MCP7940_REG_HOUR];
switch (mcp7940->type) {
default:
if (!(tmp & MCP7940_BIT_12HR))
break;
/* Be sure we're in 24 hour mode. Multi-master systems
* take note...
*/
tmp = bcd2bin(tmp & 0x1f);
if (tmp == 12)
tmp = 0;
if (mcp7940->regs[MCP7940_REG_HOUR] & MCP7940_BIT_PM)
tmp += 12;
i2c_smbus_write_byte_data(client,
MCP7940_REG_HOUR,
bin2bcd(tmp));
}
mcp7940->rtc = rtc_device_register(client->name, &client->dev,
&mcp7940_rtc_ops, THIS_MODULE);
if (IS_ERR(mcp7940->rtc)) {
err = PTR_ERR(mcp7940->rtc);
dev_err(&client->dev,
"unable to register the class device\n");
goto exit_free;
}
return 0;
exit_free:
kfree(mcp7940);
return err;
}
static int __devexit mcp7940_remove(struct i2c_client *client)
{
struct mcp7940 *mcp7940 = i2c_get_clientdata(client);
rtc_device_unregister(mcp7940->rtc);
kfree(mcp7940);
return 0;
}
static struct i2c_driver mcp7940_driver =
{
.driver =
{
.name = "rtc-mcp7940",
.owner = THIS_MODULE,
},
.probe = mcp7940_probe,
.remove = __devexit_p(mcp7940_remove),
.id_table = mcp7940_id,
};
static void rtc_pin_mux_init(void)
{
u32 mode = 0;
mode = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));
mode &= ~(0x1 << 0); // I2C_GPIO_MODE Pin , Set to I2C Pattern , namely I2C_SD(GPIO#1)I2C_SCLK(GPIO#2) Set to I2C Pattern
*(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(mode);
}
static int __init mcp7940_init(void)
{
rtc_pin_mux_init();
return i2c_add_driver(&mcp7940_driver);
}
module_init(mcp7940_init);
static void __exit mcp7940_exit(void)
{
i2c_del_driver(&mcp7940_driver);
}
module_exit(mcp7940_exit);
MODULE_AUTHOR("sky.houfei");
MODULE_DESCRIPTION("RTC driver for MCP7940");
MODULE_LICENSE("GPL");
5.2 RTC Driven makefile
makefile The name is makefile
############################## mcp7940 rtc driver makefile #########################
obj-m = rtc_mcp7940.o
TARGET_NAME=rtc_mcp7940.ko
PWD=$(shell pwd)
KERNEL_DIR?=/home/sky/develop/openWrt/openwrt/build_dir/target-mipsel_24kec+dsp_glibc-2.21/linux-ramips_mt7620/linux-3.18.29/
TOOL_CAHIN="/home/sky/develop/openWrt/openwrt/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_glibc-2.21/bin/mipsel-openwrt-linux-gnu-"
OUTPUT_DIR=$(PWD)/../../build_openwrt/mnt/sau2ag1/
###############################################################################
all:
make -C $(KERNEL_DIR) \
ARCH=mips \
CROSS_COMPILE=$(TOOL_CAHIN) \
M=$(PWD) \
modules
clean:
rm -f $(obj-m)
rm -f *.mod.c
rm -f *.mod.o
rm -f *.order
rm -f *.sysvers
#make command:
#make
#make clean
5.3 RTC Applications
mcp7940 The application is rtc_app.c, Application , The storage time is UTC Format time .
about UTC Time ,year = year -1900, month = month -1, The application is as follows .
/*
* Real Time Clock Driver Test/Example Program
*
* Compile with:
* gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
*
* Copyright (C) 1996, Paul Gortmaker.
*
* Released under the GNU General Public License, version 2,
* included herein by reference.
*
*/
#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
/*
* This expects the new RTC class driver framework, working with
* clocks that will often not be clones of what the PC-AT had.
* Use the command line to specify another RTC if you need one.
*/
static const char default_rtc[] = "/dev/rtc0";
int main(int argc, char **argv)
{
int i, fd, retval, irqcount = 0;
unsigned int cmd = 0;
unsigned long tmp, data;
struct rtc_time rtc_tm;
const char *rtc = default_rtc;
fd = open(default_rtc, O_RDONLY);
if (fd == -1)
{
printf("Can not open %s, exit the app\n", default_rtc);
}
rtc_tm.tm_year = 2015 - 1900;
rtc_tm.tm_mon = 10;
rtc_tm.tm_mday = 28;
rtc_tm.tm_wday = 3;
rtc_tm.tm_hour = 15;
rtc_tm.tm_min = 22;
rtc_tm.tm_sec = 10;
i = atoi(argv[1]);
switch(i)
{
case 1:
cmd = RTC_RD_TIME;
break;
case 2:
cmd = RTC_SET_TIME;
printf( "app set time %d-%d-%d week%d, %02d:%02d:%02d.\n",
rtc_tm.tm_year + 1900, rtc_tm.tm_mon, rtc_tm.tm_mday, rtc_tm.tm_wday,
rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
break;
default:
cmd = RTC_RD_TIME;
break;
}
retval = ioctl(fd, cmd, &rtc_tm);
if (retval == -1)
{
printf("ioctl cmd = %d, error, exit the rtc app\n");
exit(errno);
}
printf( "rtc app date/time is %d-%d-%d week%d, %02d:%02d:%02d.\n",
rtc_tm.tm_year + 1900, rtc_tm.tm_mon, rtc_tm.tm_mday, rtc_tm.tm_wday,
rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
close(fd);
printf("rtc test end\n");
return 0;
}
6、 ... and 、RTC FAQ analysis
6.1 View yes i2c Whether the bus is on
stay MT7620 Development board , Enter the command "ls /dev/i2c*", Pictured 6-1 Shown . You can see that in the diagram i2c-0, explain I2C The bus has been turned on .

6.2 see I2C Bus supported slaves device
stay MT7620 Development board , Enter the command “ls /sys/bus/i2c/devices/”, Pictured 6-2 Shown .
In the figure 6-2 in , You can see the support 0x006f The slave device (mcp7940 The address of the chip is just 0x6f).

chart 6-2 see I2C Bus supported slaves device
explain : If you don't see d0x006f Or other than i2c-0 Other equipment , shows i2c Bus does not support device Slave , At this point any i2c chip ( Slave device) Mount to MT7620 On , It is impossible to communicate , Because the mainframe (MT620 chip ) The address of the slave is not supported . You need to check 4.1.3 chapter ,dts Whether the document is modified correctly .
6.3 see i2c Bus mounted driver
stay MT7620 Development board , Enter the command “ls /sys/bus/i2c/drivers/”, Pictured 6-3 Shown . It can be seen from the picture that , The device has successfully rtc-mcp7940 The driver is mounted to i2c Bus .

chart 6-3 see i2c Bus mounted driver
explain : If you don't see rtc-mcp7940, shows rtc There is a problem with the driver of , Need to check 5.1 Chapter driver .
6.4 see rtc equipment
stay MT7620 Development board , Enter the command “ls /dev/rtc*”, Pictured 6-4 Shown . It can be seen from the picture that ,rtc The drive has been successful , You can see rtc equipment .

chart 6-4 see rtc equipment
explain : If you don't see rtc0 Or something rtc equipment , shows rtc There is a problem with the configuration of , The system does not support rtc, Need to check 4.2 Chapter rtc To configure .
7、 test
1、 mount rtc drive
rtc The compiled driver name is rtc_mcp7940, Execution mount , The message is as follows , explain rtc Successfully mounted in 0-006f Under the node , And registered as /dev/rtc0:
[email protected]:/tmp# insmod ./rtc_mcp7940.ko
[ 203.740000] rtc-mcp7940 0-006f: rtc core: registered mcp7940 as rtc0
[email protected]:/tmp# 2、 function rtc The test program
Set the time first , After setting up , Read again rtc Time , It is found that the normal reading and writing time , And right . And restart the device , After reboot ,rtc The time is also timed normally , During restart , Time is not lost or stopped .
[email protected]:/tmp# ./rtc_app_openwrt 2
app set time 2015-10-28 week3, 15:22:10.
rtc app date/time is 2015-10-28 week3, 15:22:10.
rtc test end
[email protected]:/tmp# ./rtc_app_openwrt 1
rtc app date/time is 2015-10-28 week3, 15:22:26.
rtc test end边栏推荐
- Openwrt 新增平台编译
- UDP 的报文结构和注意事项
- busybox login: can't execute '/bin/bash': No such file or directory 解决方法
- 台积电6纳米制程将于明年一季度进入试产
- 【云享读书会第13期】视频文件的编码格式
- Hj8 consolidated statement record
- First acquaintance with MySQL database
- [sword finger offer] interview question 52: the first common node of two linked lists - stack, hash table, double pointer
- C language: Sanzi game
- Push down of spark filter operator on parquet file
猜你喜欢

: 0xC0000005: 写入位置 0x01458000 时发生访问冲突----待解

DRF学习笔记(四):DRF视图

数据表的约束以及设计、联合查询——8千字攻略+题目练习解答

Binary Insertion Sort

CAS compares the knowledge exchanged, ABA problems, and the process of lock upgrading

/Dev/loop1 takes up 100% of the problem

Learn parquet file format

C语言:扫雷小游戏

SQL multi table query

Six capabilities of test and development
随机推荐
Voice live broadcast system -- a necessary means to improve the security of cloud storage
The method of exchanging two numbers in C language
Mlx90640 infrared thermal imager temperature sensor module development notes (VII)
低代码是开发的未来吗?浅谈低代码平台
To meet risc-v challenges? ARM CPU introduces custom instruction function!
网络原理(2)——网络开发
__typeof和typeof的差异
[tensorboard] oserror: [errno 22] invalid argument processing
Openwrt增加对 sd card 支持
First acquaintance with MySQL database
[sword finger offer] interview question 51: reverse pairs in the array - merge sort
[sword finger offer] interview question 55 - Ⅰ / Ⅱ: depth of binary tree / balanced binary tree
synchronized和ReentrantLock的区别
Extended log4j supports the automatic deletion of log files according to time division and expired files
Short video mall system, system prompt box, confirmation box, click blank to close the pop-up box
[sword finger offer] interview question 54: the k-largest node of the binary search tree
网络设备硬核技术内幕 路由器篇 22
Go language slow start - Basic built-in types
Addition, deletion, query and modification of MySQL table data
[regular expression] single character matching