Uboot does not normally require RTC to be turned on, but it still supports RTC for special needs. The first two articles of the underlying driver migration are described, and the top-level invocation process is described here. Top floor in uboot/common/cmd_date.c
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX software Engineering, [email protected]
*
* see File CREDITS for List of people-contributed to this
* project.
*
* This program was free software, you can redistribute it and/or
* modify it under the terms of the GNU Ge Neral public License as
* Published by the free software Foundation; either version 2 of
* The License, or (at Y Our option) any later version.
*
* This program was distributed in the hope that it'll be useful,
* but without any WARRANTY; without Eve n the implied warranty of
* merchantability or FITNESS for A particular PURPOSE. See the
* GNU general public License for more details.
*
* You should has received a copy of the GNU general public License
* along with this program; Ite to the Free software
* Foundation, Inc., Temple Place, Suite, Boston,
* MA 02111-1307 USA
*/
/*
* RTC, Date & Time Support:get and set Date & Time
*/
Include include include include Ifdef Config_reloc_fixup_worksdefine RELOC (a) Aelsedefine 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 i²c 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 I²c 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 are done and this would 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++ = ' + '; 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 = =) {/* MMDDHHMMCCYY */int year, century; if (Cnvrt2 (datestr+ 8, ¢ury) | | Cnvrt2 (datestr+10, &year)) {return (-1); } tmp->tm_year = century + year;} else if (len = =) {/* MMDDHHMMYY */int year, century; Century = tmp->tm_year/100; if (Cnvrt2 (datestr+ 8, &year)) return (-1); Tmp->tm_year = century + year;} Switch (len) {case 8:/* MMDDHHMM */* Fall thru */case:/* mmddhhmmyy */* Fall thru */case 1 2:/* MMDDHHMMCCYY */if (Cnvrt2 (datestr+0, &val) | | Val >) {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 >) {break; } tmp->tm_hour = val; if (Cnvrt2 (datestr+6, &val) | | Val > i) {break; } tmp->tm_min = val; /* Calculate Day of Week */Gregorianday (TMP); Return (0);d Efault: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"
);
Here the reverse analysis:
The first step is to register the date command
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"
);
This command is the RTC Control command. The function called is Do_date
int Do_date (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
You can see that this command calls the RTC registered Rtc_reset, Rtc_get, Rtc_set
Divided into case1: Get the time of the year
Case2 set time;
The time conversion function Mk_date can convert the string we entered into the date of the year for the Rtc_set configuration to go down
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
RTC Top-level analysis in Uboot