Help with time driver
Help with time driver
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
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
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: Help with time driver
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
Thanks for your reaction!
But, i know the CMOS RTC but the interrupts for reading it doesn't work for me (INT 1Ah).
But, i know the CMOS RTC but the interrupts for reading it doesn't work for me (INT 1Ah).
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: Help with time driver
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
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
Hi,
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
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.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.
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.
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: Help with time driver
Whoops - didn't realize you were in real mode - disregard my suggestions.
Re: Help with time driver
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
PS: I'm dutch so my english is not well
Re: Help with time driver
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?!bergen111 wrote:PS: I'm dutch so my english is not well
JAL
- Combuster
- 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
For the non-dutch a translation: If you are Dutch and your English is bad, you must be fake.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?!
Re: Help with time driver
Read second counter. Read all the other counters. Read second counter again. If different, retry.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).
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
Hi,
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
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)...Candy wrote:Read second counter. Read all the other counters. Read second counter again. If different, retry.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).
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.