How can I reset my SoC from cmm script using RISC-V trace32 debugger. I don't have TRST or SRST serial lines connected to SoC - emulation

My cmm script is something like this :
..start of cmm script
""GTL config and GTL connect""
""some JTAG.SHIFT operations""
JTAG.PIN DISable
system.mode prepare ;Need a reset here. I am trying this to reset my SoC
WAIT 10.MS ;this WAIT command is not working, no 10ms delay observed
system.down
system.mode prepare
...end of cmm script

The normal approach to reset your RISC-V from the debugger without having a dedicated reset line is the following:
SYStem.Option.ResetMode NDMRST
SYStem.Up
SYStem.Option.ResetMode NDMRSTconfigures TRACE32 to perform all system resets via the ndmreset bit of the dmcontrol debug register in the RISC-V debug module (so without physical SRST pin).
SYStem.Up is then actually performing the reset before it connects the debugger with the core. You can also call SYStem.Up from up-state, just to reset your system.
However it looks like, you want to do the reset in prepare-state or even down-state. I guess you should contact the Lauterbach support on how to do that.

Related

Linux program to emulate keystrokes without X

I'm writing a driver for a pda with a goal of converting UART received key numbers to keystrokes.
The way i currently have this system set up is that when a key number is received, i can exec a program. In a config it is defined what command is executed if a certain number is received by my driver. It does this by fork()ing and exec()ing. It runs at boot and immediately parses these key numbers, so i intend to use this instead of a real keyboard.
Is there any program then, with which i could simply do something like
programname KEY_SPACE 1 to press KEY_SPACE
and
programname KEY_SPACE 0 to release KEY_SPACE?
Such a program must work without, as well as with X. I'd also prefer this to be able to do mouse events as well, however if there is a different program to do that, that's fine by me. It can be run as root as well, if need be.
What you need is to use uinput, it allows to emulate input device from userspace. You have documentation here: https://www.kernel.org/doc/html/v5.11/input/uinput.html
It has an example showing how to send a KEY_SPACE press event and then a KEY_SPACE release event.

Cannot implement custom keyboard in u-boot

As known, u-boot loader supports some sort of "input device system" that allows to register a set of functions (like getc, tstc, start, etc...). So I need to implement my own hardware-specific "keyboard". What should I do? Sounds simple:
1) Create at least "init", "tstc", "getc" and "start" functions in driver file.
2) In "init" call "stdio_register" to let system know about my device.
3) Call driver "init" from my custom board init code.
What the problem? Unfortunately, it doesn't work. stdio_register returns 0 (like all OK), but "start", "tstc", "getc" were never called.
I guess I'm doing something wrong, but I cannot understand: another keyboards drivers seems to not contain any additional code for keyboard registration. Can anybody tell the truth?
Or maybe I should just hack u-boot and insert polling call somewhere in main_loop? :)
It sounds like you have created a custom device driver.
struct stdio_dev kon_dev
Try something like this at U-Boot command line to switch console to the custom driver
setenv stdin kon_dev
Of course, your custom driver will have to be debugged before you get to the happy place. It may not work the first time.
Using netconsole is similar to what you're doing. With netconsole it's possible for example to keep stdout continuously on serial device, switch stdin to nc device (that is, "setenv stdin nc", enter commands through that netcat session a while, then switch stdin back to serial.

How to open serial port in linux without changing any pin?

Posix requires changing RTS pin on port opening. I want a way to avoid it.
I have no idea why you'd want to do this, but this can be done pretty easily by modifying the linux kernel driver for your serial console so it doesn't toggle RTS. For example, for the 8250-series driver in drivers/tty/serial/8250/ you could change every write to the MCR register (UART_MCR) to ensure that bit 1 (mask is UART_MCR_RTS) is never set.
Since it's abstracted away in userspace, you're out of luck if you want to do this without modifying the kernel driver.
Having the same problem, I'd give it a try by patching the ftdi_sio kernel driver. You just need to uncomment a small piece of code in ftdi_dtr_rts() like this:
static void ftdi_dtr_rts(struct usb_serial_port *port, int on) {
...
/* drop RTS and DTR */
if (on)
set_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- HERE
else
clear_mctrl(port, TIOCM_DTR /*| TIOCM_RTS*/); // <<-- and HERE
}
and the RTS handshake line is not longer changed upon open() call.
Note, that the uart than might not longer working with RTS/CTS hardware handshake, as long as your modified kernel driver is loaded. But you can still control the state of the RTS handshake line manually by calling e.g.:
int opins = TIOCM_RTS;
ioctl(tty_fd, TIOCMBIC, &opins);
I'd tested this with the Ctrl+A+G command of picocom 2.3a, running Kubuntu 16.04 64 bit and Ftdi FT2232H based usb uart adapter.
You might find more details on this topic here.
A change in the DTR pin can be (eventually) avoided using the command line
stty -F /dev/ttyUSB0 -hupcl
This has the effect of making DTR turn on; and subsequently when the port is opened and closed, DTR is not affected.
Source: https://raspberrypi.stackexchange.com/questions/9695/disable-dtr-on-ttyusb0/27706#27706
And there is code there to do the same thing from python via termios, this can be done before opening the port via pyserial:
import termios
path = '/dev/ttyACM0'
# Disable reset after hangup
with open(path) as f:
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
The OP was running this on a Raspberry Pi, but I just tried it on Linux Mint on x86_64, it worked. I don't know how RTS is affected.
The reason I find this useful, is for communication with an Arduino Nano - which has a USB-> serial chip on board - and normally the Arduino gets reset every time you open the serial port from linux (rising edge of DTR causes reset). For some applications, this is not a problem, but it's clearly useful to avoid this for other applications, and it's not so easy to remove that tiny capacitor from the Arduino which connects DTR to reset.
You will still get a single reset when the stty command is executed (after plugging in the USB cable). But at least you can then keep opening and closing the serial port after that without further resets.
calling fopen("/dev/ACM0", "r") doesn't require you do do anything:) You may not receive the data you expect though.

Inner-workings of Keyboard Event Handling under Linux

When I press a keyboard's key on some GTK application under Linux, what happens exactly? How does a key get received (from which device), interpreted, passed to the program, and then handled?
It's actually rather a complex process...
The keyboard has a 2D matrix of key connections and its own microprocessor or gate array containing a microprocessor. It is constantly scanning the matrix to find out if any keys are pressed. (To save pins, the keys are not individually tested.) The keyboard micro speaks a protocol with the keyboard controller in your CPU and transmits a message indicating a keypress.
The keyboard controller notes the code and interrupts the CPU.
The keyboard driver receives an interrupt, reads the keycode out of a controller register, and places the keycode in a buffer that links the interrupt side of the kernel to the per-process threads. It marks the thread waiting for keyboard input as "runnable"
This thread wakes up. It turns out, this is the X server. The X server reads the keycode from the kernel.
The server will will check to see which window has keyboard focus. The window will be connected to one of various clients.
The server sends an event to the client that displayed that specific window. (Note that to the server, every textbox and such is a "window", not just entire applications.)
The event loop in the client is waiting for the next server event message. This connection could be via TCP or it could be a local Unix feature. It uses read(2) or a socket op to actually get the next event message.
The low-level xlib routine passes the keypress up to higher level widgets, eventually getting to a GTK function of some kind.
The GTK API element hands the character to your program.
I glossed over language mappings, console multiplexing, and a few other things...
Update: So, /dev/input/* and in fact all of the /dev/* things are things called block or character special files. The important thing is that they have no stored data in the filesystem, just a major and minor device number that serve to look up a driver in the kernel in a table. It's almost that simple. If you ls -l /dev/input you will see a major and minor device number instead of a file size. The major number identifies the device driver and the minor number is a sort of instance-number that is passed (within the kernel) as a parameter to the driver.

Serial port determinism

This seems like a simple question, but it is difficult to search for. I need to interface with a device over the serial port. In the event my program (or another) does not finish writing a command to the device, how do I ensure the next run of the program can successfully send a command?
Example:
The foo program runs and begins writing "A_VERY_LONG_COMMAND"
The user terminates the program, but the program has only written, "A_VERY"
The user runs the program again, and the command is resent. Except, the device sees "A_VERYA_VERY_LONG_COMMAND," which isn't what we want.
Is there any way to make this more deterministic? Serial port programming feels very out-of-control due to issues like this.
The required method depends on the device.
Serial ports have additional control signal lines as well as the serial data line; perhaps one of them will reset the device's input. I've never done serial port programming but I think ioctl() handles this.
There may be a single byte which will reset, e.g. some control character.
There might be a timing-based signal, e.g. Hayes command set modems use “pause +++ pause”.
It might just reset after not receiving a complete command after a fixed time.
It might be useful to know whether the device was originally intended to support interactive use (serial terminal), control by a program, or both.
I would guess that if you call write("A_VERY_LONG_COMMAND"), and then the user hits Ctrl+C while the bytes are going out on the line, the driver layer should finish sending the full buffer. And if the user interrupts in the middle of the call, the driver layer will probably just ignore the whole thing.
Just in case, when you open a new COM port, it's always wise to clear the port.
Do you have control over the device end? It might make sense to implement a timeout to make the device ignore unfinished or otherwise corrupt packets.
The embedded device should be implemented such that you can either send an abort/clear/break character that will dump the contents of its command buffer and give you a clean slate on your client app startup.
Or else it should provide a software reset character which will reset the command buffer and all state.
Or else it so be designed so that you can send a command termination (perhaps a newline, etc, depending on command protocol) and possibly have an error generated on the parsing of a garbled partial command that was in its buffer, query/clear the error, and then be good to go.
It wouldn't be a bad idea upon connection of your client program to send some health/status/error query repeatedly until you get a sound response, and only then commence sending configuration or operation commands. Unless you can via a query determine that the device was left in a suitable state, you probably want to assume nothing and configure it from scratch, after a configuration reset if available.

Resources