NUC970系列CPU和STM32一样自带RTC备份寄存器,供掉电前保存重要数据使用,容量是16x32bit=64byte
修改rtc驱动,增加nuc970_rtc_ioctl函数
struct nuc970_rtc_spr { unsigned int num; unsigned int value; }; #define RTC_SPR_SET_DATA 0x0801 #define RTC_SPR_GET_DATA 0x0802 #define REG_RTC_SPR0 0x40 //RTC备份寄存器地址 static int nuc970_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct nuc970_rtc *rtc = dev_get_drvdata(dev); struct nuc970_rtc_spr rtc_sprs; void __user *uarg = (void __user *) arg; int *err; unsigned char nums; err = check_rtc_spr_access_enable(rtc); if (IS_ERR(err)) { return PTR_ERR(err); } if (copy_from_user(&rtc_sprs, uarg, sizeof(rtc_sprs))) { return -EFAULT; } nums = rtc_sprs.num; switch (cmd) { case RTC_SPR_SET_DATA: //printk("K: set rtc spr%d, value:%x\n", nums, rtc_sprs.value); rtc_reg_write(rtc, REG_RTC_SPR0+nums*4, rtc_sprs.value); break; case RTC_SPR_GET_DATA: rtc_sprs.value = rtc_reg_read(rtc, REG_RTC_SPR0+nums*4); //printk("K: get rtc spr%d, value:%x\n", nums, rtc_sprs.value); rtc_sprs.num = nums; if (copy_to_user(uarg, &rtc_sprs, sizeof(rtc_sprs))) { return -EFAULT; } break; } return 0; } static struct rtc_class_ops nuc970_rtc_ops = { .ioctl = nuc970_rtc_ioctl, .read_time = nuc970_rtc_read_time, .set_time = nuc970_rtc_set_time, .read_alarm = nuc970_rtc_read_alarm, .set_alarm = nuc970_rtc_set_alarm, .alarm_irq_enable = nuc970_alarm_irq_enable, };测试demo
#include <stdio.h> #include <string.h> #include <linux/rtc.h> #include <sys/ioctl.h> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <math.h> #include <signal.h> struct nuc970_rtc_spr { unsigned int num; unsigned int value; }; #define RTC_SPR_SET_DATA 0x0801 #define RTC_SPR_GET_DATA 0x0802 #define FILE_DEV "/dev/rtc0" int main (int argc, char* argv[]) { int i=0; int fd = -1; int ret = -1; struct nuc970_rtc_spr rtc_spr; memset(&rtc_spr, 0x00, sizeof(rtc_spr)); printf("---------------------\n"); fd = open (FILE_DEV, O_RDWR); if (fd < 0) { printf("### open "FILE_DEV" fail!\n"); return -1; } //测试读RTC SPR0寄存器的值 rtc_spr.num = 0; if ((ret = ioctl(fd, RTC_SPR_GET_DATA, &rtc_spr)) < 0) { printf("### ioctl "FILE_DEV" get rtc spr%d data faile %d\n", rtc_spr.num, ret); return ret; } printf("### read rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value); //测试写数据到RTC SPR0寄存器 rtc_spr.num = 0; rtc_spr.value += 0xA5; printf("### write rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value); if ((ret = ioctl(fd, RTC_SPR_SET_DATA, &rtc_spr)) < 0) { printf("### ioctl "FILE_DEV" set rtc spr%d data faile %d\n",rtc_spr.num, ret); return ret; } //测试读RTC SPR1寄存器的值 rtc_spr.num = 1; if ((ret = ioctl(fd, RTC_SPR_GET_DATA, &rtc_spr)) < 0) { printf("### ioctl "FILE_DEV" get rtc spr%d data faile %d\n", rtc_spr.num, ret); return ret; } printf("### read rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value); //测试写数据到RTC SPR1寄存器 rtc_spr.num = 1; rtc_spr.value += 0xA6; printf("### write rtc spr%d data=0x%lx\n\n", rtc_spr.num, rtc_spr.value); if ((ret = ioctl(fd, RTC_SPR_SET_DATA, &rtc_spr)) < 0) { printf("### ioctl "FILE_DEV" set rtc spr%d data faile %d\n",rtc_spr.num, ret); return ret; } return 0; }