OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Apr 20, 2024 3:27 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: how to get time for text based os using RTC or else?
PostPosted: Tue Apr 24, 2018 10:44 pm 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
Hello guys I'm very new to osdev.org and os developing.I'm busy with building a small text based os and now I was stuck in showing time on my os's screen.I tried RTC interrupts but only I can get time and date without updating seconds in real time seconds.So please anybody help me to update my time in seconds when I showing time in my own os. [-o< [-o<

Code:
#define CURRENT_YEAR        2018                            // Change this each year!
int century_register = 0x00;
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char day;
unsigned char month;
unsigned int year;

enum {
      cmos_address = 0x70,
      cmos_data    = 0x71
};
int get_update_in_progress_flag() {
      outportb(cmos_address, 0x0A);
      return (inportb(cmos_data) & 0x80);
}

unsigned char get_RTC_register(int reg) {
      outportb(cmos_address, reg);
      return inportb(cmos_data);
}

void read_rtc() {

   
    unsigned char century;
    unsigned char last_second;
    unsigned char last_minute;
    unsigned char last_hour;
    unsigned char last_day;
    unsigned char last_month;
    unsigned char last_year;
    unsigned char last_century;
    unsigned char registerB;

      // Note: This uses the "read registers until you get the same values twice in a row" technique
      //       to avoid getting dodgy/inconsistent values due to RTC updates

      while (get_update_in_progress_flag());                // Make sure an update isn't in progress
      second = get_RTC_register(0x00);
      minute = get_RTC_register(0x02);
      hour = get_RTC_register(0x04);
      day = get_RTC_register(0x07);
      month = get_RTC_register(0x08);
      year = get_RTC_register(0x09);
      if(century_register != 0) {
            century = get_RTC_register(century_register);
      }

      do {
            last_second =second;
            last_minute = minute;
            last_hour =hour;
            last_day = day;
            last_month = month;
            last_year = year;
            last_century = century;

            while (get_update_in_progress_flag());           // Make sure an update isn't in progress
            second = get_RTC_register(0x00);
            minute = get_RTC_register(0x02);
            hour = get_RTC_register(0x04);
            day = get_RTC_register(0x07);
            month = get_RTC_register(0x08);
            year = get_RTC_register(0x09);
            if(century_register != 0) {
                  century = get_RTC_register(century_register);
            }
      } while( (last_second !=second) || (last_minute != minute) || (last_hour !=hour) ||
               (last_day != day) || (last_month != month) || (last_year != year) ||
               (last_century != century) );

      registerB = get_RTC_register(0x0B);

      // Convert BCD to binary values if necessary

      if (!(registerB & 0x04)) {
            second = (second & 0x0F) + ((second / 16) * 10);
            minute = (minute & 0x0F) + ((minute / 16) * 10);
            hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
            day = (day & 0x0F) + ((day / 16) * 10);
            month = (.month & 0x0F) + ((month / 16) * 10);
            year = (year & 0x0F) + ((year / 16) * 10);
            if(century_register != 0) {
                  century = (century & 0x0F) + ((century / 16) * 10);
            }
      }


      // Convert 12 hour clock to 24 hour clock if necessary

      if (!(registerB & 0x02) && (hour & 0x80)) {
            hour = ((hour & 0x7F) + 12) % 24;
      }

      // Calculate the full (4-digit) year

      if(century_register != 0) {
           year += century * 100;
      } else {
            year += (CURRENT_YEAR / 100) * 100;
            if(year < CURRENT_YEAR) year += 100;
      }


      //print_digit(year);

}

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 6:20 am 
Offline
Member
Member

Joined: Tue Aug 26, 2008 11:24 am
Posts: 159
I solved this by using the RTC to generate an interrupt every second, where I then add one to the seconds.
See https://wiki.osdev.org/RTC


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 8:21 am 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
Thanks a lot for replying me sebihepp. There is a little problem when I'm printing the time in screen. when I try to print the time ,the printed time does not update by seconds. I cant imagine where is the problem.
This is the code I used to print digits.

Code:
uint16 *textmemptr;

