Hello!

In some device there is an embedded computer (MOXA IA240LX on Linux), which collects data from modules, sensors, etc. The computer acts as a master (on one RS port) on the RS485 bus and at the same time a slave (the second RS port). Accordingly, it is necessary to transfer the data received by the master to the slave program for the request.

Since I am not strong in programming, I implemented this exchange using read / write to a .txt file, but very rarely skip data that does not correspond to reality.

I started looking for the right solutions and came across an article "Linux interprocess communication" ( https://habrahabr.ru/post/122108/ ), which indicates the implementation of such an exchange using mutex.

Is this the right solution? Or is it easier and more efficient? As I said, in programming is not strong. Thank!

Closed due to the fact that it is necessary to reformulate the question so that it was possible to give an objectively correct answer by the participants aleksandr barakin , user194374, enzo , Streletz , αλΡχολυτ Jul 2 '16 at 20:08 .

The question gives rise to endless debates and discussions based not on knowledge, but on opinions. To get an answer, rephrase your question so that it can be given an unambiguously correct answer, or delete the question altogether. If the question can be reformulated according to the rules set out in the certificate , edit it .

  • If you creatively rework the named channels for your case, that's fine. The meaning of having two channels is not entirely clear, RS485 is quite a full duplex. Write and read two different files. Each side writes only to its own file, and only reads someone else's - in this case, some super tricks are not particularly needed. Except for the need to keep track of file sizes. For example, once a minute, create a new one and delete all old files once every half an hour. - MolbOrg pm
  • but better still, it’s okay to use RS485 arduinschiki perhaps the normal search direction arduino-info.wikispaces.com/SoftwareSerialRS485Example - MolbOrg
  • Two channels - on the first device acts as a master, on the second one (it is impossible to be both on the same port and that). But the question is still not that. I just wanted to know how to remove the probability of an error when reading from a file. - AlxZahar
  • Write to two different files, each side takes care of itself in terms of recording and there is no collision, this is the main possible source of error. Please also enter the wall check box, for each validation, to be sure that the channel has nothing to do with, the same CRC32. sourceforge.net/projects/crccalculator/files/CRC And the master slave is just like a modbus abstraction, not the physical capabilities of RS485. But really, I almost forgot everything. - MolbOrg

1 answer 1

I do not understand the situation ... Is there a TWO processes on ONE computer that should exchange information? And what side is the serial port here ?! Or, after all there are TWO companies that are connected via a serial bus?

If your processes are executed (physically) on one computer, then using the COM port is meaningless. What for ?!!! You absolutely started to dig in the direction of "linux interprocess communication", but you absolutely do not need to use mutexes - too low and a primitive type of interaction between processes.

I think that for you, if not a very experienced programmer, it is clearer (and therefore easier) to use the so-called. "named pipes".

1) Create a named pipe

mkfifo pipe1 

2) In the wizard, open this channel to record

 open("pipe1", O_WRONLY) 

3) In the slave - open for reading: open ("pipe1", O_RDONLY)

4) After that, in the master use the usual write (...);?, In the slave - read (...);

5) All worries about error checking, synchronization, etc. takes over the OS.

As a WORKING EXAMPLE, here are the listings of two tiny programmers, one of which writes a line to the channel, and the other reads it.

So, the first action is creating a channel:

 mkfifo exampl 

The second step is to write and compile a reader from the channel:

 #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { FILE *ff; char line[256]; ff = fopen("exampl", "ro"); if (ff) { fgets(line, 255, ff); line[strlen(line)-1] = '\0'; printf("ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°Π»ΠΈ ΠΈΠ· ΠΊΠ°Π½Π°Π»Π°: '%s'\n", line); fclose(ff); } else perror("Ошибка открытия FIFO:"); } 

The third step is to write and compile a channel recording program:

 #include <stdio.h> int main(int argc, char *argv[]) { FILE *ff; ff = fopen("exampl", "wo"); if (ff) { fprintf(ff, "ПишСм Π² ΠΊΠ°Π½Π°Π»\n"); fclose(ff); } else perror("Ошибка открытия FIFO:"); } 

Last step - we test the received programs:

 $ ./main_r & [1] 6096 $ ./main_w ΠŸΡ€ΠΎΡ‡ΠΈΡ‚Π°Π»ΠΈ ΠΈΠ· ΠΊΠ°Π½Π°Π»Π°: 'ПишСм Π² ΠΊΠ°Π½Π°Π»' [1]+ Π“ΠΎΡ‚ΠΎΠ²ΠΎ ./main_r 

Since I used only one terminal, I started the reader in the background (&). She hung on waiting for input. Launched a program to write to the channel. She wrote down the line and ended. The reading program took a line from the channel and ended.

What could be easier ?!

  • With named channels it is not so simple - when using write / read, you should take into account that the data is represented by a stream and you need to split up the messages yourself. In this regard, it is more convenient to unix domain sockets (not to be confused with ordinary sockets). - Vladimir Gamalyan
  • you need to split up messages yourself - you can also split them up into messages just like in all other symbolic streams - with the help of the line end symbol '\ n'. If you need to use fixed-length (binary) records, you can use the message mechanism - man 3 msgget (in the SystenV variant), man 3 mq_receive (in the POSIX variant). It will be much easier and clearer than organizing the exchange through sockets. Still, the projects - this is the BASIC level. About channels and queues are already services ... - Sergey
  • Of course, you can do all this with your hands, but why when you can write a message to the unix domain socket and read another. - Vladimir Gamalyan
  • you can write a message to the unix domain socket in one command - something I have little idea what kind of TEAM is that writes to the socket ... The program (IMHO) uses operators like ... And to work with sockets they should be much more than one. I propose TS itself to decide what is easier. Here is my version: - Sergey
  • On the command line, execute ONE command: mkfifo exampl I created the named pipe. - Sergey