Help with time driver

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
bergen111
Posts: 3
Joined: Wed Sep 08, 2010 12:03 pm

Help with time driver

Post by bergen111 »

Hi,

I need to write a (interrupt) time driver. i cant find a interrupt (that works) that read the system time for me.
Can anyone help me?

PS: my programming language is Assembly
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Help with time driver

Post by NickJohnson »

Well, regardless of whether you want an interrupt at a certain time or the current system time, you probably are looking for the CMOS RTC.
bergen111
Posts: 3
Joined: Wed Sep 08, 2010 12:03 pm

Re: Help with time driver

Post by bergen111 »

Thanks for your reaction!

But, i know the CMOS RTC but the interrupts for reading it doesn't work for me (INT 1Ah).
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Help with time driver

Post by NickJohnson »

To which interrupts do you have the PIC set up to send IRQs? Do you have both IRQ8 _and_ IRQ2 enabled? Are you sure your interrupt system doesn't have any other problems?
skyking
Member
Member
Posts: 174
Joined: Sun Jan 06, 2008 8:41 am

Re: Help with time driver

Post by skyking »

Please do read the question before answering! Do you really want to do it this way? Using BIOS services for handling time means that you need to use vm86 (or real) mode, if you're aiming for using PM it would probably be a better idea to use the RTC and PIC directly.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help with time driver

Post by Brendan »

Hi,
skyking wrote:Using BIOS services for handling time means that you need to use vm86 (or real) mode, if you're aiming for using PM it would probably be a better idea to use the RTC and PIC directly.
You could get the time and date using the BIOS during boot (while you're in real mode anyway) and convert that into "ticks since the epoch" format, and then use the PIT or something after boot to update the "ticks since the epoch" counter.

There are a few other problems with using on the BIOS functions though. The first problem is that you need to rely on the BIOS functions - if the BIOS is buggy your OS gets messed up.

The second problem is that you can't get the time and date at the same time. This means you have to get them separately, and if it's near midnight you have to make sure you don't get yesterday's time then today's date (or yesterday's date then today's time), which can cause you to be wrong by about 24 hours. To avoid that you'd probably want to get the date, then get the time. If the time is "just past midnight" you'd get the date again and use the time with the second date. Otherwise you'd use the first date with the time. Of course before reading the RTC the BIOS should wait until after it does an update (e.g. wait for the "update in progress" flag to go from set to clear), and the update happens once per second, so this will take a minimum of 1 second (e.g. 2 reads starting immediately before an update) and could take up to 3 seconds (e.g. 3 reads starting immediately after an update). This is insanely slow. If you could get the time and date at the same time, then you wouldn't need to worry about "near midnight rollover", and you'd only need to wait for the update once (which should take between 0 seconds and 1 second).

An even better way might be to use RTC's update IRQ. For example, setup the "update IRQ" early during boot, then do other stuff (e.g. start device drivers, etc) while you're waiting for the update. When the update/IRQ occurs you'd read the full time and date, set a "ticks since the RTC was read" counter to zero and disable the "update IRQ" (and use some other timer like the PIT or RTC "periodic IRQ" to update the "ticks since I read the RTC" counter). When you're finished the other stuff, if the update hasn't occurred you'd wait for it; and then you'd combine the RTC time/date and "ticks since I read the RTC" into a single "ticks since the epoch" counter. That way, if it takes you 1 second or more to do other stuff (initialise drivers, etc) then getting the time and date from the RTC costs you almost no time at all.

Don't forget that the RTC could be set to UTC or "local time", and if it is set to "local time" you may need to refer to a timezone database to figure out what the (UTC) time actually is (which can mean mounting file system/s as "read only" to access the timezone database - you can't allow files to be modified unless you can create valid timestamps). Also, if you support NTP then you'd need to wait until after device drivers, etc are started to figure out what the time is. In both cases you can't know the time until after devices drivers, etc are ready.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Help with time driver

Post by NickJohnson »

Whoops - didn't realize you were in real mode - disregard my suggestions.
bergen111
Posts: 3
Joined: Wed Sep 08, 2010 12:03 pm

