Getch(), timer_wait(), all that stuff.

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
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Getch(), timer_wait(), all that stuff.

Post by zhiayang »

Great. Not 6 hours after my previous thread, here I am again. Sorry... :oops:

Anyway, I have a question:

For functions like getch(), timer_wait, kbhit(), etc, how does one go about implementing them?
From what I find, using this:

Code: Select all

while(!got_ch)
{
    //Do something
}

//Somewhere else

keyboard_handler(...)
{
    got_ch = 1;
}

doesn't work. If I guessed correctly, (I don't have multitasking yet) the kernel gets stuck in the while loop, because the keyboard handler can't get called? Or do interrupts rip control (figuratively?) from the current function, then transfer control to the handler? If the former is true, does that mean I need multitasking to do stuff like waiting on a timer or keyboard press?

Else, if the latter is true, why doesn't my pseudocode work?
User avatar
brain
Member
Member
Posts: 234
Joined: Thu Nov 05, 2009 5:04 pm
Location: UK
Contact:

Re: Getch(), timer_wait(), all that stuff.

Post by brain »

get interrupt handling working and interrupt routines for the timer and keyboard before you attempt any of this.

Then it may be easier to do mulitasking first

Once youve got that working, consider this below:

Internally functions like getch() should be non-blocking, meaning if there is nothing to do they return an error code, instead of int getch() you'd want "int kgetch(int* character)", the return code indicating status, and if status is valid, setting the character in the pointer parameter.

This way you can poll the state of buffers etc without needing to block your process. This can be used as the lowest level building block on a blocking getch() provided to userland.

Of course if you wanted to be more advanced, events would be better but this certainly needs a more advanced system and i don't think youre quite there yet?

Let me know if this makes sense.
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Getch(), timer_wait(), all that stuff.

Post by zhiayang »

brain wrote:get interrupt handling working and interrupt routines for the timer and keyboard before you attempt any of this.

Then it may be easier to do mulitasking first

Once youve got that working, consider this below:

Internally functions like getch() should be non-blocking, meaning if there is nothing to do they return an error code, instead of int getch() you'd want "int getch(int* character)", the return code indicating status, and if status is valid, setting the character in the pointer parameter.

This way you can poll the state of buffers etc without needing to block your process.

Of course if you wanted to be more advanced, events would be better but this certainly needs a more advanced system and i don't think youre quite there yet?

Let me know if this makes sense.
Ah. But err... I'm at the memory management stage, I do have interrupt handling and all that.

So based on your advice, how would I wait for user input?

if I were to use

Code: Select all

while(!getch(*ptr))
{
    //DO something
}
Wouldn't that have the same effect?

:?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Getch(), timer_wait(), all that stuff.

Post by Brendan »

Hi,
requimrar wrote:Anyway, I have a question:

For functions like getch(), timer_wait, kbhit(), etc, how does one go about implementing them?
The "getch()" and "kbhit()" functions look like they should be built on top of some sort of IPC. Start by deciding how separate pieces of software (e.g. processes) should communicate with each other, then implement it, then design device driver interfaces to suit your IPC, then implement device drivers for things like keyboard, mouse, etc (that send data like characters and keypresses via. your IPC to whatever is listening at the other end).

The "timer_wait()" function looks like something that should be built into the scheduler - put some sort of reference to the task/thread onto some sort of queue, then tell the scheduler not to give the task/thread any CPU time. Then you'd have a timer IRQ that wakes tasks/threads up and tells the scheduler to give the "woken" tasks/threads CPU time again.

In general, there's an order to implement things. Normally it's (very roughly) something like "memory management, then scheduler, then IPC". If you start trying to mess about with device drivers, GUIs or applications before you've got the fundamental stuff done then you're wasting your time. It's like trying to build a house - you don't start with the roof, you start with the foundation.


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
brain
Member
Member
Posts: 234
Joined: Thu Nov 05, 2009 5:04 pm
Location: UK
Contact:

Re: Getch(), timer_wait(), all that stuff.

Post by brain »

no, you would need to actually implement the kgetch function.

Here is how i do it:

1) at the lowest level, the keyboard driver handles keypress interrupts, placing ascii codes into a buffer. The buffer has a read pointer and a write pointer, pressing keys increments the write ptr and reading keys increments the read ptr. The buffer is 'circular' and wraps round so long as the write ptr doesnt 'lap' the read ptr (which means buffer is full)

2) an internal kgetch function checks if there are characters in the buffer. If there are, it returns the tail item from the list, and removes it. If there are not it returns an error code.

3) in userland, a library calls kgetch, and uses this to build up a buffer if and when keys arrive. While the buffer is not complete (e.g. enter is not pressed) the process is 'blocked' meaning it is not run unless kgetch() returns non-error.

4) when kgetch() returns success AND an enter keypress, then the input is complete and the process stops calling kgetch(), the process ceased to be blocked and the input is complete.

In short you have to do all of this yourself... It takes a fair while to code it :)
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Getch(), timer_wait(), all that stuff.

Post by zhiayang »

brain wrote:no, you would need to actually implement the kgetch function.

Here is how i do it:

1) at the lowest level, the keyboard driver handles keypress interrupts, placing ascii codes into a buffer. The buffer has a read pointer and a write pointer, pressing keys increments the write ptr and reading keys increments the read ptr. The buffer is 'circular' and wraps round so long as the write ptr doesnt 'lap' the read ptr (which means buffer is full)

2) an internal kgetch function checks if there are characters in the buffer. If there are, it returns the tail item from the list, and removes it. If there are not it returns an error code.

3) in userland, a library calls kgetch, and uses this to build up a buffer if and when keys arrive. While the buffer is not complete (e.g. enter is not pressed) the process is 'blocked' meaning it is not run unless kgetch() returns non-error.

4) when kgetch() returns success AND an enter keypress, then the input is complete and the process stops calling kgetch(), the process ceased to be blocked and the input is complete.

In short you have to do all of this yourself... It takes a fair while to code it :)

Great, thanks.
Post Reply