Hi All,
I want to set the RTC time to the current time and date without hard-coding it.
I tried to use the function time() and ctime() defined in time.h, but I read that time() is a semihosted function (http://www.keil.com/support/man/docs/armlib/armlib_chr1359122861930.htm)
#include <time.h> time_t rawtime; char buffer[50] ={0}; time(&rawtime); sprintf (buffer, "%s", ctime(&rawtime) );
So if I include time(&rawtime), then the program stops with BKPT 0xAB (indicating semihosting) and if I don't include it then the buffer displays 00:00 1 Jan 1970.
So my question is, how do I write the retarget.c to use the time function? I read a lot of examples on retargeting printf, but can't find anything on time().
Or what is the normal way of setting the current date/time?
Thank you.
Why not just write your own set_RTC() and read_RTC() functions, and use them directly?
You're going to have to do that work anyhow to support time() ...
Note that time() doesn't set any time. It's just intended to retrieve time.
If you have an RTC that ticks a variable very second, and zero is the Unix epoch of 1970-01-01 00:00, then you can just write your own time:
time_t time(time_t* t) { time_t tmp = my_magical_rtc_tick_value; if (t) *t = tmp; return tmp; }
If the RTC maybe can generate an interrupt pulse every second and is interfaced using for example Maxim/Dallas one-wire protocol, then you need to write code that can write a clock value to the RTC, and that on program start can retrieve the current time. Then an interrupt handler that can increment a one-second tick variable.
If you have an internal RTC in the processor, then you might even read out the time from the RTC on every call to time() - but you may then have to use mktime() to convert from broken-down year, month, day, hour, min, sec into the epoch tick value that time() is expected to return.
Thanks for the reply, I think I'm not very clear on my question...
The my_magical_rtc_tick_value is exactly what I'm trying to get at.
So I will have to program multiple chips at different times with the same code, but I want their RTC value to reflect what the ACTUAL time is at the moment it is being programmed (according to the PC anyway).
I have the rtc_read function as follows
time_t rtc_read(void) { RTC_DateTypeDef dateStruct; RTC_TimeTypeDef timeStruct; struct tm timeinfo; hrtc.Instance = RTC; // Read actual date and time HAL_RTC_GetTime(&hrtc, &timeStruct, FORMAT_BIN); // Read time first! HAL_RTC_GetDate(&hrtc, &dateStruct, FORMAT_BIN); // Setup a tm structure based on the RTC timeinfo.tm_wday = dateStruct.WeekDay; timeinfo.tm_mon = dateStruct.Month - 1; timeinfo.tm_mday = dateStruct.Date; timeinfo.tm_year = dateStruct.Year + 100; timeinfo.tm_hour = timeStruct.Hours; timeinfo.tm_min = timeStruct.Minutes; timeinfo.tm_sec = timeStruct.Seconds; // Convert to timestamp time_t t = mktime(&timeinfo); return t; }
and in main I can read it and it gives me the hardcoded value that I put in.
rawtime = rtc_read(); sprintf (buffer, "%s", ctime(&rawtime) );
I saw SYS_TIME (0x11) and it seems to be what I need, but I can't find any example code and have no idea how to use it.
Any ideas?
www.keil.com/.../armcc_pge1358787060782.htm
So you're saying that the RTC hardware is not working?
Specifically, the RTC hardware is just "sticking" at the value you last set - it is not advancing as time moves on?
In that case, no amount of fiddling around with system functions is going to help - is it?
You need to find out why the RTC hardware is not working - and fix that!!
I think I'm not very clear on my question...
I think you don't actually realize what your question even is.
I want their RTC value to reflect what the ACTUAL time
And that's why your question should have been: "How do I transport the current wall clock time from outside the micro controller into it?"
There are three principal ways of doing that.
1) you change the file you program into the chip according to current time, for every device 2) you use in-circuit-testing techniques like JTAG/boundary scan to write the time directly in the RTC, while the device is being produced, or 3) you tell the microcontroller the current time by one of its communication lines to the outside world, using a "set time to" special command.
As this will almost certainly have to be done more than once in a device's lifetime, you really should pick 3).
The end user will not have access to any JTAG interface. And you'll have to be happy if your RTC drifts less than 30 seconds/year. Not to mention the outcome when a customer needs to replace the RTC battery - or in case you use a supercap what happens if the customer (or you) keep the device on a shelf until the supercap is emptied.
And you need to consider that this world has a significant number of time zones - so a customer may not be happy with a clock that runs in your time zone.
So your device will need some interface that will allow the clock to be set out in the field. If you don't have a display and some buttons, then it's time to consider a serial port - preferably something a standard PC has, like USB or Ethernet, since RS-232 are no longer fitted on modern computers and I2C, SPI etc are intended for internal use and would require very special adapters to interface with a PC.
Or, possibly, something wireless ...
Possibly connected to a serial port.
But while WiFi would manage time, it would either require the device to have a way to manually set IP and present IP - or that the OP writes some application to let the user find what IP the unit got from the router. And then there wouldn't have been any thread about how to set the time, since the addition of NTP or similar would have been a trivial exercise.
Bluetooth allows serial ports - but isn't easy to use for an end user, unless they get an Android/iPhone application.
Zigbee isn't something an end user is likely to have a gateway for. Same with an RFID-based solution.
GPS would work, if there is enough signal - and if there is no need to play around with time zones.
DCF77 would work for most parts of Europe, but requires a backup solution unless the equipment will not only be available for mainland Europe. The TDF transmitter in France would cover a larger range but still not world-wide.
Agreed - but it may still be an option in a particular application or use-case.
That's why I just said, "possibly".
And, yes - it's quite likely that the radio would connect to the main processor via a serial port of some sort.
Of course, we don't know what connectivity and/or management options may already be present in the project/product ...
Of course it is. That's why I posted the message.
Strange that you think you need to validate the statement.