Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dual terminal support #56

Merged
merged 8 commits into from
Dec 3, 2014
Merged

Dual terminal support #56

merged 8 commits into from
Dec 3, 2014

Conversation

wchill
Copy link
Contributor

@wchill wchill commented Nov 30, 2014

Support for two terminals in the emulator. Closes #19

Note that sometimes junk and/or the error message mkdir: can't create directory '/tmp/root-runtime-dir': File exists will appear in either terminal window; as far as I can tell this is related to how the login process is now handled in /etc/inittab and does not affect functionality in any way.

To switch between terminals, press the newly added arrow button in the top right corner of the terminal. Fullscreen state is maintained between switches. gcc compilation still happens in the first terminal window, but this can be changed later if necessary.

hdgcc-mod.bz2 (the disk image) has been modified to start getty on boot. /etc/inittab and /bin/autologin were modified to achieve this.

There is a test setup running on http://tf2.intense.io:9000/#playground

@wchill
Copy link
Contributor Author

wchill commented Nov 30, 2014

Additional note: terminal 1 now runs using /dev/ttyS0 instead of /dev/console - there were some very strange bugs when attempting to stick with /dev/console.

/dev/ttyS1 was also used instead of just /dev/tty1 because all the data sent to tty1 would get stuck in the receive buffer due to control registers not being toggled (I spent several hours trying to figure this out). Opening tty1 as a serial port (ttyS1) toggles the appropriate registers and allows TX/RX to work properly.

@angrave
Copy link
Contributor

angrave commented Nov 30, 2014

Getting the virtual UART to work reliably (albeit slowly in some cases)
for large transfers that exceed kernel buffer (e.g. 8K) took most of the
Summer :-)
It's a bit of a hack because the kernel does not expect a near infinite
incoming bandwidth from the UART (e.g. when the Kernel is in idle mode)
so we deliberately try to rate-limit the receiving bandwidth by CPU
instructions retired.

The UART requires RTSCTS handshaking_; this will need to be set for
*each_ terminal.
There should be a stty command (e.g. stty -clocal crtscts -ixoff )
somewhere...

So I expect you'll need ...

|
|
|

stty -F /dev/ttyS0 -clocal crtscts -ixoff
stty -F /dev/ttyS1 -clocal crtscts -ixoff
|

|
|

