Cron job / calendar function in MCU? - Page 1
Forum section: electronics / general

author: Araho
author_rank: Regular Contributor
timestamp: November 01, 2014, 02:03:45 am
content: Hi!I'm working on the pre-project specification of my Bachelors Thesis in EE at the moment, and have gotten a really cool project from a company in my hometown. As part of that project I need to send data periodically from my MCU-based unit in the field to a webserver, and in the specification email they talk about a cron job-functionality as per the protocol. Since this protocol is also used for sending data via satellite etc, transfers aren't done very often, and I guess that's why they say cron job; The need to set specific (large) timeframes between initiating transfers. I'm guessing the typical timeframe here is far larger than what is reasonable to achieve with the typical timers of a SAM4L MCU. So I would like to know if there is a standard way of doing this on the ARM platform.My plan for now is comparing the GPS time on wakeup from sleep (because the board has a GPS unit as well) with checkpoints for sending in data, set after the last attempted transfer. I haven't given it an enormous amount of thought yet, just thought I'd throw this out here if anyone had any great ideas or experience on the subject.

author: ivaylo
author_rank: Frequent Contributor
timestamp: November 01, 2014, 06:25:12 am
content: Aren't you running some sort of OS on that ARM? Put any Linux you manage and you get cron and everything...

author: adam1213
author_rank: Regular Contributor
timestamp: November 01, 2014, 06:50:51 am
content: What is your experience with Linux?Are you planning on having the processor in sleep mode most of the time for power management reasons?

author: Bored@Work
author_rank: Super Contributor
timestamp: November 01, 2014, 07:11:36 am
content: The SAM4L has an RTC, read about it in the datasheet. If you want to use the GPS time and date, you probably have to synchronize the RTC to the GPS time and date. But if you need to do that occasionally, regularly, or maybe not at all, depends on the required accuracy and precision of the times of transfers. As always, run the numbers before you commit to an architecture and implementation.

author: andersm
author_rank: Super Contributor
timestamp: November 01, 2014, 08:45:01 am
content: Quote from: ivaylo on November 01, 2014, 06:25:12 amThe SAM4L is a Cortex-M4 microcontroller, so no Linux.

author: bingo600
author_rank: Super Contributor
timestamp: November 01, 2014, 12:05:33 pm
content: Cron is scheduling "per minute" matches.Use the RTC , and on every minute tick , scan the "jobtable" to see if anything have to be "run"/Bingo

author: Araho
author_rank: Regular Contributor
timestamp: November 01, 2014, 01:58:44 pm
content: Quote from: ivaylo on November 01, 2014, 06:25:12 amQuote from: adam1213 on November 01, 2014, 06:50:51 amAtmel SAM4L is, as mentioned by someone else, a Cortex M4 cpu, so I don't think it has the power to properly run Linux. Yes, I need to be very power-aware during this design. The goal is to draw less than 500uW, if I remember correctly.Quote from: Bored@Work on November 01, 2014, 07:11:36 amHmm, I guess I missed this! Back to reading the datasheet more closely. What I'll use in the end probably depends on the power consumption of the RTC. Thanks for tipping me off on this!

author: SeanB
author_rank: Super Contributor
timestamp: November 01, 2014, 05:31:29 pm
content: Most RTC units draw so little current in operation that they are part of the deep sleep power use. You configure it to generate an interrupt every minute ( or whatever it supports) to wake the processor out of deep sleep, then run your list of jobs then put it back to sleep.Just be careful in that a lot of the deep sleep modes stop the main oscillator, and when it powers back on it takes a while to start running, giving a latency on your wake up that may be variable. If you absolutely need it to be the same you need to stop in a sleep mode that keeps it running, which uses more power but which has lower latency.

