I have a C++ (technically MATLAB mex) program, which I am planning to use to launch a stand-alone pure C++ slave program on my system. The master calling program may look something like the following:
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]){
system ("path/to/slave/program");
}
Once the slave is launched, I would then like to have a second mex program which will communicate with and send data to the slave program. The data sent will be in the form of large-ish C++ arrays.
I imagine that I will need some kind of handle to the slave program (perhaps its pid?), a method for sending messages and presuamably a way for the slave program to listen out for incoming messages.
I have no experience in getting separate C++ programs to communicate with each other, so any hints in this area would be appreciated. In addition, if there are any specific MATLAB mex-specific caveats, I would be interested to hear about these.
EDIT: I should have mentioned that I am building this on Ubuntu, but will ultimately like it to work on all platforms. Platform specific advice very welcome, but multi-platform ideas are really what I'm after.
You are looking for an IPC (Interprocess Communication) mechanism.
Boost has an entire chapter on this and is a cross-platform solution.
Boost.Interprocess has been tested in the following compilers/platforms:
Visual 7.1 Windows XP
Visual 8.0 Windows XP
GCC 4.1.1 MinGW
GCC 3.4.4 Cygwin
Intel 9.1 Windows XP
GCC 4.1.2 Linux
GCC 3.4.3 Solaris 11
GCC 4.0 MacOs 10.4.1
If you have time, as suggested in previous answers, you should definitely go for IPC.
However, there is also many "quick and dirty" solutions, where you don't need to spend time reading any documentations.
The one I can recommend you, is to use files. When you want to communicate, Process 1 write down a file with the arguments. And then another file to say that the arguments are ready. Process 2, have a loop waiting for this second file. If it finds it, it remove it and then read the arguments.
I know this is dirty, but this is very fast to program, and no need to read any documentations.
If you have large arguments, and you would waste a lot of time writing them on the hard disk. I suggest you something even dirtier: mounting the RAM, and writing on it:
mkdir -p /tmp/ram
sudo mount -t tmpfs -o size=512M tmpfs /tmp/ram/
I highly recommend COM technology for all Windows communication.
http://www.microsoft.com/com/default.mspx
By the way, if you want to use Matlab code directly, you can compile COM component using Matlab Builder NE, so you don't need to write mex at all.
If you're looking for a cross platform solution for communication checkout boost::interprocess. The documentation also has quite a bit of information about how these things work.
This is platform specific, but on a POSIX platform you can use popen(3) to launch a command, giving you a pipe you can use to write data to its standard input (and also read from its standard output).
More portably, but less simply, the Boost.Interprocess library has all sorts of ways of communicating between processes.
Related
I'm currently getting familiar with PLC's, the WAGO 750-8206 PLC in particular. It offers a linux OS and can run CoDeSys programs. There are some I/O modules attached to the controller: 750-530, 750-430 and 750-600. What I would like to know is this:
Is it possible to write a C++ linux application that runs on the PLC and gets/sets the digital inputs and outputs?
Even better: can I write a CoDeSys program that "talks to the I/O's" and handles all the logic and at the same time can be accessed by a C++ linux program? THe idea is this: I would like the CoDeSys program to check for let's say two digital inputs. If both are high, a variable should be set to a defined value. The linux application should be able to read that variable and conduct further processing (such as sending JSon data to a server or similar).
Also, I would need to be able to send commands from the linux application to the CoDeSys program in order to switch digital outputs (or set values on analog outputs etc) when the linux application receives a message that triggers the command.
Any thoughts and comments on this topic are greatly appreciated as I am completely new to this topic. Thanks in advance!
The answer you might want
The actual situation has changed into the opposite of the previous answer.
WAGO's recent Board Support Packages and Documentation actively support you in making changes and extensions to the PLC200 line. Specifically the WAGO 750-8206 and 17 (as of March 2016) other PLCs :
wago.us -> Products -> Components for Automation -> Modular WAGO-I/O-SYSTEM, IP 20 (750/753 Series)
What you have to do is get in touch with them and ask for their latest Board Support Package (BSP) for the PLC200 line.
I quote from the previous answer and mark the changes, my additions are in bold.
Synopsis
Could you hack a PFC200 and get custom binaries executed? Probably Absolutely yes. As long as the program is content to run on the Linux-3.6.11 kernel and glibc-2.16 and is compiled for the "armhf" API, any existing ARM application, provided you also copy the libraries it uses as well, will just run without even compiling it specifically for the PFC200.
Would it be easy or quick? No. Yes, if you have no fear of the Linux Command line. It is as easy as using the Cross Compiler provided by the Board Support Package (BSP) with the provided C-libraries and then run this to transfer your program to the PFC's flash and run it: scp your-program root#PFC200:/usr/bin
ssh root#FC200 /usr/bin/your-programOf course, you can use Eclipse CDT with the Cross Toolchain for the PFC200 and configure Eclipse to do do remote run and debug.
Will this change in the future? Maybe. Remember that PFC200 is fairly new in North America.It has, PFC200 has appeared in September 2014
The public HOWTO Building FORTE for Wago describes how to use the initial BSP to run FORTE, which is the IEC 61499 run-time environment of 4DIAC (link: sf.net/projects/fordiac ), an open source PLC environment allowing to implement industrial control solutions in a vendor neutral way. 4DIAC implements IEC 61499 extending IEC 61131-3 with better support for controller to controller communication and dynamic reconfiguration.
In case you want to access the KBUS (which talks to the I/Os) directly, you have to know that currently only one application can be in charge of KBUS.
So either CODESYS, or FORTE, or your own KBUS application can be in charge of the KBUS.
The BSP from 2015 has many examples and demos how to use all the I/O of the PLC200 (KBUS, CAN, MODBUS, PROFIBUS as well as the Switches and LEDs on the PFC200 directly). Sources for the kernel and with all kernel drivers and the other Open Source components is provided and compiled in the Board Support Package (BSP).
But, the sources for the libraries and tools developed from scratch by WAGO and are not based on GPL/Open Source code are not provided: These include the Application Device Interface(ADI)/Device Abstraction Layer(DAL) libraries which do CANopen, PROFIBUS-Slave and KBus (which is used all PLC I/O modules connected to the main PLC unit)
While CANopen is using the standard Linux Socketcan API to talk to the kernel and you could just write a normal socketcan program using the provided libsocketcan, the KBus API is an WAGO-specific invention and there, you'd have to do some reverse-engineering if you'd not want to use WAGO's DAL for accessing all the electrical I/O of the PLC, but the DAL is documented and examples how to use it are provided in the BSP.
If you use CODESYS however, there is an "codesys_lib_demo-0.1" example library which shows how to provide a library for CODESYS to use.
Outdated Answer
This answer was very specific to circumstances in 2014 and 2015. As of 2016, it contains incorrect information. Still going to leave as-is for now to provide background.
The quick answer you probably don't want
You could very reasonably write code using Codesys that put together a JSON packet and sent it off to a server elsewhere. JSON is just text, and Codesys can manipulate text in a fashion very similar to C. And there are many ethernet protocols available from within Codesys using addon libraries provided by Wago.
Now the long Answers
First some background
Since you seem to be new to Wago and the philosophy of Codesys in general... a short history.
Codesys is used to build and deploy Hard Realtime execution environments, and it is important to understand that utilizing libraries without fully understanding the consequences can destabilize performance of the entire system (bringing Codesys to its knees and throwing watchdog errors in the program). Remember, many PLC's are controlling equipment that could kill someone if it ever crashed.
Wago is fond of using Linux to provide the preemptive RT kernel for the low level task scheduling and then configuring Codesys to utilize much of the standard C-libraries that often accompany linux. Wago has been doing this for quite some time, but they would never allow you to peel back the covers without going through Codesys (which means using IEC 61131 languages, of which C++ is not included), and this was for your own safety (and their product image). If you wanted the power of linux on a Wago, you had to get a special PLC with a completely naked OS, practically no manual or support, and forfeit the entire Codesys runtime.
The new PFC200's have much more RAM and memory available than recent models, allowing for more of the standard linux userland stack (ssh, ftp, http,...) to be included without compromising the Codesys runtime, and they advertise this. BUT... they are still keeping a lid on compilation tools and required header files needed to compile and link to Codesys libraries or access specialized hardware (the Wago KBUS, which interfaces your I/O modules).
The Synapsis
Could you hack a PFC200 and get custom binaries executed? Probably yes.
Would it be easy or quick? No.
Will this change in the future? Maybe. Remember that PFC200 is fairly new in North America.
Things you may not know
Codesys does not necessarily know or care about Wago. You can get Target Platforms for Codesys that do target Intel processors running a linux os. Codesys DOES SUPPORT accessing external libraries (communication in the reverse direction is dangerous), but they often expect a C style interface, and you can only access those libraries by defining C-headers that Codesys will analyze, so you may need to do some magic to get C++ working seemlessly. What you can do is create a segment of shared memory that both C++ and Codesys access, and that is how they pass information (synchronization is another problem).
You can get an Open Wago PLC, running Codesys on Linux. Wago's IPC are made specifically for this purpose. They have more power, memory, and communication capabilities in general; but they do cost more than double your typical Wago PLC.
If you feel like toying with the idea of hacking a Wago, you will need to tear apart the manuals for Codesys (it has its own), the manuals for the Wago IPC's, and already be familiar with linux style inter-process-communication and/or dynamic libraries.
Also, there is an older Wago PLC that had the naked Linux on it 750-8??. It also has a very good manual on how to access the Wago hardware using supplied headers.
You must first understand how Codesys expects to talk to its target operating system. Then you work backwards to make it talk to Wago specific libraries living on that operating system. You must be careful not to hijack Codesys.
Your extra C++ libs should assist Codesys, not take it over. For instance, host a sqlite database on the same device, and use C++ to manage the database and provide a very simple interface that Codesys can utilize. All Codesys would do is call a function and pass some values, but your C++ would actually build an SQL query and issue it to the database (Codesys doesn't need to know why or how this is happening).
I hope at least one paragraph is helpful in some way.
When I develop a loadable kernel module (LKM) should I use C?
Is it possible to develop a loadable kernel module (LKM) on Linux with language other than C for example C++?
It may be possible to an extent, but be warned (from http://www.tux.org/lkml/#s15-3):
Is it a good idea to write a new driver in C++?
The short answer is
no, because there isn't any support for C++ drivers in the kernel.
Why not add a C++ interface layer to the kernel to support C++ drivers?
The short answer is why bother, since there aren't any C++ drivers for
Linux.
I think the best idea is to consult existing resources (there are a few kernel driver books, including a free one online) which are all in C, get the basics figured out, then you can try and see if you can get c++ to work there.
But I very much doubt that will be easy. You don't even have access to the full C standard library in the kernel. Something to think about: it does not link to shared libraries, and the total executable image is usually 2-3 MB.
I'm pretty sure I saw a kernel configuration option somewhere allowing C++ in kernel modules, a while back (but cannot find it again).
I can see how certain templates would be very interesting to use in driver modules. Just for anecdotics: the OS X Mach kernel is partly written in C++.
In the end it comes down to object code, which is generated by the Assembler and linked together afterwards.
So yes it is possible, you find a debate about that here.
It depends on what you want to do with the LKM, do you want to use it for yourself and some experiments or is it going to become productive anywhere?
There is an operating system which is rewriting Linux Kernel in C++ it's called Boss-Mool and you can write drivers using C++. Here's the link : https://www.bosslinux.in/boss-mool
Well, the original question was for Linux, not OS X or Windows or whatever.
There is absolutely no way to write a Linux kernel mode driver in C++ !
That's because you would need to link with libstdc++ which will not link with your module. libstdc++ is not available for kernel mode, as simple as that !
I have a rather large MFC based program. I have been tasked to get it running on Linux. I have explained that this will require a re-write of the program either into straight C++ with STL (more work), or into Qt/C++ (less work). I am now told that I need to write wrappers to get every MFC class working in Linux and use preprocessor directives to only compile what is needed in either Linux or Windows. I explained that we are having a communication disconnect and that I believed this to be more work than rewriting the entire project from scratch (which I would not have to do to convert to Qt).
Any good arguments out there to help explain this issue? Am I wrong?
If you don't want a full rewrite, you could try compiling against Winelib. Most things should just work and then since you have the source, you can work around the parts that don't.
The obvious solution is to run the code unchanged and un-recompiled on WINE.
A simple (kludgy) solution is to run an entire Windows VM on the Linux system, and deploy the application as a virtual hard-drive, but that will require a Windows license and is little different than simply connecting a Windows system to a Linux network.
If you must re-write, wxWidgets would be more familiar to an MFC developer than Qt perhaps.
Here is an article on porting MFC apps to Linux that considers the use GTK+, Qt and wxWidgets. It also discusses why you should consider and try WINE before any of those options. The author talks about future articles on the subject, but appears to have written nothing further since 2004.
The sources for MFC and ATL total to over 500000 lines of code, and most of the functionality of this code is actually provided by the Windows API itself. How many lines of code can you write in a day? The scale of what you are being asked to do is simply impractical, even if you're only implementing a small subset of MFC.
i have code written in c++. its a console app that takes an input and displays output. Now i can just give my a.out to someone without giving them the code and it should work on another unix system. but what if they have windows environment. I would like to learn how to make dll for them so they can run that.
also, if they were going to use it as part of another program I guess i would need to make an api or function for them. But i am not sure how that works with dlls as i have never done this before.
Now i can just give my a.out to
someone without giving them the code
and it should work on another unix
system.
No it shouldn't and almost certainly won't. Executables are not typically portable across even closely related operating systems, and most flavours of Unix are not too closely related. You need to compile your application for the specific (and "unix" is not specific enough) target OSs you are interested in.
You need to recompile your application for Windows, either on a Windows machine or by using a crosscompiler. This requires that all routines which you use need to be available under Windows, too.
Either you wrote your application from scratch using portable libraries (read: no unix/posix system calls), or you will get problems porting your code to run under Windows. Cygwin can probably help, check it out.
If you say its a pure console app, I assume you're using std::cout and std::cin or other stuff from the C++ standard library. These are indeed universally available on every C++ implementation.
I'm trying to get information like OS version, hard disk space, disk space available, and installed RAM on a Linux system in C++. I know I can use system() to run different Linux commands and capture their output (which is what I'm currently doing) but I was wondering if there's a better way? Is there something in the C++ standard library that I can use to get information from the operating system?
If you are using *nix commands via system.
Then do man scroll to the bottom of the man page and it will usually show you what relevant C system calls are related.
Example: man uname:
SEE ALSO
uname(2), getdomainname(2), gethostname(2)
Explanation of numbers:
(1): User UNIX Command
(2): Unix and C system calls
(3): C Library routines
(4): Special file names
(5): File formats
(6):
(7):
(8): System admin commands
So if you are using system("uname"). From the man page you can see that there is also a uname C system call (uname(2)). So you can now do a 'man 2 uname' to get information about how to use the C system call uname.
There is nothing in the C++ Standard library for these purposes. The library you could use is libhal, which abstracts the view of programs to the hardware, collecting various informations from /proc, /sys and others. HAL, scroll down, there seems to be an unofficial C++ binding available too (haven't tested it though, while libhal works also fine for C++ programs). Use the command lshal to display all device informations available to HAL.
If you don't want to use HAL as litb suggests, you can read things straight out of the /proc filesystem, provided it's there on your system. This isn't the most platform-independent way of doing things, and in many cases you'll need to do a little parsing to pick apart the files.
I think HAL abstracts a lot of these details for you, but just know that you can read it straight from /proc if using a library isn't an option.
System information is by definition not portable, so there is no standard solution. Your best bet is using a library that does most of the work for you. One such cross platform library (unlike hal, which is currently Linux specific) is SIGAR API, which is open source BTW. I've used it in a C++ project without much trouble (the installation is a bit non-standard but can be figured out easily)