what is the different between cgaputc(int c) / uartputc(int c) / constputc( int c) in xv6? - c

In xv6 MIT operating system, I'm trying to understand what is the different between the a few putc functions in /xv6/console.c
static void cgaputc(int c).
void uartputc (int c).
static void constputc(int c).
Thanks!

consputc() is a console output function. It writes a char to the console, which in that OS appears to mean both the serial port and the CGA text display. Before doing that, it first checks if the system has panicked (a panic is the state which the kernel enters when it has encountered an error and doesn't know what to do, so instead of going ahead and probably making matters worse decides to panic and stop), and if so, enters an infinite loop with interrupts disabled, so only a system reset can leave the panic state.
uartputc() writes a char to the serial port. It first checks that the serial port is not busy, and will accept the char.
cgaputc() writes a char to the CGA text framebuffer, and adjust the cursor position accordingly. The CGA text framebuffer starts at address 0xb8000, and consists of interleaved (attribute, character) bytes. The default mode, mode 3 is a 80x25 (80 columns, 25 rows) text mode. Attribute 07 means gray text on black background. The cursor position is manipulated via the CRT controller port, which exposes several registers, registers 14 and 15 hold the cursor position as 14 bits. The CRTC is accessed by first selecting a register to access by writing its number to the index CRTC port at 0x3d4, and then writing or reading from the CRTC control/data port at 0x3d5. This stuff is documented in a document called vgadoc4b, and in Ralph Brown's interrupt list.

You can see what all these functions do if you consult the code.
consputc(int c) clears interrupts then calls uartputc() and then calls cgaputc().
uartputc(int c) uses in and out to write c to the serial port (UART)
cgaputc(c) appears to be a console input/output function. Writes c to the serial port or the console, and it also sets the position of the cursor and sets the color for the console (black on white)
That's what I get from reading the code anyway, I have not used these functions before, but it seems pretty straight forward.

Related

EhBASIC input on 6502 emulator

I have been working on this 6502 emulator for a while, and I'm tying to get a simple Enhanced BASIC ROM to work. Although it lacks precise clock timing, the emulator did pass AllSuiteA.asm.
With EhBASIC, I've managed to get some output by printing the value of $F001 when a read is done to that address.
if(lastwrite == 0xF001)
{
printf("%c",CPUMEM[0xF001]);
}
However, I have no idea how to emulate the input process. This post states that whenever EhBASIC wants input, It will poll $F004. But my current code seems to have two problems:
while(1)
{
decodeandexecute();
if(lastread == 0xF004)
{
inputchar = getchar();
CPUMEM[0xF004] = inputchar;
}
if(lastwrite == 0xF001)
{
printf("%c",CPUMEM[0xF001]);
}
}
Input is only possible through individual letters (Expected)
After the program asks for memory size, giving any input will just cause a loop of reading from $F004 (LDA $F004) - i.e. I can't let EhBASIC know when to stop receiving inputs
I want to know an effective method of entering a string of characters, and getting passed "memory size?".
Additionally, if I want to let EhBASIC calculate the memory size automatically, what should I input to $F004?
I'm pretty much a newbie in this area....
I see you use getchar in the code and if I remember correctly that is a blocking call (it will wait until someone presses some key).
In the manual of ehbasic it says:
How to.
The interpreter calls the system routines via RAM based vectors and,
as long as the requirements for each routine are met, these can be changed
on the fly if needs be.
All the routines exit via an RTS.
The routines are ...
Input
This is a non halting scan of the input device. If a character is ready it
should be placed in A and the carry flag set, if there is no character then A,
and the carry flag, should be cleared.
One way to deal with this is to use two threads. One thread that runs the emulation of the 6502 running ehbasic and another thread that polls the keyboard.
Then let the polling thread push any input key strokes into a small buffer from which the ehbasic input routine can use.
Manual: http://www.sunrise-ev.com/photos/6502/EhBASIC-manual.pdf
UPDATE
Reading the question/answer you linked to, I see it is a modified ehbasic.
Your keyboard polling thread should place the keystrokes read in $F004 (and after a while clear F004 again - if I understand the instructions).
UPDATE 2
As a debugging tip: In you first version simply have a string with a fixed input such as 10 print "hello" 20 goto 10 and feed $f004 from there. That way you don't have to worry about any problems with using an actual keyboard.

Forcing raw serial mode in C - linux

Not sure how to word the title, but what I'm trying to do is test my micro controller with my Linux PC to ensure data is correct. After hours of searching, I found out that the stty command can change how data is managed through the serial port and it turned out that by default if xon or xoff characters are received from the port, they don't get displayed. At first I thought my computer was too slow that I was losing characters at 57.6Kbps but that wasn't the case.
Back in the day when I was playing with the serial mouse in QuickBasic for DOS, I could use this command to start the serial port:
OPEN "com1:1200,n,7,1,op0" for binary as #1
So what I want to do now is create something simple in C that would allow me to open up the serial port in the rawest mode possible. I want it so that whatever data I give to it is sent to it unmodified. I also want to receive data unmodified. so if the controller decides to send a character the PC would recognize as a special control code, I still want to see the character, not have the PC go funny just because a character matches a control code.
One idea I thought of is to create a fork to the stty program and use nearly every (50+?) parameters added to the program making the requirement of program stack space a bit high.
Another idea I thought of is to do direct I/O with the port address itself (using inb and outb) but I'm not sure if the kernel would run those commands through anything else before the data reaches the port, but I'd rather use that as a last option in case I ever replace my computer and the serial port value changes (or becomes a serial port made through USB to serial converter hardware).
so rather than inb and outb and those variants (like inw), and without executing stty with specifying 50+ parameters in my program, is there a function in C I can use (without requiring a special library not included with a standard linux distribution) to force the serial port device as a raw device so I can do any I/O on it without the kernel modifying or dropping data?

Init a serial communication with c library open() causes TX to send one bit on RPi

I'm trying to set up a serial communication between the RPI and an FPGA. However, there is an issue when using the standard C library open() to init the serial interface: I'm using a scope to monitor what is sent and received via the RX and TX lines. A call to open causes the TX line of the RPI to go low for the length of one bit. I do not see this behavior with other computers/linux PCs. The point is, the FPGA assumes a valid transmission, since he thinks it's a start bit, but it's not.
I checked with minicom installed on the RPI. Same thing. Starting minicom causes the TX line sending one bit. Once minicom has started, the communication runs as expected and all bytes have the correct frame size. Is there any way to suppress the TX line going low upon the open call to init the serial communication? Is this an expected behavior?
This is a super far-fetched hunch, but this code seems a bit suspicious, from the pl011_startup() function in the PL011 serial port driver:
/*
* Provoke TX FIFO interrupt into asserting.
*/
It seems as if it's twiddling the TX line when starting up the port, which would explain the pulse you're seeing. More investigation would surely be needed before concluding this is what happens, of course.
So, I guess my "answer" boils down to: that sounds weird, perhaps it's something with the driver?
Of course, one way of working around this is to apply some care in the FPGA end, assuming you have more control over it. "Proper" framing would take care of this, and make it clear that the spurious send can be discarded.
UPDATE: I meant that if "proper" messages were to be always framed by some sequence of bytes, the FPGA might be able to discard invalid ("unframed") data anyway, and thus become immune to the random pulse. For instance, messages could be defined to always start with SOH (start of header) or SOT (start of text) symbols (bytes with the values 0x01 and 0x02, respectively).

Can I log variable value to a file without break points in gdb?

Is it possible to log for ex: array values to a log file without using break points in gdb?
I used this:
set logging on some_file
b func
command 1
p print_clock_cycles
c
end
Aim: To log the clock cycles value to a file through gdb. The logging can be infinite so I cannot use the existing memory.
My problem: In case I am printing the clock cycles by reading a register, the value is different when printed with the above script when compared to without breakpoint (reading by some other means which I do not want to use due to memory constraints). I am assuming gdb is taking some more time to print when we have a break point which is affecting the clock cycles. I do not have any other debugger for ex jtag attached.
Is there any other means by which I can log the value?
Thanks
Do you have a serial port available? When I develop on embedded platforms, that's a good way to save debugging information.
I wrote functions to manage the serial port. My "print" functions queue up string data in a buffer, and the serial ISR drains data out of the buffer. As long as the serial port can drain the buffer fast enough it never fills up.

Use keyboard as stdin

I do not know how I can obtain user inputs from a keyboard and display those inputs to a terminal emulator (Real term).
I usually do the following to set up the stdin. However, I do realize that I cannot have the word KEYBOARD as a stream.
FILE receive_str = FDEV_SETUP_STREAM(NULL, KEYBOARD , _FDEV_SETUP_READ);
stdin = &receive_str;
The program is compiled with AVR Studio 4.18 under Windows 7, targeting an ATmega 32 microcontroller.
See http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html for information on the FDEV_SETUP_STREAM method of setting up stdio. In particular, what you put as "KEYBOARD" in your example above is supposed to be the function that provides the keyboard input. So the way you've written your code means that it's looking for a function like this:
int KEYBOARD(FILE *stream)
{
return 'A';
}
This would be a stream that always returns the letter A, for example. Of course, it's up to you to fill in that function with whatever code is necessary to read from whatever keyboard hardware you have connected to your microcontroller.
The avr-libc manual linked above describes the other values you can return from this function, too, like _FDEV_ERR (if an error occurred) or _FDEV_EOF (if it's the end-of-file, i.e., there is no more input to read).

Resources