var onTTYLogin = function (completed) {

this.sendKeys('\nstty -clocal crtscts -ixoff\ngcc hello.c;echo
boot2ready-$?;rm a.out\n', 'boot2ready-0', onBootFinished);

For each tty because we're bringing the kernel's view of the hardware
inline with the actual UART settings; so maybe this belongs in the
/etc/inittab script
(The only reason it's not there is because it's a pain to mount and
edit; and I'm concerned about entropy of those images - the more we
modify them the harder it is to replace them/understand bugs in the future)

((FYI Other handshaking is possible - e.g. S_ON S_OFF characters -
however they are not quick enough to prevent buffer overflow and
incoming chars are dropped.
This leads to corruption of longer programs that are 'typed' in by the
front-end - by the time the kernel sends out the 'please stop!' char to
the UART - it's already too late
FYI Rate limiting code starts here and then jumps into uart.js
https://github.com/cs-education/jor1k/blob/master/js/worker/system.js#L364

))

L.
On 11/30/14 6:37 AM, Eric Ahn wrote:

Additional note: terminal #1
#1 now runs using
|/dev/ttyS0| instead of |/dev/console| - there were some very strange
bugs when attempting to stick with |/dev/console|.

|/dev/ttyS1| was also used instead of just |/dev/tty1| because all the
data sent to |tty1| would get stuck in the receive buffer due to
control registers not being toggled (I spent several hours trying to
figure this out). Opening |tty1| as a serial port (|ttyS1|) toggles
the appropriate registers and allows TX/RX to work properly.


Reply to this email directly or view it on GitHub
#56 (comment).

@wchill
Copy link
Contributor Author

wchill commented Nov 30, 2014

Yep, I had a hell of a time trying to trace the flow of the UART code.

I didn't try setting parameters using stty during the bootup sequence because I could not figure out why tty0 would accept input and tty1 would not, other than the observation that tty0 happens to be the lowest number and logically /bin/login would use that to start a terminal session. I'll go ahead and try that out.

@neelabhg
Copy link
Member

neelabhg commented Dec 2, 2014

@wchill Is the test setup you hosted running your latest changes? The compilation does not seem to work (An exception is thrown when the compile button is pressed).

SysViewModel.getInstance().ttyFullScreen.subscribe(function () {
this.lastMouseDownTarget = this.terminalcanvas;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change this? Based on your hosted test setup, currently what happens is when you switch to full screen on the first (left) terminal, the focus is set to the second terminal -- hence anything you type is sent to the second (right) terminal.
You need to set focus to the terminal on which the full screen button was clicked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I forgot to fix that. I'll get around to fixing that.

Compilation is most likely because terminal one is using a different TTY device, I will look into that also

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your latest commit fixed it.

@wchill
Copy link
Contributor Author

wchill commented Dec 2, 2014

Just found out why compilation causes an exception: sendKeys() in sys-runtime.js requires selecting which tty device to use. live-edit.js line 48 was not updated to use that new format (should be this.runtime.sendKeys('tty0', 'clear\n");)

I edited the file using Chrome's developer tools and verified that this fixes it. Will fix in next commit.

@wchill
Copy link
Contributor Author

wchill commented Dec 2, 2014

Also Neelabh, yes the test setup is running directly off my dual branch.

@neelabhg
Copy link
Member

neelabhg commented Dec 3, 2014

Also, can you edit the PR description to briefly describe what you changed in the binary file app/jor1k_hd_images/hdgcc-mod.bz2?

@wchill
Copy link
Contributor Author

wchill commented Dec 3, 2014

Done.

@wchill
Copy link
Contributor Author

wchill commented Dec 3, 2014

I've pushed a new commit fixing the two previous mentioned bugs, please review.

this.terminput = new TerminalInput(new UARTDev(this));
this.termTwo = new Terminal(24, 80, termIdTwo);
this.terminput = new TerminalInput(new UARTDev(this, termId));
this.terminputtwo = new TerminalInput(new UARTDev(this, termIdTwo));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the tty parameter to the UARTDev constructors be the literal strings 'tty0' and 'tty1' instead of termId and termIdTwo?
The uart sends the command to the worker which only understands 'tty0' and 'tty1' - it doesn't know about the HTML element ids. It just happens that the element ids are the strings 'tty0' and 'tty1' so everything works.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was deliberate on my part, I prefer not to use hardcoded constants and it makes sense if you think of a terminal canvas 'attaching' to a UART for I/O.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. However, the way I see it is that you are supposed to use the hardcoded constants. The jor1k codebase, sys-runtime.js and live-edit.js all use these string constants to refer to the ttys. These should ideally be global constants/enums or something instead of strings. If you want to use the element ids to refer to the ttys then the ids should be constants - the element ids shouldn't then be passed in as parameters to the Jor1kGUI constructor. What happens if the HTML programmer uses some different ids and passes them to the Jor1kGUI constructor? The very fact that the ids are accepted as params means that we cannot rely on them being the constants we expect them to be. If you want to get rid of the constants entirely, then you'll need to modify jor1k itself or somehow map from the term ids to the constants. This was just my opinion, what do you think?

Anyway, no changes are required, I just merged in your code.

@neelabhg
Copy link
Member

neelabhg commented Dec 3, 2014

I just merged PR #55 , which is causing merge conflicts with this one. Do you mind merging the changes and updating your branch? I think the following steps should do it:

git fetch upstream
git checkout master
git merge upstream/master
git checkout dual
git merge master
git push origin dual

Hopefully git will be able to auto-merge so that you do not have to do it manually.

@neelabhg neelabhg merged commit 09ae919 into cs-education:master Dec 3, 2014
@neelabhg
Copy link
Member

neelabhg commented Dec 3, 2014

Nevermind, I did it manually from the command line.

@wchill wchill deleted the dual branch December 4, 2014 11:11
@neelabhg neelabhg added this to the UIUC senior project Fall 2014 milestone Dec 6, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Two terminals
3 participants