Page 1 of 1
Help with time driver
Posted: Wed Sep 08, 2010 12:08 pm
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
Re: Help with time driver
Posted: Wed Sep 08, 2010 1:28 pm
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.
Re: Help with time driver
Posted: Thu Sep 09, 2010 12:07 pm
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).
Re: Help with time driver
Posted: Thu Sep 09, 2010 12:43 pm
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?
Re: Help with time driver
Posted: Thu Sep 09, 2010 1:37 pm
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.
Re: Help with time driver
Posted: Thu Sep 09, 2010 9:13 pm
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
Re: Help with time driver
Posted: Thu Sep 09, 2010 9:53 pm
by NickJohnson
Whoops - didn't realize you were in real mode - disregard my suggestions.
Re: Help with time driver
Posted: Fri Sep 10, 2010 8:37 am
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
Re: Help with time driver
Posted: Mon Sep 13, 2010 8:54 am
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
Re: Help with time driver
Posted: Mon Sep 13, 2010 9:57 am
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.

Re: Help with time driver
Posted: Tue Sep 14, 2010 2:19 am
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

Re: Help with time driver
Posted: Tue Sep 14, 2010 2:31 am
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