author: nctnico
author_rank: Super Contributor
timestamp: November 01, 2014, 09:43:47 pm
content: I use a timer interrupt which increments a seconds counter in an unsigned int (32 bit) in my microcontroller projects. For Posix compatibility I have a time() function which tells me the number of seconds since power on. If I have a clock then I could preset the seconds counter with the current UTC time. If an event needs to happen at a certain time you can calculate the number of seconds that event is in the future and test if the time has passed.Say an event needs to happen 5 days from now:event_time=time(NULL) + 5*24*60*60 ;Somewhere in the main loop:if (time(NULL)>=event_time){event_time=time(NULL) + 5*24*60*60 ;//do the event}Note the >=. If the UTC time gets adjusted it may skip a second.edit: see my next post for the correct code.

author: dannyf
author_rank: Super Contributor
timestamp: November 01, 2014, 10:29:40 pm
content: QuotePosix or not, that piece of code qualifies as a prime example of how not to write code for entry-level programmers: think about timing errors and roll-over.Anyone who produced that in a gainful employment should be fired on the spot.

author: nctnico
author_rank: Super Contributor
timestamp: November 01, 2014, 10:45:48 pm
content: Roll over is not an issue. A 32 bit second counter will overflow in 136 years. And even then a roll over causes no problems due to the integer being unsigned. This particular piece of code has been tested and reviewed many times to make sure it works (and it does).

author: miguelvp
author_rank: Super Contributor
timestamp: November 01, 2014, 10:48:31 pm
content: But time_t is signed2038 will be the next Y2KEdit: it will roll over so you can assume greater than, you have to subtract and get the deltaEdit again: even if unsigned, say it's within the last 432000 seconds from max unit32: 4294967295, your next event will be between 0-431999every tick until it rolls over it will generate an event until the roll-over.And by every tick I mean the CPU speed not every second for the last 5 days, but that times the speed of your processor.Edit to recant: not every tick, only just every cycle your program hits that so not as bad as the speed processor but still bad.

author: dannyf
author_rank: Super Contributor
timestamp: November 01, 2014, 10:59:58 pm
content: QuoteIt shows how bad the reviews / reviewers are, not how good that piece of code is.

author: nctnico
author_rank: Super Contributor
timestamp: November 02, 2014, 01:04:14 am
content: Quote from: miguelvp on November 01, 2014, 10:48:31 pmOfcourse you use an unsigned type for this purpose since we are making our own uint32_t time() function here. However there is an error in my code indeed (too sleepy)The code should read:uint32_t event_interval=5*24*60*60 ; //5 daysuint32_t event_timer=time(NULL);Somewhere in the main loop:if ((time(NULL)-event_timer) >=event_interval){event_timer=time(NULL); //reset timer//do the event}

author: miguelvp
author_rank: Super Contributor
timestamp: November 02, 2014, 01:28:09 am
content: much better,BTW you can still use the POSIX code even with the signed int32 it will work the same as if unsigned.Otherwise you can't tell time before 1970, which to me is important since I was born before thatThat said, it's about time (no pun intended) to deprecate the use of POSIX time and time_t even if some systems now use 64 signed integers is a waste to store it in seconds since some epoch64 bits signed integers in microseconds since Jan 1 2000 will do nicely for the next 292263 years and also for the past 292291 years. (removed the commas so it won't get confuse with decimal point)

author: Marco
author_rank: Super Contributor
timestamp: November 02, 2014, 01:32:04 am
content: Go big or go home.128 bits, big bang to heat death.

author: miguelvp
author_rank: Super Contributor
timestamp: November 02, 2014, 01:40:01 am
content: Quote from: Marco on November 02, 2014, 01:32:04 am128 bits we could do femtosecond (10^-15) increments and have plenty to spare5 391 566 852 722 571 years from now and before now.

author: nctnico
author_rank: Super Contributor
timestamp: November 02, 2014, 01:58:01 am
content: True but on an 32 bit ARM controller a 32 bit type is atomic by itself. If you use a larger type you'll need semaphores to get the timer from the interrupt domain into the main loop domain.

author: westfw
author_rank: Super Contributor
timestamp: November 02, 2014, 07:59:01 am
content: First of all "cron" is part of the usual Unix system infrastructure used to run commands at pre-configured times.Log into a unix/linux system and do "man 5 crontab" for the most useful information (format of the file used to specify times and commands.) ("cron" itself is the system program that reads all of the individual user crontab files and actually executes the commands.) Cron is generally time-of-day based, with a granularity of 1 minute.Second, "RTC" is one of those terms that has at least two meanings:If a microcontroller says that it includes an RTC, that usually means that it has a second crystal oscillator optimized to run a 32768Hz clock crystal even when the rest of the CPU is turned-off power-saving modes, with some sort of ability wake/interrupt/reset the CPU at periodic but "large" intervals (one second, for example.) AVR and STM32f1xx microcontrollers are like this (as are most that I've looked at.)If an external peripheral chip claims to be an RTC, that usually means it has a similar 32768Hz oscillator, but there is ALSO usually clock/calendar logic to keep track of seconds/minutes/hours/day-of-week/month/year. And an "alarm clock" capability that will assert some external pin at some specific time (useful for waking up a separate cpu.) Note that a typical RTC chip does all this calendar functionality while using (usually) less power than the RTC in a microcontroller would use with the rest of the CPU asleep.In order to get cron-like functionality out of a microcontroller-style RTC, you would have to write software to convert periodic interrupts form the RTC into clock/calendar data (just like the separate RTC chip already does FOR you.) IMO, an external RTC chip is a much better match to providing such functions.

author: mikerj
author_rank: Super Contributor
timestamp: November 02, 2014, 02:15:35 pm
content: Quote from: nctnico on November 02, 2014, 01:58:01 amYou certainly don't need semaphores to enable atomic access to a data object, especially one as fast to access as a 64 bit integer. This is where critical sections are used.Quote from: nctnico on November 01, 2014, 09:43:47 pmSome noob made this exact mistake in some embedded code at work. It was a millisecond counter and it all worked nicely for 50 days...