void putch(char c)
{
  uint16 *where;
  uint16 att = attrib << 8;

  /* Handle a backspace, by moving the cursor back one space */
  if(c == 0x08)
  {
      if(csr_x != 0) csr_x--;
  }
  /* Handles a tab by incrementing the cursor's x, but only
  *  to a point that will make it divisible by 8 */
  else if(c == 0x09)
  {
      csr_x = (csr_x + 8) & ~(8 - 1);
  }
  /* Handles a 'Carriage Return', which simply brings the
  *  cursor back to the margin */
  else if(c == '\r')
  {
      csr_x = 0;
  }
  /* We handle our newlines the way DOS and the BIOS do: we
  *  treat it as if a 'CR' was also there, so we bring the
  *  cursor to the margin and we increment the 'y' value */
  else if(c == '\n')
  {
      csr_x = 0;
      csr_y++;
  }
  /* Any character greater than and including a space, is a
  *  printable character. The equation for finding the index
  *  in a linear chunk of memory can be represented by:
  *  Index = [(y * width) + x] */
  else if(c >= ' ')
  {
      where = textmemptr + (csr_y * 80 + csr_x);
      *where = c | att;   /* Character AND attributes: color */
      csr_x++;
  }

  /* If the cursor has reached the edge of the screen's width, we
  *  insert a new line in there */
  if(csr_x >= 80)
  {
      csr_x = 0;
      csr_y++;
  }

  /* Scroll the screen if needed, and finally move the cursor */
  scroll();
  //move_csr();
}

void print_digit(int num)
{
    textmemptr = (uint16*) 0xb8000;
    int index = 1;
    char str[80] = "";
while ( num > 0 )
{
    str[index]= '0'+ num%10;
    num = num/10;
    index++;
}
while ( index > 0 )
{
    putch(str[index]);
    index--;
}
}



Please correct me if I wrong because I'm very new to osdev. [-o< [-o<

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 10:23 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
Could be a problem outside the code you are showing. Do you have your project on github or some other similar inline service that can share your code?


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 10:41 am 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
Yeah I uploaded kernel into github.
https://github.com/vishdrck/Osmium-Operating-System-Development/tree/master/kernel
I don't know whats wrong with my code. help me please [-o< [-o< [-o<

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 2:30 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
Looking at your github code where do you actually attempt to print the number of seconds? I see a read_rtc function but no call is made to it that I can find. Your current interrupt handler prints a message every 3 seconds. Since reading the real time clock is a costly task (time wise) you normally wouldn't call read_rtc repeatedly. You can, but performance will suffer. Have you at least tried calling read_rtc from your timer interrupt to see what happens?

You'd usually call read_rtc early on in kernel initialization to set the starting timer tick count, and then update the timer tick every time a timer tick occurred. If you want to print out the time you'd create a routine that takes the number of timer ticks and convert the number of ticks back into years/months/day/hours/minutes/seconds etc to be used for display purposes.


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 9:17 pm 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
Hi MichaelPetch. Yes tried couple of times to print the time. I called read_rtc() in k_main() function. let me show when prints the time.
This is my main kernel function and I initialize my functions here.
https://github.com/vishdrck/Osmium-Operating-System-Development/blob/master/kernel/k_main.c
Code:
void k_main(void)
{
cls();             //clear the screen with blank spaces before use
///upper_line(0,9);
//
    upper_line(0,9); //Line at the top
   read_rtc(); // initializing and print the current time.

print("\n");

print_xy_clr("&&&&&&$                &&&&&&&         &&&&&&&&&\n"
             "&&     &&             &&       &&     &&\n"
             "&&       &          &&          &&   &&\n"
             "&&     &&           &&          &&    &&\n"
             "&&&&&&&             &&          &&     &&&&&&&&&\n"
             "&&         &&&&&&   &&          &&              &&\n"
             "&&                  &&          &&               &&\n"
             "&&                    &&       &&               &&\n"
             "&&                      &&&&&&&         &&&&&&&& \n",15,7,15,0);

    print_xy_clr("Loading\n",37,10,9,0);


    upper_line(11,9); //Line at the bottom

}


This piece of code let me to print time.I put this code into time.c file.
Code:
print("\n Current CPU time is - ");
print_digit(hour);
print(":");
print_digit(minute);
print(":");
print_digit(second);



