390 lines
13 KiB
ReStructuredText
390 lines
13 KiB
ReStructuredText
Additional Linux Details
|
|
========================
|
|
The tutorial gives most information required for getting started on a Linux
|
|
machine. Some additional information is given here.
|
|
|
|
|
|
Detailed dependency installation info
|
|
-------------------------------------
|
|
You need to have cmake version at least 3.14 installed. It is available in
|
|
Ubuntu 19.04 and later.
|
|
|
|
To install on Ubuntu 16.04 or 18.04, follow the instructions here:
|
|
https://www.kitware.com/ubuntu-cmake-repository-now-available/
|
|
|
|
It is also possible to install it via snap::
|
|
|
|
sudo snap install cmake --classic
|
|
|
|
When using it, you might need to replace ``cmake`` with ``snap run cmake``.
|
|
If uninstalling the default ``cmake``, the snap-installed version should be
|
|
used by default after reboot.
|
|
|
|
Optional dependencies (for development and documentation of the p-net stack)::
|
|
|
|
sudo apt install -y \
|
|
clang-tools \
|
|
clang-format-10 \
|
|
doxygen \
|
|
graphviz
|
|
|
|
|
|
Run tests and generate documentation
|
|
------------------------------------
|
|
Run tests (if you told cmake to configure it)::
|
|
|
|
cmake --build build --target check
|
|
|
|
Run a single test file::
|
|
|
|
build/pf_test --gtest_filter=CmrpcTest.CmrpcConnectReleaseTest
|
|
|
|
Create Doxygen documentation::
|
|
|
|
cmake --build build --target docs
|
|
|
|
The Doxygen documentation ends up in ``build/html/index.html``
|
|
|
|
See the "Writing documentation" page if you would like to install
|
|
the toolchain to build the entire Sphinx documentation.
|
|
|
|
The clang static analyzer can also be used if installed. Create a new
|
|
build directory by running::
|
|
|
|
scan-build cmake -B build.scan-build -S p-net
|
|
scan-build cmake --build build
|
|
|
|
|
|
Setting Linux ephemeral port range
|
|
----------------------------------
|
|
This is the range of random source ports used when sending UDP messages.
|
|
Profinet requires that the UDP source port should be >= 0xC000, which is 49152
|
|
in decimal numbers.
|
|
|
|
To change the ephemeral port range::
|
|
|
|
echo "49152 60999" > /proc/sys/net/ipv4/ip_local_port_range
|
|
|
|
This should typically be done at system start up.
|
|
|
|
|
|
File size and memory usage on Linux
|
|
-----------------------------------
|
|
The resulting file size of the sample application binary is heavily dependent
|
|
on the compile time options, for example whether to include debug information.
|
|
In this example we use::
|
|
|
|
BUILD_SHARED_LIBS ON
|
|
CMAKE_BUILD_TYPE Release
|
|
LOG_LEVEL Warning
|
|
PNET_MAX_AR 2
|
|
PNET_MAX_SLOTS 5
|
|
PNET_MAX_SUBSLOTS 3
|
|
|
|
To get an estimate of the binary size, partially link it (use release, without
|
|
standard libraries)::
|
|
|
|
p-net/build$ make all
|
|
p-net/build$ /usr/bin/cc -O3 -DNDEBUG CMakeFiles/pn_dev.dir/samples/pn_dev/sampleapp_common.o CMakeFiles/pn_dev.dir/src/ports/linux/sampleapp_main.o -o pn_dev libprofinet.a -nostdlib -r
|
|
|
|
Resulting size::
|
|
|
|
p-net/build$ size pn_dev
|
|
text data bss dec hex filename
|
|
244481 72 8 244561 3bb51 pn_dev
|
|
|
|
See https://linux.die.net/man/1/size for information on how to use the command.
|
|
Also the rt-kernel page in this documentation has some description on how to
|
|
interpret the output.
|
|
|
|
The size of the p-net stack can be estimated from the size of libprofinet,
|
|
built with the options given above::
|
|
|
|
p-net/build$ size libprofinet.so
|
|
text data bss dec hex filename
|
|
230888 3304 8 234200 392d8 libprofinet.so
|
|
|
|
An estimate of the p-net RAM usage can be made from the size of the ``pnet_t`` struct.
|
|
The sample application has a command line option to show this value, for the used
|
|
compile time options (for example the maximum number of modules allowed).
|
|
|
|
|
|
Debug intermittent segmentation faults during tests on Linux
|
|
------------------------------------------------------------
|
|
Enable core dumps::
|
|
|
|
ulimit -c unlimited
|
|
|
|
Run a test case until the problem occurs (in the build directory)::
|
|
|
|
while ./pf_test --gtest_filter=DiagTest.DiagRunTest; do :; done
|
|
|
|
Study the resulting core::
|
|
|
|
gdb pf_test core
|
|
|
|
|
|
SNMP (Conformance class B)
|
|
--------------------------
|
|
Conformance class B requires SNMP support. Linux uses net-snmp as agent,
|
|
see http://www.net-snmp.org/. The name of the SNMP agent binary is ``snmpd``.
|
|
|
|
P-Net for Linux implements a Net-SNMP subagent that handles the Profinet
|
|
mandatory MIB:s. Also
|
|
see :ref:`network-topology-detection` for information regarding SNMP.
|
|
|
|
Enable SNMP by setting ``PNET_OPTION_SNMP`` to ``ON`` in the p-net compilation
|
|
options. Net-SNMP also needs to
|
|
be installed. On Ubuntu you can install the required packages using::
|
|
|
|
sudo apt install -y snmpd libsnmp-dev
|
|
|
|
To show the installed version of ``snmpd``, use::
|
|
|
|
snmpd -v
|
|
|
|
|
|
Change snmpd command line arguments
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
The p-net SNMP subagent will handle the system objects, so the default
|
|
SNMP "system" module should be disabled by adding the snmpd argument
|
|
``-I -system_mib``. Otherwise the subagent will complain about
|
|
"registering pdu failed" at startup. If you use systemd init system (for
|
|
example on Ubuntu Linux) you should change
|
|
``/lib/systemd/system/snmpd.service`` to read::
|
|
|
|
[Unit]
|
|
Description=Simple Network Management Protocol (SNMP) Daemon.
|
|
After=network.target
|
|
ConditionPathExists=/etc/snmp/snmpd.conf
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStartPre=/bin/mkdir -p /var/run/agentx
|
|
ExecStart=/usr/sbin/snmpd -LOw -u Debian-snmp -g Debian-snmp -I -system_mib,smux,mteTrigger,mteTriggerConf -f -p /run/snmpd.pid
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
To see the status of the service::
|
|
|
|
systemctl status snmpd.service
|
|
journalctl -u snmpd.service -f
|
|
|
|
To restart the service after modification::
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl restart snmpd.service
|
|
|
|
The command line arguments ``-u`` and ``-g`` are for the user id and group id
|
|
of the snmpd process will use after its initial startup.
|
|
They are not necessary to use snmpd.
|
|
However snmpd must be started with permissions to open relevant sockets,
|
|
typically root permissions.
|
|
|
|
If you use "system V init" instead of systemd, then snmpd is typically started
|
|
by a script file named ``/etc/init.d/snmpd``. Change the snmpd command line
|
|
arguments in the file, typically via ``SNMPDOPTS``. Stop and start the
|
|
service with::
|
|
|
|
sudo /etc/init.d/snmpd stop
|
|
sudo /etc/init.d/snmpd start
|
|
|
|
|
|
Configuration file for snmpd
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
The file ``snmpd.conf`` controls access to the snmp agent. It should be
|
|
set to listen on all interfaces and allow read-write access to the
|
|
Profinet MIB:s. On Ubuntu Linux you should change
|
|
``/etc/snmp/snmpd.conf`` to read::
|
|
|
|
master agentx
|
|
agentaddress udp:161
|
|
view systemonly included .1.3.6.1.2.1.1
|
|
view systemonly included .1.3.6.1.2.1.2.2
|
|
view systemonly included .1.0.8802.1.1.2
|
|
rocommunity public default -V systemonly
|
|
rwcommunity private default -V systemonly
|
|
|
|
If your Linux distribution does give a long description for ``ifDesc`` you can
|
|
override it by adding a line to the ``snmpd.conf`` file. Adapt the interface
|
|
index (last digit in OID) and the interface name::
|
|
|
|
override 1.3.6.1.2.1.2.2.1.2.3 octet_str "enp0s31f6"
|
|
|
|
See :ref:`network-topology-detection` for more details on SNMP and how to
|
|
verify the SNMP communication to the p-net stack.
|
|
|
|
|
|
Start your application after snmpd
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
You probably would like your application to wait for the ``snmpd`` application to
|
|
be up and running. If you use systemd as init system, modify this line in
|
|
the ``[Unit]`` part of your ``.service`` file::
|
|
|
|
After=network.target snmpd.service
|
|
|
|
You might also need to add this to the ``[Service]`` part of your
|
|
``.service`` file::
|
|
|
|
ExecStartPre=/usr/bin/sleep 0.3
|
|
|
|
If the p-net application fails to connect to snmpd, a message "Warning: Failed
|
|
to connect to the agentx master agent" will be written to the p-net sample
|
|
app log file every 15 seconds.
|
|
|
|
|
|
Debugging snmpd settings
|
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
The command line argument ``-LOw`` for snmpd sets the snmpd logging to
|
|
standard out with log level "warning".
|
|
To change to log level debug, use ``-LOd``. You should also use the ``-D`` flag
|
|
to select which debug messages you are interested in. Use the ``-Dagentx``
|
|
command line argument to debug the agentx communication between the snmpd and
|
|
the subagent in the p-net stack. A log example when asked for a single OID::
|
|
|
|
Connection from UDP: [192.168.0.30]:43833->[192.168.0.50]:161
|
|
agentx/master: agentx master handler starting, mode = 0xa0
|
|
agentx/master: request for variable (iso.3.6.1.2.1.1.4.0)
|
|
agentx/master: sending pdu (req=0x8,trans=0x7,sess=0x6)
|
|
agentx_build: packet built okay
|
|
agentx/master: got response errstat=0, (req=0x8,trans=0x7,sess=0x6)
|
|
agentx/master: agentx_got_response() beginning...
|
|
agentx/master: handle_agentx_response: processing: iso.3.6.1.2.1.1.4.0
|
|
agentx/master: handle_agentx_response() finishing...
|
|
|
|
Note that there might be a warning message "pcilib: Cannot open /proc/bus/pci"
|
|
in the snmpd log if you specify that it should use all interfaces.
|
|
That is because it will look also for (possibly non-existing) PCI interfaces.
|
|
|
|
To trouble-shoot snmpd issues, verify that no other snmpd instances are running::
|
|
|
|
ps -ef | grep snmpd
|
|
|
|
and verify that no other process is using UDP port 161::
|
|
|
|
sudo lsof -i udp -n -P
|
|
|
|
|
|
snmpd in a Yocto build
|
|
----------------------
|
|
In an embedded Linux Yocto build, you would include the ``snmpd`` daemon by
|
|
using the ``net-snmp`` recipe.
|
|
|
|
|
|
Persistent logs
|
|
---------------
|
|
To make the journalctl logs persistent between restarts::
|
|
|
|
sudo mkdir -p /var/log/journal
|
|
sudo systemd-tmpfiles --create --prefix /var/log/journal
|
|
|
|
Remove all contents of the journalctl logs::
|
|
|
|
sudo journalctl --rotate
|
|
sudo journalctl --vacuum-time=1s
|
|
|
|
The configurations for journalctl are located in ``/etc/systemd/journald.conf``.
|
|
If you do experiments with frequent reboots, it might be useful to change some
|
|
values::
|
|
|
|
SyncIntervalSec=10s
|
|
MaxRetentionSec=4h
|
|
|
|
|
|
|
|
Boot time optimization
|
|
----------------------
|
|
To improve the startup time of your Linux device, it is useful to study what
|
|
is delaying the start. If you use the "systemd" init system, you can use these
|
|
commands to analyze the startup::
|
|
|
|
systemd-analyze
|
|
systemd-analyze blame
|
|
systemd-analyze critical-chain pnet-sampleapp.service
|
|
|
|
To decrease the startup time, disable services you don't use. On a Raspberry Pi
|
|
it might be for example::
|
|
|
|
sudo systemctl disable triggerhappy triggerhappy.socket apt-daily.timer apt-daily-upgrade.timer logrotate.timer rpi-display-backlight lightdm bluetooth hciuart rsync cups cups-browsed alsa-state avahi-daemon
|
|
|
|
Other applications that you might disable for experimentation::
|
|
|
|
sudo systemctl disable snapd snapd.socket wpa_supplicant systemd-timesyncd dhcpcd
|
|
|
|
|
|
Debug the sample application on a Linux Laptop
|
|
----------------------------------------------
|
|
It can be convenient to be able to run the sample application and the p-net
|
|
stack in a debugger tool. It is easy using gdb and the Visual Studio Code
|
|
editor.
|
|
|
|
First make sure you can run the application from a terminal on your Linux
|
|
laptop.
|
|
|
|
Next step is to be able to run it from the terminal within Visual Studio Code.
|
|
In case of compilation error messages, you can click on the code line given
|
|
in the terminal (within Visual Studio Code) and the corresponding file will
|
|
be opened. Hold the CTRL key while clicking on the line.
|
|
|
|
To use debug features while running (for example breakpoints) you need to adapt
|
|
the settings file for Visual Studio Code. Click the "Run and Debug" icon
|
|
in the left side tool bar. Then click "Create a launch.json file". In the
|
|
"Select environment", use "C++ (GDB/LLDB)".
|
|
|
|
Modify the ``launch.json`` file to point at the correct executable, working
|
|
directory and to use correct command line arguments.
|
|
|
|
If you need to run the application with root permissions, you need to add a path in the
|
|
``"miDebuggerPath"`` field. It should point to a text file typically named
|
|
``gdb``, with this content::
|
|
|
|
pkexec /usr/bin/gdb "$@"
|
|
|
|
Put the ``gdb`` file for example in the ``.vscode`` subdirectory within
|
|
the ``p-net`` directory. Set the executable flag::
|
|
|
|
chmod +x gdb
|
|
|
|
An example of a ``launch.json`` file::
|
|
|
|
{
|
|
"version": "0.2.0",
|
|
"configurations": [
|
|
|
|
{
|
|
"name": "(gdb) Launch",
|
|
"type": "cppdbg",
|
|
"request": "launch",
|
|
"program": "${workspaceFolder}/build/pn_dev",
|
|
"args": ["-vv", "-i", "enp0s31f6"],
|
|
"stopAtEntry": false,
|
|
"cwd": "${workspaceFolder}/build/",
|
|
"environment": [],
|
|
"externalConsole": false,
|
|
"MIMode": "gdb",
|
|
"miDebuggerPath": "${workspaceFolder}/.vscode/gdb",
|
|
"setupCommands": [
|
|
{
|
|
"description": "Enable pretty-printing for gdb",
|
|
"text": "-enable-pretty-printing",
|
|
"ignoreFailures": true
|
|
}
|
|
]
|
|
}
|
|
|
|
]
|
|
}
|
|
|
|
The given ``"args"`` command line arguments in the example is for
|
|
increasing the verbosity level and to set the Ethernet interface name.
|
|
Adapt those and also paths to your particular setup.
|
|
|
|
Use the ``CMAKE_BUILD_TYPE`` setting as ``Debug`` when running the executable
|
|
via the debugger.
|
|
|
|
Start the debugging by clicking on the small green "Run" icon on the
|
|
"Run and Debug" page. It will stop at any breakpoint. Set a breakpoint in
|
|
any file by clicking on a line to the left of the line number.
|