📜 ⬆️ ⬇️

Look up from the bottom or Ubuntu Server for the developer of electronics. Part 2

We continue to develop the theme of using a computer with a ubuntu server as a device for connecting the world of microcontrollers with the world of personal computers.

Link to part 1
image
Let me remind you that the article describes the practice of using the described equipment and does not set a goal to cover all the depths and possibilities of modern equipment. This is one of the solutions to the task.

In this section, I will show you how to pass the following points:

Static IP + DHCP server
In the local network at the moment there are only two devices. The server itself and the control machine. Based on this simplicity, let's configure the Ubuntu server.
Static IP
Reference Information
1. To find out the logical name of the network interface:
')
sudo lshw -C network 
and look for the line
  logical name: enp3s0 

The option of using the ifconfig function (as an analogue of ipconfig in windows) can sometimes only give loop 127.0.0.1. The name of the interface depends on the hardware. On two different machines I installed ubuntu from the same flash drive and there were different names for network interfaces. enp3s0 is a classification by bus and device number, as I understand it. Happen still from such series eth0 and such ens35. Do not be scared.

2. Change network configuration file

 sudo nano /etc/network/interfaces 
(nano - this little text editor)
It should be like this:

  # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # My local network. allow-hotplug enp3s0 iface enp3s0 inet static address 172.16.55.1 netmask 255.255.255.0 gateway 172.16.55.1 

Press cntrl-x - to exit the editor
Press y - to save changes.

3. Restart the network service:
 service networking restart 


DHCP server
Reference Information
1. We edit files for work of the DHCP server
 sudo nano /etc/default/isc-dhcp-server 
find the line
 INTERFACES="" 
Is the interface name for the DHCP server. In our case it should be like this:

 INTERFACES="enp3s0" 

In file
 sudo nano /etc/dhcp/dhcpd.conf 
need to add
 subnet 172.16.55.0 netmask 255.255.255.0{ range 172.16.55.2 172.16.55.100; } 
Within this subnet, the DHCP server will issue addresses in the range from 2 to 100.

2. If you use the gethostbyname () function, then in the file
 sudo nano /etc/hosts 
should be spelled pc name and ip. Perhaps there is a more convenient way to get your own IP, but I did not succumb to it.
 127.0.0.1 localhost 172.16.55.1 ubuntu 

The file / etc / hostname stores the name of the pc (ubuntu). You can look through
 sudo cat /etc/hostname 
and a million more ways.

3. Restart the network service:
 service networking restart 

