0
\$\begingroup\$

I will be starting a project where we use an embedded microcontroller to control a research set-up. We want to control it from a PC, using a USB connection, where we monitor the current state and can tune a wide variety of parameters.

I imagine this as a virtual variable pool: the microcontroller and PC can read from and write to the same variables.

This sounds like a very general situation, so I was wondering, do current solutions exist for such a variable pool? Maybe there already is a library of some kind?

I realise sending bytes back and forward over serial USB is not difficult. But making a flexible protocol to selectively write to variables would already be a lot harder. So anything pre-made would be great.

I'm largely inspired by ADS variables in TwinCAT. The TwinCAT hosts effectively runs a variables server, that other programs can read from/write to.

\$\endgroup\$
2
  • \$\begingroup\$ Right. I've added an emphasis to my question that I mean a virtual pool, so not literally shared memory. Indeed, I imagine the MCU acts as a server and the PC as a client. \$\endgroup\$
    – Roberto
    May 10 at 7:44
  • 1
    \$\begingroup\$ Oh, and product recommendations are off-topic here since they get outdated fast. coughPhidgetscough. \$\endgroup\$
    – DKNguyen
    May 10 at 7:48
4
\$\begingroup\$

Create a packed structure which holds your variables in your controller side. Calculate the size of the structure and give the pointer of the structure into your usb_tx function. Once you get a receive interrupt in your application , parse the incoming data into a same ordered structure. I have used this method and it is quite effective.

\$\endgroup\$
2
  • \$\begingroup\$ Yeah, that's a good option. The downside is it requires the client (the PC) to transmit the entire struct when only a single variable is sent. But maybe this could be expanded to allow an offset, e.g. let the client announce how many bytes at which point in the struct it wants to write. \$\endgroup\$
    – Roberto
    May 10 at 7:51
  • \$\begingroup\$ Even simpler, you can have several structs. Let the PC first send a char to identify which struct to read/write, and then the struct data. It's not very hard to implement. As noted by @swer be sure to use something like "struct __attribute__((packed)) Register {...}" (your compiler may use a different idiom) to avoid padding between fields, which may differ between PC and MCU. \$\endgroup\$
    – DamienD
    May 10 at 10:29
3
\$\begingroup\$

True dual-port memory, which is a very exotic and expensive solution, allows simultaneous read/write operations to the same location and has things to handle collisions and what takes precedence and whether you read the old data or the new data in such a situation.

But your PC will never be able to communicate with dual-port memory directly over USB without going through a microcontroller. So in reality, your PC will communicate to the MCU and requests to read or write from a variable, and the MCU itself directly manages the variables in regular old memory including whether or not the old data or new data is read in a simultaneous write/read and what takes precedence in a simultaneous write.

I can't think of many situations like you describe though where you would actually need both sides to write to the same variable though. Seems to me the vast vast majority of cases would be variables you only write to and variables you only read from.

Also, using a UART-USB bridge tends to be easier than using native USB since you just install virtual COM port drivers on your PC and the MCU and PC software just manipulate UART/RS-232 signals. Native USB is higher bandwidth but takes more work and won't be supported by weaker MCUs.

\$\endgroup\$
1
  • \$\begingroup\$ Right, that makes sense. I should have clarified that I mean a virtual pool, so not literally shared memory. Indeed, I imagine the MCU acts as a server and the PC as a client. And yes, MCU and PC will likely not often write to the same variables. \$\endgroup\$
    – Roberto
    May 10 at 7:48
2
\$\begingroup\$

making a flexible protocol to selectively write to variables would already be a lot harder

There are two things you could copy depending on performance:

  • old style AT commands. AT (letter) (value) writes a value, AT (letter) reads it. Not especially fast but easy to understand and get working.

  • HID reports. These are considerably harder to understand and get working, but provide a generic mechanism for sending data back and forth. More likely to be useful if you eventually write a "real" driver for your device.

\$\endgroup\$
1
  • \$\begingroup\$ "... write a "real" driver for your device.": Do you refer to device drivers for Windows, Linux, macOS? If so, there is really no good reason to write a device driver for USB devices. Either use a standardized protocol like CDC, HID, mass storage or use the generic USB protocol available via libusb, WinUSB and native SDKs. \$\endgroup\$
    – Codo
    May 10 at 13:11
1
\$\begingroup\$

I've just released an open source application that is doing exactly what you want to do.

The application is multiplatform (Win/Linux/MAC) and fully customizable with one file.

It require only two files to add to your microcontroller project. The project is here link to github project

I'm already using it for my job.

EDIT: A summary of the app:

The project has on a one hand an application for a desktop computer (named HOST) and on the other hand two files (monitor.c and monitor.h) to add to the embedded system (named ECU) project. A .ini file is also required by the application and must be written by the user. This .ini file describes exactly what/how/which/when data are transmitted/received by the ECU and also describes how these data are displayed in the application. The application has also a powerful plotting tool that can be used to display and log over time the data sampled.

\$\endgroup\$
2
  • \$\begingroup\$ I would +1, but maybe describe your application more in your answer. \$\endgroup\$
    – Ben
    Aug 25 at 12:36
  • \$\begingroup\$ I've add a small explanation \$\endgroup\$ Aug 27 at 6:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.