Re: Help with time driver

Post by bergen111 »

I'll do it in real mode because i want to learn how a computer works in his first stage, after learning everything inside out i go further to more complex things like switching to Pmode and memory managemant

PS: I'm dutch so my english is not well
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Help with time driver

Post by jal »

bergen111 wrote:PS: I'm dutch so my english is not well
Ehm... sinds wanneer kunnen Nederlanders geen Engels? Als je, pak 'm beet, een Pool, een Rus, een Chinees of een Japanner was (of, zeg, een Italiaan of Fransman), dan had je een excuus, maar als Nederlander?!


JAL
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Help with time driver

Post by Combuster »

jal wrote:Ehm... sinds wanneer kunnen Nederlanders geen Engels? Als je, pak 'm beet, een Pool, een Rus, een Chinees of een Japanner was (of, zeg, een Italiaan of Fransman), dan had je een excuus, maar als Nederlander?!
For the non-dutch a translation: If you are Dutch and your English is bad, you must be fake. :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Help with time driver

Post by Candy »

Brendan wrote:The second problem is that you can't get the time and date at the same time. This means you have to get them separately, and if it's near midnight you have to make sure you don't get yesterday's time then today's date (or yesterday's date then today's time), which can cause you to be wrong by about 24 hours. To avoid that you'd probably want to get the date, then get the time. If the time is "just past midnight" you'd get the date again and use the time with the second date. Otherwise you'd use the first date with the time. Of course before reading the RTC the BIOS should wait until after it does an update (e.g. wait for the "update in progress" flag to go from set to clear), and the update happens once per second, so this will take a minimum of 1 second (e.g. 2 reads starting immediately before an update) and could take up to 3 seconds (e.g. 3 reads starting immediately after an update). This is insanely slow. If you could get the time and date at the same time, then you wouldn't need to worry about "near midnight rollover", and you'd only need to wait for the update once (which should take between 0 seconds and 1 second).
Read second counter. Read all the other counters. Read second counter again. If different, retry.

Assuming your code isn't insanely slow this'll take at most two tries and be done in 14 cmos reads. That's very significantly less than the solution Brendan proposes.

It also breaks if your code is *so* slow that it takes a full minute to read the 14 registers. That shouldn't happen for obvious reasons :-)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Help with time driver

Post by Brendan »

Hi,
Candy wrote:
Brendan wrote:The second problem is that you can't get the time and date at the same time. This means you have to get them separately, and if it's near midnight you have to make sure you don't get yesterday's time then today's date (or yesterday's date then today's time), which can cause you to be wrong by about 24 hours. To avoid that you'd probably want to get the date, then get the time. If the time is "just past midnight" you'd get the date again and use the time with the second date. Otherwise you'd use the first date with the time. Of course before reading the RTC the BIOS should wait until after it does an update (e.g. wait for the "update in progress" flag to go from set to clear), and the update happens once per second, so this will take a minimum of 1 second (e.g. 2 reads starting immediately before an update) and could take up to 3 seconds (e.g. 3 reads starting immediately after an update). This is insanely slow. If you could get the time and date at the same time, then you wouldn't need to worry about "near midnight rollover", and you'd only need to wait for the update once (which should take between 0 seconds and 1 second).
Read second counter. Read all the other counters. Read second counter again. If different, retry.
I was talking about using the BIOS functions, where you can only "get time" or "get date", and can't read individual counters (unless you stop using the BIOS)...

If you're not using the BIOS, poll the "update in progress" flag, then (after the update has completed, and with interrupts disabled) read all of the counters once only. If you don't like wasting up to 1 second polling the "update in progress" flag, then use the "update IRQ" (and do other things while you're waiting)...

EDIT: Also note that reading the seconds, then reading the rest, then reading seconds again and retrying if it changed doesn't work. If you start in the middle of an update (e.g. after RTC has updated seconds but before RTC has finished updating the hour) you get dodgy results (e.g. maybe you read 1:59:00 instead of 2:00:00). If you make sure an update isn't currently in progress before you start, then an update could start before you read seconds (so you read "new seconds" and "old minutes" anyway).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply