How to connect GPIO in QEMU-emulated nachine to an object in host?

I need to connect the GPIO pins in the ARM machine emulated in QEMU to the GUI objects in application working on the host machine.

For example, the level on the output GPIO should be reflected by a color of a rectangle. The input GPIO should be connected to a button. When the butt on in GUI is pressed, the input GPIO should be read as zero (otherwise as o ne) etc. Of course the input GPIOs should be also capable of generating the interrupts.

In fact it would be perfect to connect the emulated pin to a pipe or socket so that a change of the state caused by QEMU would produce a message sent to the host, and the appropriate message sent by the host should trigger th e appropriate change of the state of GPIO in QEMU (and possibly generate an interrupt).

I have created a few own peripherials for QEMU (e.g,

formatting link
) but implementation of such G PIO seems to be not trivial.

Up to now I have found that material:

formatting link
but it uses relatively old QEMU. Additionally, the proposed solution is compatible onl y with the old sysfs-based method of handling GPIOs.

Are there any existing solutions of that problem? I'll appreciate any hints or suggestions.

TIA & Regards, Wojtek

Reply to
wzab01
Loading thread data ...

I think that the application implementing the GUI could use msgpack (

formatting link
) protocol to communicate the QEMU. So whenever the QEMU changes the state of the pin, it sends a message contining two fields: Direction: (In, Out) State: (High, Low, High Impedance)

Whenever somebody changes the state of the pin in the GUI, similar message is sent to QEMU, but it should contain only one field: State: (High, Low)

I assume that the logic that resolves collisions and generates the random state when somebody tries to read the not connected input should be implemented in the GUI application.

What do you think about it?

Reply to
wzab01

In a version of QEMU modified by Xilinx I have found something that either maybe a solution, or at least provides means to find the solution.

These are the files with names starting with "remote-port" in the

formatting link
and
formatting link
directories.

Reply to
wzab01

According to

formatting link
(chapter Remote-Port, page 37), the remote-po rt is intended for cosimulation with System-C. It is not clear if it can be easily interfaced with user designed GUI...

Reply to
wzab01

I have found a newer solution based on

formatting link
It is available in the
formatting link
repository. However, it is not clear if it is libgpiod compatible.

Reply to
wzab01

I have managed to modify the model of the MPC8XXX GPIO in QEMU so that it w orks together with the GUI written in Python. The communication is establis hed via POSIX message queues. The code is available at alt.sources group ht tps://groups.google.com/forum/#!topic/alt.sources/_EbOdnQKZ18 The full project that uses the modified MPC8XXX in an emulated Vexpress A9 board is available in in

formatting link
reposit ory in branch "gpio". The code is just a "proof of the concept" so it lacks error checking, and p robably is buggy, but it works for me. I hope that somebody may find it useful and develop the concept further.

With best regards, Wojtek

PS. The concept is inspired by the "remote port" solution introduced by Xil inx in their version of QEMU (see the files with names starting with "remot e-port" in the

formatting link
and ht tps://github.com/Xilinx/qemu/tree/master/hw/core directories.)

Reply to
wzab01

My code handles input and output, but still has a problem with interrupts. When I enable interrupt for a pin, then I get error in QEMU:

buildroot-2020.02/output/build/host-qemu-4.2.0/accel/tcg/tcg-all.c:40:tcg_handle_interrupt: assertion failed: (qemu_mutex_iothread_locked())

Obviously I must modify handling of input so that interrupts are not triggered when mutex is locked.

Reply to
wzab01

OK. It appeared that the problem was trivial. I have learned the solution from

formatting link

I simply had to call qemu_mutex_lock_iothread(); before calling qemu_set_irq() and qemu_mutex_unlock_iothread() after, when generating IRQs in my thread:

static void * remote_gpio_thread(void * arg) { //Here we receive the data from the queue const int MSG_MAX = 8192; char buf[MSG_MAX]; gpio_msg * mg = (gpio_msg *)&buf; mqd_t mq = mq_open("/to_qemu",O_CREAT | O_RDONLY,0x660,NULL); if(mqmagick[1] != REMOTE_GPIO_MAGICK) { printf("Wrong message received"); } if(mg->pin < 32) { qemu_mutex_lock_iothread(); mpc8xxx_gpio_set_irq(arg,mg->pin,mg->state); qemu_mutex_unlock_iothread(); } } }

Reply to
wzab01

The version of my emulated GPIO connected to the GUI is quite mature. It even simulates the bouncing effect in buttons and switches. You may find it in

formatting link

Regards, Wojtek

Reply to
wzab01

I have found a similar interesting solution:

formatting link
described in:
formatting link

Regards, Wojtek

Reply to
wzab01

Today I have added support for simulated buttons/switches/LEDs in U-Boot, s o my students may also experiment with systems equipped with the button-sel ectable "rescue mode" (or "administrative mode"). The design is in the bran ch "gpio_uboot" of the

formatting link
repository .

Reply to
wzab01

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.