uboot中rtc顶层分析
uboot一般不会要求开启rtc,只是还是支持rtc以备特殊需求的。
底层驱动移植前面两篇已经介绍。这里介绍顶层的调用过程。顶层在uboot/common/cmd_date.c
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* RTC, Date & Time support: get and set date & time
*/
include
include
include
include
ifdef CONFIG_RELOC_FIXUP_WORKS
define RELOC(a) a
else
define RELOC(a) ((typeof(a))((unsigned long)(a) + gd->reloc_off))
endif
int mk_date (char , struct rtc_time );
int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
struct rtc_time tm;
int rcode = 0;
int old_bus;
/* switch to correct I2C bus */
old_bus = I2C_GET_BUS();
I2C_SET_BUS(CONFIG_SYS_RTC_BUS_NUM);
switch (argc) {
case 2: /* set date & time */
if (strcmp(argv[1],"reset") == 0) {
puts ("Reset RTC...\n");
rtc_reset ();
} else {
/* initialize tm with current time */
rcode = rtc_get (&tm);
if(!rcode) {
/* insert new date & time */
if (mk_date (argv[1], &tm) != 0) {
puts ("## Bad date format\n");
break;
}
/* and write to RTC */
rcode = rtc_set (&tm);
if(rcode)
puts("## Set date failed\n");
} else {
puts("## Get date failed\n");
}
}
/* FALL TROUGH */
case 1: /* get date & time */
rcode = rtc_get (&tm);
if (rcode) {
puts("## Get date failed\n");
break;
}
printf ("Date: %4d-%02d-%02d (%sday) Time: %2d:%02d:%02d\n",
tm.tm_year, tm.tm_mon, tm.tm_mday,
(tm.tm_wday<0 || tm.tm_wday>6) ?
"unknown " : RELOC(weekdays[tm.tm_wday]),
tm.tm_hour, tm.tm_min, tm.tm_sec);
break;
default:
cmd_usage(cmdtp);
rcode = 1;
}
/* switch back to original I2C bus */
I2C_SET_BUS(old_bus);
return rcode;
}
/*
* simple conversion of two-digit string with error checking
*/
static int cnvrt2 (char *str, int *valp)
{
int val;
if ((*str < '0') || (*str > '9'))
return (-1);
val = *str - '0';
++str;
if ((*str < '0') || (*str > '9'))
return (-1);
*valp = 10 * val + (*str - '0');
return (0);
}
/*
* Convert date string: MMDDhhmm[[CC]YY][.ss]
*
* Some basic checking for valid values is done, but this will not catch
* all possible error conditions.
*/
int mk_date (char *datestr, struct rtc_time *tmp)
{
int len, val;
char *ptr;
ptr = strchr (datestr,'.');
len = strlen (datestr);
/* Set seconds */
if (ptr) {
int sec;
*ptr++ = '\0';
if ((len - (ptr - datestr)) != 2)
return (-1);
len = strlen (datestr);
if (cnvrt2 (ptr, &sec))
return (-1);
tmp->tm_sec = sec;
} else {
tmp->tm_sec = 0;
}
if (len == 12) { /* MMDDhhmmCCYY */
int year, century;
if (cnvrt2 (datestr+ 8, ¢ury) ||
cnvrt2 (datestr+10, &year) ) {
return (-1);
}
tmp->tm_year = 100 * century + year;
} else if (len == 10) { /* MMDDhhmmYY */
int year, century;
century = tmp->tm_year / 100;
if (cnvrt2 (datestr+ 8, &year))
return (-1);
tmp->tm_year = 100 * century + year;
}
switch (len) {
case 8: /* MMDDhhmm */
/* fall thru */
case 10: /* MMDDhhmmYY */
/* fall thru */
case 12: /* MMDDhhmmCCYY */
if (cnvrt2 (datestr+0, &val) ||
val > 12) {
break;
}
tmp->tm_mon = val;
if (cnvrt2 (datestr+2, &val) ||
val > ((tmp->tm_mon==2) ? 29 : 31)) {
break;
}
tmp->tm_mday = val;
if (cnvrt2 (datestr+4, &val) ||
val > 23) {
break;
}
tmp->tm_hour = val;
if (cnvrt2 (datestr+6, &val) ||
val > 59) {
break;
}
tmp->tm_min = val;
/* calculate day of week */
GregorianDay (tmp);
return (0);
default:
break;
}
return (-1);
}
/*****************************************/
U_BOOT_CMD(
date, 2, 1, do_date,
“get/set/reset date & time”,
“[MMDDhhmm[[CC]YY][.ss]]\ndate reset\n”
” - without arguments: print date & time\n”
” - with numeric argument: set the system date & time\n”
” - with ‘reset’ argument: reset the RTC”
);
这里反向分析:
第一步是注冊 date命令
U_BOOT_CMD(
date, 2, 1, do_date,
“get/set/reset date & time”,
“[MMDDhhmm[[CC]YY][.ss]]\ndate reset\n”
” - without arguments: print date & time\n”
” - with numeric argument: set the system date & time\n”
” - with ‘reset’ argument: reset the RTC”
);
这个命令就是rtc的控制命令了 调用的函数是 do_date
int do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
能够看到这命令是调用了rtc里面注冊的rtc_reset、rtc_get、rtc_set
分为case1 :获取当年的时间
case2 设置时间;
时间转换函数mk_date 能够将我们输入的字符串转化成为时间的年月日 供rtc_set 配置下去去
uboot中rtc顶层分析的更多相关文章
- u-boot中网口处理--软件部分
u-boot中DM9000驱动分析 1. CSRs和PHY reg读写. static u16 phy_read(int reg) { u16 val; /* Fill the phyxcer reg ...
- u-boot中nandflash初始化流程分析(转)
u-boot中nandflash初始化流程分析(转) 原文地址http://zhuairlunjj.blog.163.com/blog/static/80050945201092011249136/ ...
- U-boot中SPL功能和源码流程分析
在U-boot目录下,有个比较重要的目录就是SPL的,SPL到底是什么呢?为什么要用它呢? SPL(Secondary programloader)是uboot第一阶段执行的代码.主要负责搬移uboo ...
- tiny4412 串口驱动分析一 --- u-boot中的串口驱动
作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...
- 为什么要有uboot?带你全面分析嵌入式linux系统启动过程中uboot的作用
1.为什么要有uboot 1.1.计算机系统的主要部件 (1)计算机系统就是以CPU为核心来运行的系统.典型的计算机系统有:PC机(台式机+笔记本).嵌入式设备(手机.平板电脑.游戏机).单片机(家用 ...
- 分析uboot中 make xxx_config过程
make xxx_config实质上就是调用了 首先看MKCONFIG: [注意]SRCTREE=源文件下的目录 之后的语句: @$(MKCONFIG) $(@:_config=) arm arm92 ...
- uboot中setenv和saveenv分析
转:https://blog.csdn.net/weixin_34355715/article/details/85751477 Env在u-boot中通常有两种存在方式,在永久性存储介质中(flas ...
- uboot的配置流程分析
简单介绍一下uboot的基本配置流程.和绝大多数源码编译安装一样,uboot在执行make之前需要执行make XXXconfig来配置相关信息,而且uboot本身是针对多种平台的bootloader ...
- 从0移植uboot (一) _配置分析
来源:Linux社区 作者:xiaojiang1025 :http://www.linuxidc.com/Linux/2017-02/141018.htm 和绝大多数源码编译安装一样,uboot的 ...
随机推荐
- 【2017"百度之星"程序设计大赛 - 复赛】Arithmetic of Bomb
[链接]http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=777&pid=1001 [题意] 在这里写 [题解] ...
- 洛谷——U10783 名字被和谐了
https://www.luogu.org/problem/show?pid=U10783 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约 ...
- 洛谷 P1689 方程求解
P1689 方程求解 题目描述 给一个方程,形如X+Y=Z或X-Y=Z.给出了其中两个未知数,请求出第三个数.未知数用‘?’表示,等式中也许会出现一些多余的空格. 输入输出格式 输入格式: 一行,方程 ...
- 王小川分享AI
王小川的分享:Link
- 2.1 使用eclipse4.4 搭建 maven简单结构项目。
1.前言 1.本博客面向0基础开发人员. 2.本博客为系列博客.<1.X>系列为服务器数据库相关技术,前几章为简单搭建linux+tomcat+mysql+nginx+redis.< ...
- 洛谷 P1097 统计数字
P1097 统计数字 题目描述 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自 ...
- 2017.1-TOP5 Android开源库
Colorful (Github) Colorful简单实用,通过这个开源库可以通过编码的方式来改变应用的主题,不再需要定义不同的style dependencies { compile 'com.g ...
- ajax+客户端与服务器端的交互
一. AJAX 原生JS var xhr=new XMLHttpRequest(); xhr.open("GET","[请求地址]",false); xhr.o ...
- C# 泛型特化
C# 泛型不是 C++ 的模板类,并不支持特化和偏特化,但是使用一些技巧可以在一定程度上达到相同的目的. 原文是 po 在 stackoverflow 上的一个回答:A: Generic indexe ...
- POJ 1201 Intervals || POJ 1716 Integer Intervals 差分约束
POJ 1201 http://poj.org/problem?id=1201 题目大意: 有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该序列中处于[ai, ...