https://github.com/vishdrck/Osmium-Operating-System-Development/blob/master/Test_Files/1.png
https://github.com/vishdrck/Osmium-Operating-System-Development/blob/master/Test_Files/2.png
https://github.com/vishdrck/Osmium-Operating-System-Development/blob/master/Test_Files/3.png

I have updated github also. https://github.com/vishdrck/Osmium-Operating-System-Development/tree/master/kernel
As my opinion I think I need to make a function like refresh() or similar one for update printed text (exactly printed time). I found read_rtc() returns cpu time regularly but my problem is printed text does not update regularly. It just like I ask for time and os print only requested time.. please give me any advice to solve this.
However thank you MichaelPetch for paying your valuable time.. [-o< [-o<

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 10:23 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
I may be misunderstanding.Is the problem that the time in the virtual machine doesn't match the host machine time? I'm confused. I think there is a bit of a language barrier and I'm not understanding what the problem is. The code you put on Github with the changes doesn't update the time at all. It displays it once when the OS starts and that is it. You don't have a call to read_rtc in timer_handler so I don't see how you expect the time on screen to change


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Wed Apr 25, 2018 11:15 pm 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
MichaelPetch wrote:
The code you put on Github with the changes doesn't update the time at all. It displays it once when the OS starts and that is it.

That is the problem I have. It displays the time once when the os starts.
As a example:
My Windows 10 time is 10:30:57 a.m
I started my virtual machine to load my own os in that time (10:30:57 a.m)
It prints the time as "Current CPU time is - 10:30:57" .I want use it as a clock. So should I need another way to do it?
I hope this :
"Current CPU time is - 10:30:57"
10:30:58
10:30:59
10:31:00
10:31:01
10:31:02 etc. Just like a digital clock.
https://github.com/vishdrck/Osmium-Operating-System-Development/blob/master/Test_Files/giphy.gif
This is the point that I can't solve.It prints the time -> Ok.
But it does not act as a clock.
[-o< [-o< [-o<
If can please be kind enough to tell me some resources to observe about how to build kernel clock?

Sorry about my english grammar.. :cry: :cry:

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Thu Apr 26, 2018 10:54 am 
Offline
Member
Member

Joined: Tue Aug 26, 2008 11:24 am
Posts: 159
Just to be sure: You call the print function in a loop or in a process/task, right?
Otherwise you just have printed the time once. Video memory does not update itself - you have no connection to your time variable, just the value will be copied.


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Thu Apr 26, 2018 11:03 am 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
Oh thanks sebihepp . I found the fault as you said and I got the idea. Thank you so much sebihepp and MichaelPetch :lol: :lol:

_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Thu Apr 26, 2018 12:00 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
Just an observation (not related to your question), but you sure your cls function is correct? You don't seem to initialize textmemptr to 0xb8000. I noticed when I compiled your code my screen didn't actually clear before you updated it with text.


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Fri Apr 27, 2018 12:38 am 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
MichaelPetch...It works to me without any problem. When I only write to print a text "hello" and run it,os prints "hello" to the screen and next I write cls() it clears the screen. Let me inform you and give me a little time to check it. I need to put keyboard controller to the os and then I can find cls() works or not.
However thank you so much!

Code:
//First time
print("hello");
//I got a printed text "hello"

Code:
//Second time
print("hello");
cls();
//I got empty black screen


_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
 Post subject: Re: how to get time for text based os using RTC or else?
PostPosted: Fri Apr 27, 2018 7:39 am 
Offline
User avatar

Joined: Fri Apr 20, 2018 8:00 am
Posts: 9
Location: Sri Lanka
I added a textmemptr = (uint16 *)0xB8000 to the cls(). I think now it is ok. Am I right MichaelPetch ??

Code:
void cls()
{
  /* Fill screen with blank spaces (with current attribute)
attribute stands for current forecolor and backcolor so it fills the screen with current backcolor and no forecolor bcs of blank spaces

*/
   uint16 blank = 0x20 | (attrib << 8);

  textmemptr = (uint16 *) 0xB8000;

  memsetw ( ( uint16 *) textmemptr, blank, 80 * 25);

}


_________________
- vishwajith Weerasinghe -


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot] and 17 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group