Ssh access
In theory, having connected a desktop computer now, we will get an IP for it and we will be able to access via SSH. For access from Windows, I used the PuTTY utility. In the same place, in the PuTTY program files, there is a utility for transmitting data over the network.
Here is the composition of the batch file for transferring files from Ubuntu to Windows.
 d:\"Program Files"\PuTTY\pscp.exe ubuntu@172.16.55.1:/home/ubuntu/tool/* "F:/WORK/SERVER/tool/" 

And for uploading to the server
 d:\"Program Files"\PuTTY\pscp.exe "F:/WORK/SERVER/tool/*" ubuntu@172.16.55.1:/home/ubuntu/tool/ 


Put the driver from FTDI
FTDI drivers are shipped in a compressed form. The package contains the drivers themselves, libraries, usage examples and the README.pdf file that was most interesting. From the D3XX Programmers Guide file it is never clear how to use a driver for Linux. I even had to write to those who support FTDI, since they are responsible in a timely and responsible manner. It would be possible not to write if I immediately opened this archive. But the links that they sent, examples of wiring and circuitry turned out to be useful.
As shown above, using the pscp utility from the PuTTY kit, copy the driver to the server. I had d3xx-linux-i686-0.5.0.tar.bz2. Go to this folder on the server and do
 tar -xvf d3xx-linux-i686-0.5.0.tar.bz2 

Further, according to the instructions FTDI execute:
 cd linux-i686 sudo rm -f /usr/lib/libftd3xx.so sudo cp -f libftd3xx.so /usr/lib sudo cp -f libftd3xx.so.0.5.0 /usr/lib sudo cp -f 51-ftd3xx.rules /etc/udev/rules.d sudo udevadm control --reload-rules 


Compile the program
I wrote the program in codeBlocks and it, with the exception of some points, including because of FTDI, is compatible with Windows. It stopped compiling for Windows when I put the h file from the linux driver D3XX there (there were no problems with the D2XX and FT232RL chip).
Now makefile. Programmers already know why it is needed, just point out the features:
STATLIB = libftd3xx.a - specify the name of the library for Linux
CFLAGS = $ (DEPENDENCIES) -Wall -Wextra -std = c ++ 11 - enable c ++ 11
sample makefile for one main.cpp project file
 CC=g++ UNAME := $(shell uname) ifeq ($(UNAME), Darwin) DEPENDENCIES := -lpthread -ldl -lobjc -framework IOKit -framework CoreFoundation else DEPENDENCIES := -lpthread -ldl -lrt endif CFLAGS=$(DEPENDENCIES) -Wall -Wextra -std=c++11 STATLIB=libftd3xx.a APP = prgr all: $(APP) $(APP): main.o $(CC) -o $(APP) main.o $(STATLIB) $(CFLAGS) main.o: main.cpp $(CC) -c -o main.o main.cpp $(CFLAGS) clean: rm -f *.o ; rm $(APP) 

Thus, in the project folder are the main.c files ftd3xx.h makefile libftd3xx.a and other project files. And to compile the project, now you need to go into this folder and make
 make 


daemon
The role of daemons in Linux is similar to the role of services in Windows. These are programs that live in the background and do all peripheral work. It all starts with systemd - the program that starts first, has a PID = 1, respectively, and runs all other background tasks through scripts. Having picked it up in Ubuntu, I was surprised at how much of everything inside is built on scripts. You have already seen how static IP changes, programs are configured, by simply correcting files in a text editor.

By completing
 ps -el 
You will see a list of running programs with their PID. PID is a mandatory identifier of a running program, which the OS monitors for this program. In an extreme situation, you can bang the program on this PID from the terminal - write kill and PID (it can be useful for debugging).

So, when starting the daemon, a script is executed, which indicates when and how the program should be started, how to stop or restart it. In order for the daemon to work normally, the program, upon launch, must save its PID to the file, the path to which is specified in the script, and switch to another stream (to the background mode).

The manual on the demon brought me into sadness and longing. Strongly simplifying the daemon, I turned it into a utility to run any program. But the mandatory part has not changed. In addition, he keeps a log to check if anything happens.

daemon code
 void SetPidFile(char* Filename) { FILE* f; f = fopen(Filename, "w+"); if (f) { fprintf(f, "%u", getpid()); fclose(f); } } int main( int argc, char** argv ) { char toolfile[32]; char folder[32]; intptr_t ret; FILE* logfile; if( argc!=3 ) { printf( "Write address of the program and name: /home/ubuntu/tool/ tool\n"); return -1; } pid_t pid, sid; pid = fork(); if (pid < 0) { sleep(1); return -1; } //We got a good pid, Close the Parent Process if (pid > 0) { return 0; } //Create a new Signature Id for our child sid = setsid(); if (sid < 0) { return -1; } //Change File Mask umask(0); //Save PID memcpy( toolfile, argv[0], strlen(argv[0]) ); memcpy( toolfile + strlen(argv[0]), ".log", 4 ); memset( toolfile + strlen(argv[0]) + 4, 0, 1 ); printf( "Daemon:: log to:%s\n", toolfile ); logfile = fopen( toolfile, "w" ); fprintf( logfile, "Daemon:: started with 0=%s 1=%s 2=%s\n", argv[0], argv[1], argv[2] ); memset( toolfile, 0, 32 ); memcpy( toolfile, argv[0], strlen(argv[0]) ); memcpy( toolfile + strlen(argv[0]), ".pid", 4 ); memset( toolfile + strlen(argv[0]) + 4, 0, 1 ); SetPidFile( toolfile ); fprintf( logfile, "Daemon:: PID=%u saved in the %s\n", getpid(), toolfile ); memset( folder, 0, 32 ); memcpy( folder, argv[1], strlen(argv[1]) ); fflush ( logfile ); memset( toolfile, 0, 32 ); memcpy( toolfile, folder, strlen(argv[1]) ); memset( toolfile + strlen(argv[1]), '/', 1 ); memcpy( toolfile + strlen(argv[1]) + 1, argv[2], strlen(argv[2]) ); //Change Directory //If we cant find the directory we exit with failure. if ((chdir(folder)) < 0) { fprintf( logfile, "Daemon:: Program folder was not found:%s\n", folder ); fclose( logfile ); return -1; } //Close Standard File Descriptors close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); fprintf( logfile, "Daemon:: Program started\n" ); fflush ( logfile ); ret = execl( toolfile, folder, NULL ); if( ret==-1 ) { fprintf( logfile, "Daemon:: execl error: %s. File=%s Folder=%s\n", strerror(errno), toolfile, folder ); fclose( logfile ); return -1; } fprintf( logfile, "Daemon:: closed\n" ); fclose( logfile ); return 0; } 

Compile the daemon.

At this point in our working directory, say / home / ubuntu / daemon /, we have:

daemon - daemon program
prgr - program
prgr.strt - a script that you need to run before starting the program (if necessary)
prgr.stop - the script that you need to run to stop the program (if necessary)

You need to allow programs to work:

 sudo chmod 755 ./tool sudo chmod 755 ./daemon 

Now I need a script for systemd
Do
 sudo nano /etc/systemd/system/mydaemon.service 
and write our script there.

mydaemon.service
 [Unit] Description=my service After=network.target After=isc-dhcp-server.service [Service] Type=forking PIDFile=/home/ubuntu/daemon/daemon.pid ExecStartPre=/bin/sh /home/ubuntu/daemon/prgr.strt ExecStart=/home/ubuntu/daemon/daemon /home/ubuntu/daemon/prgr prgr ExecStop=/bin/sh /home/ubuntu/daemon/prgr.stop Restart=always TimeoutSec=5 [Install] WantedBy=multi-user.target 

In the script briefly:
Description - a short title description.
After - what is required to run
Type = forking - systemd assumes that the service is started once and the process forks with the completion of the parent process.
PIDFile - file with the program PID from the daemon
ExecStartPre - before launching the program
ExecStart - program with parameters
ExecStop - how to stop
WantedBy - the level at which to run

Now you can try to run everything.
We write
 systemctl daemon-reload systemctl status mydaemon 

If everything is without errors, then run:
 systemctl start mydaemon 

After that, see the demon log, everything should go.
For autoload to work
 systemctl enable mydaemon 


Friends, I look forward to your interesting comments and valuable tips. If you lied to where you are, do not get angry, just indicate what can be done better. I hope, there will be 3 part about a big script, automatic installation ... maybe something else.

Source: https://habr.com/ru/post/335042/


All Articles