From 959f53cd99c0a2dc83c0419edf1244aebdfe0043 Mon Sep 17 00:00:00 2001 From: Luca Toniolo <10792599+grandixximo@users.noreply.github.com> Date: Mon, 14 Sep 2026 08:04:47 +0800 Subject: [PATCH] mesa_modbus: remove deprecated framework, superseded by hm2_modbus Per the developer meeting decision, remove the mesa_modbus framework (modcompile + mesa_modbus.c.tmpl driver template) from master entirely. It was deprecated in 46074f8c41 in favor of the hm2_modbus driver with mesambccc-compiled MBCCB files, and the 2.9 branch retains it, so existing configurations keep documentation and migration support there. Remove the modbus source directory with its samples and README, the mesa_modbus driver doc and modcompile man page, the build rules, debian packaging entries, docs pipeline entries, and fix the two cross-references that pointed at the removed pages. A migration note is added to the 2.10 section of updating-linuxcnc.adoc. --- .gitignore | 1 - debian/linuxcnc-uspace-dev.install | 2 - debian/linuxcnc.manpages.in | 1 - docs/po4a.cfg | 2 - docs/src/Master_Documentation.adoc | 2 - docs/src/Submakefile | 5 +- docs/src/drivers/mesa_modbus.adoc | 378 -------- .../getting-started/updating-linuxcnc.adoc | 8 + docs/src/hal/components.adoc | 1 - docs/src/index.tmpl | 1 - docs/src/man/man1/mesambccc.1.adoc | 2 - docs/src/man/man1/modcompile.1.adoc | 65 -- docs/src/man/man3/hm2_pktuart.3.adoc | 2 +- src/Makefile | 2 - .../drivers/mesa-hostmot2/modbus/README.adoc | 15 - .../drivers/mesa-hostmot2/modbus/analogue.mod | 27 - .../mesa-hostmot2/modbus/mesa_modbus.c.tmpl | 886 ------------------ .../modbus/mesa_modbus.mod.sample | 33 - .../mesa-hostmot2/modbus/modcompile.py | 126 --- .../mesa-hostmot2/modbus/relayboard.mod | 30 - src/hal/utils/Submakefile | 11 +- 21 files changed, 12 insertions(+), 1588 deletions(-) delete mode 100644 docs/src/drivers/mesa_modbus.adoc delete mode 100644 docs/src/man/man1/modcompile.1.adoc delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/README.adoc delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/analogue.mod delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.mod.sample delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/modcompile.py delete mode 100644 src/hal/drivers/mesa-hostmot2/modbus/relayboard.mod diff --git a/.gitignore b/.gitignore index 4e3ccbcb4c8..ae679ab6090 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ share/menus/CNC.menu share/desktop-directories/linuxcnc-cnc.directory share/desktop-directories/linuxcnc-ref.directory share/desktop-directories/linuxcnc-doc.directory -share/linuxcnc/mesa_modbus.c.tmpl src/modules.order /configs/*/emc.nml !/configs/common/emc.nml diff --git a/debian/linuxcnc-uspace-dev.install b/debian/linuxcnc-uspace-dev.install index 199dae9fcc0..f7e58d261ea 100644 --- a/debian/linuxcnc-uspace-dev.install +++ b/debian/linuxcnc-uspace-dev.install @@ -1,7 +1,5 @@ usr/bin/halcompile -usr/bin/modcompile usr/include/linuxcnc usr/lib/liblinuxcnc.a usr/lib/*.so usr/share/linuxcnc/Makefile.modinc -usr/share/linuxcnc/mesa_modbus.c.tmpl diff --git a/debian/linuxcnc.manpages.in b/debian/linuxcnc.manpages.in index 964814da5fa..1b59c6518c9 100644 --- a/debian/linuxcnc.manpages.in +++ b/debian/linuxcnc.manpages.in @@ -59,7 +59,6 @@ usr/share/man/man1/milltask.1 usr/share/man/man1/millturn.1 usr/share/man/man1/millturngui.1 usr/share/man/man1/mitsub_vfd.1 -usr/share/man/man1/modcompile.1 usr/share/man/man1/monitor-xhc-hb04.1 usr/share/man/man1/motion-logger.1 usr/share/man/man1/moveoff_gui.1 diff --git a/docs/po4a.cfg b/docs/po4a.cfg index 376bd8f3187..864e1e4e55a 100644 --- a/docs/po4a.cfg +++ b/docs/po4a.cfg @@ -64,7 +64,6 @@ [type: AsciiDoc_def] src/drivers/hostmot2.adoc $lang:build/adoc/$lang/drivers/hostmot2.adoc [type: AsciiDoc_def] src/drivers/hal_gpio.adoc $lang:build/adoc/$lang/drivers/hal_gpio.adoc [type: AsciiDoc_def] src/drivers/mb2hal.adoc $lang:build/adoc/$lang/drivers/mb2hal.adoc -[type: AsciiDoc_def] src/drivers/mesa_modbus.adoc $lang:build/adoc/$lang/drivers/mesa_modbus.adoc [type: AsciiDoc_def] src/drivers/mitsub-vfd.adoc $lang:build/adoc/$lang/drivers/mitsub-vfd.adoc [type: AsciiDoc_def] src/drivers/pico-ppmc.adoc $lang:build/adoc/$lang/drivers/pico-ppmc.adoc [type: AsciiDoc_def] src/drivers/pmx485.adoc $lang:build/adoc/$lang/drivers/pmx485.adoc @@ -200,7 +199,6 @@ [type: AsciiDoc_def] src/man/man1/milltask.1.adoc $lang:build/adoc/$lang/man/man1/milltask.1.adoc [type: AsciiDoc_def] src/man/man1/millturn.1.adoc $lang:build/adoc/$lang/man/man1/millturn.1.adoc [type: AsciiDoc_def] src/man/man1/mitsub_vfd.1.adoc $lang:build/adoc/$lang/man/man1/mitsub_vfd.1.adoc -[type: AsciiDoc_def] src/man/man1/modcompile.1.adoc $lang:build/adoc/$lang/man/man1/modcompile.1.adoc [type: AsciiDoc_def] src/man/man1/monitor-xhc-hb04.1.adoc $lang:build/adoc/$lang/man/man1/monitor-xhc-hb04.1.adoc [type: AsciiDoc_def] src/man/man1/motion-logger.1.adoc $lang:build/adoc/$lang/man/man1/motion-logger.1.adoc [type: AsciiDoc_def] src/man/man1/moveoff_gui.1.adoc $lang:build/adoc/$lang/man/man1/moveoff_gui.1.adoc diff --git a/docs/src/Master_Documentation.adoc b/docs/src/Master_Documentation.adoc index 185561cf8f3..b1c373e7d59 100644 --- a/docs/src/Master_Documentation.adoc +++ b/docs/src/Master_Documentation.adoc @@ -136,8 +136,6 @@ include::drivers/hostmot2.adoc[] include::drivers/mb2hal.adoc[] -include::drivers/mesa_modbus.adoc[] - include::drivers/mitsub-vfd.adoc[] diff --git a/docs/src/Submakefile b/docs/src/Submakefile index 8f991768d8c..775150a24df 100644 --- a/docs/src/Submakefile +++ b/docs/src/Submakefile @@ -168,7 +168,6 @@ DOC_SRCS_EN := \ drivers/hal_pi_gpio.adoc \ drivers/hostmot2.adoc \ drivers/mb2hal.adoc \ - drivers/mesa_modbus.adoc \ drivers/pico-ppmc.adoc \ drivers/pmx485.adoc \ drivers/shuttle.adoc \ @@ -354,8 +353,8 @@ postatus:: # (rather than scanning $(L)/ with $(wildcard) or assuming every English # source has a translation) gives two properties at once: the list does # not depend on po4a having already produced the files (no "build twice" -# fragility), and it does not include English-only sources like -# drivers/mesa_modbus.adoc that are absent from the translation pipeline. +# fragility), and it does not include English-only sources that are +# absent from the translation pipeline. TRANSLATED_DOC_SRCS := $(shell sed -nE 's|^\[type: AsciiDoc_def\] src/([^ ]+).*|\1|p' \ $(DOC_DIR)/po4a.cfg) $(foreach L,$(LANGUAGES),\ diff --git a/docs/src/drivers/mesa_modbus.adoc b/docs/src/drivers/mesa_modbus.adoc deleted file mode 100644 index 8e118b49883..00000000000 --- a/docs/src/drivers/mesa_modbus.adoc +++ /dev/null @@ -1,378 +0,0 @@ -:lang: en -:toc: - -[[cha:mesa_modbus]] - -= Mesa Modbus = - -WARNING: The Mesa Modbus framework (modcompile and mesa_modbus) is deprecated and will be removed in a future release. New configurations should use the link:../man/man9/hm2_modbus.9.html[hm2_modbus] driver with link:../man/man1/mesambccc.1.html[mesambccc]-compiled MBCCB files instead. - -A framework to create custom, realtime, modbus drivers using the Mesa -PktUART component. - -There are several existing ways to control Modbus devices with LinuxCNC, -and those should also be considered. -They include, but are not limited to: - -<> - -https://forum.linuxcnc.org/24-hal-components/38733-vfdmod-an-easy-vfd-control-over-modbus-rtu?start=0#162435[vfdmod] - -<> - -There are also several drivers for specific VFDs, for example - -<> - -<> - -<> - -hy-vfd - HuangYang VFD - -hy-gt-vfd - HuangYang GT VFD - -gs2-vfd - Automation Direct GS2 VFD - -vfdb-vfd - Delta VFD-B VFD - -wj200-vfd - Hitachi wj200 VFD - -For most applications (especially the "hy" (HuangYang) VFDs which do not -actually conform to true modbus) it is likely to be less work to use -these. - -Reasons to use this framework: - -1) It is realtime, commands and reads happen deterministically. This -does not mean that they are fast, but that they happen at the same rate -all of the time, independent of other activity on the PC. At 9600bps a -typical transaction takes 18 servo-thread cycles, and the channels are -serviced consecutively. At higher bit-rates things are better, but each -read or write will always take at least three cycles, per register. To -ameliorate this a little, writes to registers are only performed when -necessary. Reads happen in turn, taking as long as they take. - -2) It uses ports on the Mesa card. If you already have a Mesa card then -this means that no extra hardware is needed. A typical application would -be to re-purpose the smart-serial port on the 7i96 as a modbus port to -control a VFD. If you do not have a Mesa card then this is obviously no -advantage at all. - -== Quick Start == - -Install the linuxcnc-uspace-dev or linuxcnc-dev package (depending on the -LinuxCNC version installed). - -Create a new definition file similar to analogue.mod and relayboard.mod -(the annotated mesa_uart.mod.sample file should help here) - -Run the command: - ----- -./modcompile my_file.mod ----- - -and the "modcompile" script will compile and install the module. As -some realtime implementations of LinuxCNC realtime require that modules -be kernel modules, and kernel modules have no access to files, the -mesa_modbus framework compiles-in the modbus register structure and -HAL pins into an immutable, loadable, module. If you need to change -the register assignments or add/remove pins/registers then the module -must be recompiled. - -Load and activate the module with HAL commands such as - ----- -loadrt my_file ports=hm2_7i69.0.pktuart.0 -addf my_file.00 servo-thread ----- - -== Modbus == - -Rather than document modbus here, the main details can be found at: -https://en.wikipedia.org/wiki/Modbus - -The mesa_modbus system supports modbus commands 1,2,3,5,6,15,16. - -== HAL Interface == - -Modbus *write* commands will create HAL *input* pins, that take values -from HAL and pass them to the Modbus device. - -Modbus *read* commands will read data from the device and pass that to -HAL *output* pins for use by other components. - -HAL_BIT, HAL_U32 and HAL_S32 pins will present the (16 bit) Modbus -registers exactly as the bits are delivered from the device and will -send them to the device as 16 bit values according to standard C type -conversion standards. HAL_FLOAT values are treated differently. When a -float pin is specified then two extra HAL pins are created with the -same name but suffixed with -scale and offset. The value from the -modbus register will be interpreted as a sighed-16 bit number. It will -then be multiplied by the scale value and then the offset will be -added (i.e. the offset is in engineering units, and the scale converts 16 -bit register values to engineering units). - -The reverse transformation is performed when writing to the device. - -All Modbus registers are 16 bits. It is possible that in some applications -this might be used to represent encoder counts or some other number that -will wrap-around. To circumvent this problem in the case of the HAL_S32 -pin type the registers will be promoted to signed 64-bit internally then -multiplied by the "scale" pin value and presented as a floating point -value on a HAL pin with the suffix "scaled". -For example mymodule.0.counts-0-scaled. - - -In addition to the pins configured in the definition file, each -module will create the following pins for each instance of the driver: - -*modname.address* (default 0x01) - -*modname.baudrate* (default 9600) - -*modname.parity* (default 0 (no parity) options are 1 for odd and 2 for even.) - -*modname.txdelay* (default 20 bit lengths. Generally should be larger than Rx Delay) - -*modname.rxdelay* (default 15) - -*modname.drive_delay* (default 0) - -*modname.update-hz* (default 0) - -*modname.fault* - indicates a fault with the device or comms - -*modname.last-error* - indicates the error code that set the fault output. - -These can be redefined at any time and will take effect the next time -that a modbus packet is assembled. - -*modname.update-hz* is provided to slow down the transaction rate for -modbus devices that become unstable if polled too frequently. If you see -fault 11 then try setting this to 0.1Hz or even 1Hz. If set to zero the -system runs as fast as it can. - -The fault codes returned in "last error" are - -[width="90%",options="header"] -|=== -|Code|Fault -|1|Illegal Function -|2|Illegal Data Address -|3|Illegal Data Value -|4|Server Device Failure -|5|Acknowledge -|6|Server Device Busy -|7|Negative Acknowledge -|8|Memory Parity Error -|9|Gateway Path Unavailable -|10|Gateway Failed to Respond -|11|Comm Timeout -|=== - -Each module exports a single HAL function to be attached to a realtime -thread. The function name is just the module name, with no distinction -made between read and write cycles. - -All modules created by the framework require a hostmot2 pktuart instance -to be given to the "ports" modparam on the "loadrt" file. See the -example in the [Quick Start] section. - - -== Configuration File == - -A Mesa_Modbus configuration file is actually a C header file and must -conform to C syntax rules. An example file is included here: - -[source,C] ----- -/* -The format of the channel descriptors is: - -{TYPE, FUNC, ADDR, COUNT, pin_name} - -TYPE is one of HAL_BIT, HAL_FLOAT, HAL_S32, HAL_U32 -FUNC = 1, 2, 3, 4, 5, 6, 15, 16 - Modbus commands -COUNT = number of coils/registers to read -*/ - -#define MAX_MSG_LEN 16 // may be increased if necessary to max 251 - -static const hm2_modbus_chan_descriptor_t channels[] = { -/* {TYPE, FUNC, ADDR, COUNT, pin_name} */ -// Create 8 HAL bit pins coil-00 .. -07 supplying the values of coils at 0x0000 - {HAL_BIT, 1, 0x0000, 8, "coil"}, -// Create 8 HAL bit pins input-00 .. -07 supplying the values of inputs at 0x0000 - {HAL_BIT, 2, 0x0000, 8, "input"}, -// Create a HAL pin to set the coil at address 0x0010 - {HAL_BIT, 5, 0x0010, 1, "coil-0"}, -// Create 8 HAL pins to set the coils at 0x0020 - {HAL_BIT, 15, 0x0020, 8, "more_coils"}, -// Create a scaled floating point pin calculated from input register 0x0100 - {HAL_FLOAT, 4, 0x0100, 1, "float"}, -// Create 4 unsigned integer HAL pins from the holding registers at 0x0200-0x203 - {HAL_S32, 3, 0x0003, 4, "holding"}, -// Create a single signed int HAL pin to control the register at 0x0300 - {HAL_S32, 6, 0x0300, 1, "relay-3"}, -// Create 7 scaled FP HAL pins to control holfing registers at 0x400-0x406 - {HAL_FLOAT, 16, 0x0300, 1, "more_floats"}, -}; ----- - -Typically the comments would not be included in a config file. - -MAX_MSG_LEN can be included as a #define if required, but will default -to 16 bytes if this is omitted. The Modbus protocol forces a hard max -limit of 251 bytes, but that would imply setting thousands of bits or -hundreds of registers in a single transaction. - -An optional DEBUG parameter may be defined. This will default to -RTAPI_MSG_ERR (1) which means that only error messages will be shown. -include the line ----- -#define DEBUG 3 ----- -To see verbose data from the driver which can be useful for debugging. -Be aware that this is a lot of data, and it should be turned back to -1 when the driver is working. - -The text `static const hm2_modbus_chan_descriptor_t channels[] = {` -must be left unchanged, and the concluding `};` is also very -important. - -Between the start and end delimiters defined above there should be as -many descriptors as necessary for the device being controlled. For a -simple device (such as a single channel ADC) there might be only one -line. For such a simple device the following minimal description file -would suffice - -[source,C] ----- -static const hm2_modbus_chan_descriptor_t channels[] = { -/* {TYPE, FUNC, ADDR, COUNT, pin_name} */ - {HAL_FLOAT, 3, 0x0000, 1, "volts"}, -}; ----- - -The valid HAL pin types supported are HAL_BIT, HAL_FLOAT, HAL_U32 and -HAL_S32. - -The supported Modbus command types are: - -[width="90%",options="header"] -|=== -|Description|Code -|Read Coils|1 -|Read Discrete Inputs|2 -|Read Multiple Holding Registers|3 -|Read Input Registers|4 -|Write Single Coil|5 -|Write Single Holding Register|6 -|Write Multiple Coils|15 -|Write Multiple Holding Registers|16 -|=== - -The Modbus address can be given in Hexadecimal, decimal (or even octal) -as can the modbus command. Typically the modbus commands are given in -decimal and the addresses in hex. - -If the number in the "count" column is >1 _and_ if the command given -supports multiple reads/writes then a numbered sequence of HAL pins will -be created using the root name from the definition with an appended 2 -digit suffix, eg `volts-03`. For commands that do not support multiple -values (5, 6) the count column is silently ignored (but must be numeric -and not omitted) - -== Compiling == - -A simple script 'modcompile' is provided that will compile and install -a new HAL module based on the mesa_modbus.c file and the pin definition -file. The sample definition files use the .mod prefix but this is not -necessary except in the special case of the 'modcompile all' command, -which will compile and install all .mod files in the current directory. - ----- -sudo modcompile my_file.mod ----- - -or - ----- -sudo modcompile all ----- - -"modcompile" is provided by the "linuxcnc-dev" package. - ----- -sudo apt-get install linuxcnc-uspace-dev ----- - -or - ----- -sudo apt-get install linuxcnc-dev ----- - -if using RTAI kernel realtime. - -Alternatively the package should be installable with the Synaptic -package manager. - -== Hardware Connection == - -The Mesa serial ports have separate pins for Tx and Tx pairs. For RS422 -Modbus RTU communications these should be connected at the Mesa card -Tx+ to Rx+ and Tx- to Rx-. - -Note that there are differing naming standards for Modbus pins. -Typically Rx+ and TX+ will connect to the B- pin on the modbus device -and Rx- and Tx- will connect to the A+ pin, i.e., +/- will appear reversed. - - -=== Ad-hoc Modbus device access === - -For experimentation and one-off configuration it is possible to send / -receive data through the FPGA serial port using the mesaflash utility -in a script. A sample script follows. - -[source,bash] ----- -#! /bin/bash - -# First setup the DDR and Alt Source regs for the 7I96 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x1100=0x1F800 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x1104=0x1C3FF -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x1200=0x1F800 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x1204=0x1C3FF -# Next set the baud rate DDS's for 9600 baud -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6300=0x65 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6700=0x65 -# setup the TX and RX mode registers -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6400=0x00000A20 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6800=0x3FC0140C -# Reset the TX and RX UARTS -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6400=0x80010000 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6800=0x80010000 -# load two 8-byte modbus commands: -# 01 05 00 00 5A 00 F7 6A and 01 01 00 00 00 01 FD CA -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6100=0x00000501 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6100=0x6AF7005A -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6100=0x00000101 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6100=0xCAFD0100 - -# Command the TX UART to send the two 8 byte packets -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6200=0x08 -mesaflash --device 7i96 --addr 10.10.10.10 --wpo 0x6200=0x08 -sleep 1 -# display TX Mode -mesaflash --device 7i96 --addr 10.10.10.10 --rpo 0x6400 -# display the RX mode reg, RX count, and the data -mesaflash --device 7i96 --addr 10.10.10.10 --rpo 0x6800 -mesaflash --device 7i96 --addr 10.10.10.10 --rpo 0x6600 -mesaflash --device 7i96 --addr 10.10.10.10 --rpo 0x6500 -mesaflash --device 7i96 --addr 10.10.10.10 --rpo 0x6500 ----- - -// vim: set syntax=asciidoc: diff --git a/docs/src/getting-started/updating-linuxcnc.adoc b/docs/src/getting-started/updating-linuxcnc.adoc index d9f44143dab..39f2b7ee517 100644 --- a/docs/src/getting-started/updating-linuxcnc.adoc +++ b/docs/src/getting-started/updating-linuxcnc.adoc @@ -224,6 +224,14 @@ Touchy: the Touchy MACRO entries should now be placed in a [MACROS] section of the INI rather than in the [TOUCHY] section. This is part of a process of commonising the INI setting between GUIs. +The mesa_modbus framework (modcompile and the mesa_modbus.c.tmpl driver +template) has been removed. Configurations using it must migrate to the +hm2_modbus driver with mesambccc-compiled MBCCB files, see +link:../man/man9/hm2_modbus.9.html[hm2_modbus(9)] and +link:../man/man1/mesambccc.1.html[mesambccc(1)]. The 2.9 release retains +the framework, so its documentation remains available in the +http://linuxcnc.org/docs/2.9/html/drivers/mesa_modbus.html[2.9 docs]. + == Preview renderer now requires OpenGL 3.3 core diff --git a/docs/src/hal/components.adoc b/docs/src/hal/components.adoc index d4987f82b26..ab9155e8d17 100644 --- a/docs/src/hal/components.adoc +++ b/docs/src/hal/components.adoc @@ -154,7 +154,6 @@ To search in the man pages, use the UNIX tool `apropos`. | link:../man/man1/latency-plot.1.html[latency-plot] |Another way to view latency numbers || | link:../man/man1/latency-test.1.html[latency-test] |Tests the realtime system latency || | link:../man/man1/linuxcncmkdesktop.1.html[linuxcncmkdesktop] |Create a desktop icon for LinuxCNC || -| link:../man/man1/modcompile.1.html[modcompile] |Utility for compiling Modbus drivers. Deprecated: use hm2_modbus with mesambccc instead.|| | link:../man/man1/motion-logger.1.html[motion-logger] |Log motion commands sent from LinuxCNC || | link:../man/man1/pncconf.1.html[pncconf] |Configuration wizard for Mesa cards || | link:../man/man1/sim_pin.1.html[sim_pin] |GUI for displaying and setting one or more HAL inputs || diff --git a/docs/src/index.tmpl b/docs/src/index.tmpl index ee1fef424e2..2b0d800ae21 100644 --- a/docs/src/index.tmpl +++ b/docs/src/index.tmpl @@ -113,7 +113,6 @@
  • Raspberry Pi GPIO Driver
  • Mesa HostMot2 Driver
  • Modbus to HAL Driver
  • -
  • Modbus framework for Mesa cards (deprecated)
  • Mitsubishi VFD Driver
  • Pico Drivers
  • Powermax Modbus Driver
  • diff --git a/docs/src/man/man1/mesambccc.1.adoc b/docs/src/man/man1/mesambccc.1.adoc index 04790753bbf..4ce94ea05cb 100644 --- a/docs/src/man/man1/mesambccc.1.adoc +++ b/docs/src/man/man1/mesambccc.1.adoc @@ -678,8 +678,6 @@ Recognized '//' attributes: *linuxcnc*(1), *hm2_modbus*(9). -https://linuxcnc.org/docs/devel/html/drivers/mesa_modbus.html - == AUTHOR This man page written by B.Stultiens, as part of the LinuxCNC project. diff --git a/docs/src/man/man1/modcompile.1.adoc b/docs/src/man/man1/modcompile.1.adoc deleted file mode 100644 index 076e14c8415..00000000000 --- a/docs/src/man/man1/modcompile.1.adoc +++ /dev/null @@ -1,65 +0,0 @@ -= modcompile(1) - -== NAME - -modcompile - Utility for compiling Modbus drivers (DEPRECATED) - -== SYNOPSIS - -*modcompile -h* - -*modcompile* [*-k*] [*-n*] [*-v*] all - -*modcompile* [*-k*] [*-n*] [*-v*] module.mod ... - -== DESCRIPTION - -*modcompile* and the mesa_modbus framework are deprecated and will be removed in a future release. -New configurations should use the *hm2_modbus* driver with *mesambccc*-compiled MBCCB files instead. - -The *modcompile* utility is used to compile modbus drivers that use the PktUART -interface of Mesa cards. - -See the main LinuxCNC documentation for more details. - -https://linuxcnc.org/docs/devel/html/drivers/mesa_modbus.html - -== OPTIONS - -*-h*, *--help*:: - Brief help message. -*-k*, *--keep*:: - Keep the temporary files. The program will print a line where these are - located. You will be responsible for deleting them. -*-n*, *--noinstall*:: - Do not run the install step for the compiled module. This option is probably - only useful if you also use the *--keep* option. -*-v*, *--verbose*:: - Do a verbose build, showing all steps detailed while being performed. - -== SEE ALSO - -linuxcnc(1) - -Much more information about LinuxCNC and HAL is available in the -LinuxCNC and HAL User Manuals, found at /usr/share/doc/LinuxCNC/. - -== BUGS - -None known at this time. - -== AUTHOR - -This man page written by Andy Pugh, as part of the LinuxCNC project. - -== REPORTING BUGS - -Report bugs at https://github.com/LinuxCNC/linuxcnc/issues - -== COPYRIGHT - -Copyright © 2023 Andy Pugh. - -This is free software; see the source for copying conditions. There is -NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR -PURPOSE. diff --git a/docs/src/man/man3/hm2_pktuart.3.adoc b/docs/src/man/man3/hm2_pktuart.3.adoc index ce10b709dbc..802e5ae4660 100644 --- a/docs/src/man/man3/hm2_pktuart.3.adoc +++ b/docs/src/man/man3/hm2_pktuart.3.adoc @@ -243,7 +243,7 @@ The functions / hostmot2 component do not create any HAL pins. == EXAMPLE See inuxcnc-dev/src/hal/components/mesa_pktgyro_test.comp for a simple example (which might not work, and uses the deprecated direct reads and writes. -**mesa_modbus** is a better example, but significantly more complex and less instructive because of that. +**hm2_modbus** is a more complete example, but significantly more complex and less instructive because of that. == Testing == diff --git a/src/Makefile b/src/Makefile index 64d7d75c34a..c05d9071f95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -783,8 +783,6 @@ ifeq ($(BUILD_GUI),yes) $(FILE) ../share/gtksourceview-4/language-specs/*.lang $(DESTDIR)$(datadir)/gtksourceview-4/language-specs/ endif - $(FILE) ../src/hal/drivers/mesa-hostmot2/modbus/*.tmpl $(DESTDIR)$(prefix)/share/linuxcnc/ - install-kernel-indep: install-python install-python: install-dirs $(DIR) $(DESTDIR)$(SITEPY) $(DESTDIR)$(SITEPY)/rs274 diff --git a/src/hal/drivers/mesa-hostmot2/modbus/README.adoc b/src/hal/drivers/mesa-hostmot2/modbus/README.adoc deleted file mode 100644 index 949d28c03a9..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/README.adoc +++ /dev/null @@ -1,15 +0,0 @@ -WARNING: The mesa_modbus framework (this directory and modcompile) is -deprecated and will be removed in a future release. Use the hm2_modbus -driver with mesambccc-compiled .mbccb files instead. - -Do not edit mesa_modbus.c (Unless you are sure that you want to, of -course). -Create a new xxxxx.mod file that describes your particular modbus device -and run ----- -modcompile xxxxx.mod ----- -to compile, and install, the component on your system. - -See the main mesa_modbus docs (in the "Hardware Drivers" section for -further information. diff --git a/src/hal/drivers/mesa-hostmot2/modbus/analogue.mod b/src/hal/drivers/mesa-hostmot2/modbus/analogue.mod deleted file mode 100644 index f2e3b899c98..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/analogue.mod +++ /dev/null @@ -1,27 +0,0 @@ -/* Modbus definition file for a single-channel analogue input module - found on eBay */ - -/* -The format of the channel descriptors is: - -{TYPE, FUNC, ADDR, COUNT, pin_name} - -TYPE is one of HAL_BIT, HAL_FLOAT, HAL_S32, HAL_U32, ENCODER -FUNC = 1, 2, 3, 4, 5, 6, 15, 16 - Modbus commands -COUNT = number of coils/registers to read -*/ - -#define MAX_MSG_LEN 16 // may be increased if necessary to max 251 - -static const hm2_modbus_chan_descriptor_t channels[] = { -/* {TYPE, FUNC, ADDR, COUNT, pin_name} */ - {HAL_FLOAT, 3, 0x0000, 1, "volts"}, -}; - -/* Optionally #define DEBUG to aid with troubleshooting. - Use 3 to see a lot of information about the modbus - internal workings. 1 is default (errors only) */ - -#define DEBUG 1 - -// vim: syn=c diff --git a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl b/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl deleted file mode 100644 index 05b2b3dad34..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl +++ /dev/null @@ -1,886 +0,0 @@ -// Copyright (C) 2023 Andy Pugh - -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// - -/* A configurable component to use Mesa PktUART for modbus control */ - - -#include -#include -#include -#include -#include -#include - -#if !defined(__KERNEL__) -#include -#include -#endif - -/* module information */ -MODULE_AUTHOR("Andy Pugh"); -MODULE_DESCRIPTION("Modbus control using Mesa PktUART\n" - "halcompiled from mesa_modbus.c and renamed"); -MODULE_LICENSE("GPL"); - -#define MAX_CHAN 8 - -static const char *error_codes[]={ - "Invalid exception code 0", - "Illegal Function", - "Illegal Data Address", - "Illegal Data Value", - "Server Device Failure", - "Acknowledge", - "Server Device Busy", - "Negative Acknowledge", - "Memory Parity Error", - "Unknown exception code 9", - "Gateway Path Unavailable", - "Gateway Failed to Respond", - "Comm Timeout" -}; - -// This is needed by the header file -typedef struct { - hal_type_t type; - int func; - rtapi_u16 addr; - rtapi_u8 count; - char name[HAL_NAME_LEN * 16]; -} hm2_modbus_chan_descriptor_t; - -#define xstr(x) #x -#define str(x) xstr(x) - -#ifdef _COMP_NAME_ -#define COMP_NAME str(_COMP_NAME_) -#else -#define COMP_NAME "mesa_modbus" -#endif - -// get the channel / register definitions -#ifdef MODFILE -#include str(MODFILE) -#else -#error No Modbus definition file provided. \ - Compile this file with "modcompile my_data.mod" -#include -#endif - -#ifndef MAX_MSG_LEN -#define MAX_MSG_LEN 16 -#endif - -#ifndef DEBUG -#define DEBUG 1 -#endif - -// Values within +/-EPSILON are considered zero -#define EPSILON (1e-12) - -// Rate is the update-hz pin frequency. There is no point in slower than once -// every 1000 seconds or faster than 10000 times per second. The slowness of -// the RS485/Modbus protocol prevents any real fast communication. -// Anyway, the current implementation does not honor the frequency correctly. -// This limit will at least prevent a divide-by-zero. -#define RATE_MIN (1e-3) -#define RATE_MAX (1e4) - -enum { - START, - WAIT_FOR_SEND_BEGIN, - WAIT_FOR_SEND_COMPLETE, - WAIT_FOR_DATA_FRAME, - WAIT_FOR_FRAME_SIZES, - WAIT_FOR_DATA, - FETCH_MORE_DATA, - WAIT_A_BIT, - WAIT_FOR_RX_CLEAR, - RESET_WAIT, -}; - -typedef struct { - hal_refs_u *pins; - hal_real_t *scale; - hal_refs_u *pin2; - rtapi_s64 *buff; - hal_bool_t fault; - hal_uint_t last_err; - hal_sint_t address; - hal_sint_t baudrate; - hal_sint_t parity; - hal_sint_t txdelay; - hal_sint_t rxdelay; - hal_sint_t drive_delay; - hal_real_t rate; -} hm2_modbus_hal_t; - -typedef struct { - hal_type_t type; - rtapi_u8 func; - rtapi_u16 addr; - int count; - int start_pin; - int ptr; // pointer to last byte - rtapi_u8 data[MAX_MSG_LEN + 4]; // add enough space for header and checksum -} hm2_modbus_channel_t; - -typedef struct{ - char port[HAL_NAME_LEN]; - int num_chans; - int num_pins; - hm2_modbus_hal_t *hal; - hm2_modbus_channel_t *chans; - int baudrate; - int parity; - int txdelay; - int rxdelay; - int drive_delay; - int state; - int index; - int pin; - int frame_index; - rtapi_u32 fsizes[16]; - rtapi_u32 rxdata[257]; - int iter; // used for timeout - int old_state; // used for timeout -} hm2_modbus_inst_t; - -typedef struct { - int num_insts; - hm2_modbus_inst_t *insts; -} hm2_modbus_t; - -static int comp_id; -static hm2_modbus_t *m; -static void process(void *arg, long period); -static int parse_data_frame(hm2_modbus_inst_t *inst); -static int build_data_frame(hm2_modbus_inst_t *inst); -static int do_setup(hm2_modbus_inst_t *inst); -static uint16_t RTU_CRC(rtapi_u8* buf, int len); - -static char *ports[MAX_CHAN]; -RTAPI_MP_ARRAY_STRING(ports, MAX_CHAN, "PktUART names"); - -int rtapi_app_main(void){ - int retval; - int i; // instance loops - int c; // channel loop - int p; // pin loops - int j; // generic loops - - rtapi_set_msg_level(DEBUG); - - rtapi_print_msg(RTAPI_MSG_WARN, COMP_NAME": WARNING: mesa_modbus-based drivers are deprecated" - " and will be removed in a future release. Use the hm2_modbus driver with" - " mesambccc-compiled MBCCB files instead.\n"); - - if (!ports[0]) { - rtapi_print_msg(RTAPI_MSG_ERR, "The "COMP_NAME" component requires at least" - " one valid pktuart port, eg ports=\"hm2_5i25.0.pktuart.7\"\n"); - return -EINVAL; - } - - comp_id = hal_init(COMP_NAME); - if (comp_id < 0) { - rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME": ERROR: hal_init() failed\n"); - return -1; - } - - // allocate shared memory for the base struct - m = (hm2_modbus_t*)rtapi_kmalloc(sizeof(hm2_modbus_t), RTAPI_GFP_KERNEL); - //m = (hm2_modbus_t*)hal_malloc(sizeof(hm2_modbus_t)); - if (m == 0) { - rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME": Out of Memory\n"); - hal_exit(comp_id); - return -1; - } - - // Count the instances. - for (m->num_insts = 0; ports[m->num_insts];m->num_insts++) {} - m->insts = (hm2_modbus_inst_t*)rtapi_kmalloc(m->num_insts * sizeof(hm2_modbus_inst_t), RTAPI_GFP_KERNEL); - // Parse the config string - for (i = 0; i < m->num_insts; i++) { - hm2_modbus_inst_t *inst = &m->insts[i]; - inst->num_chans = sizeof(channels)/sizeof(channels[0]); - // there may be more pins than channels - inst->num_pins = 0; - for (c = 0; c < inst->num_chans; c++){ - inst->num_pins += channels[c].count; - } - // Malloc structs and pins, some in main or kernel memory, some in HAL - inst->chans = (hm2_modbus_channel_t *)rtapi_kmalloc(inst->num_chans * sizeof(*inst->chans), RTAPI_GFP_KERNEL); - inst->hal = hal_malloc(sizeof(*inst->hal)); - inst->hal->pins = hal_malloc(inst->num_pins * sizeof(*inst->hal->pins)); - inst->hal->scale = hal_malloc(inst->num_pins * sizeof(*inst->hal->scale)); - inst->hal->pin2 = hal_malloc(inst->num_pins * sizeof(*inst->hal->pin2)); - inst->hal->buff = hal_malloc(inst->num_pins * sizeof(*inst->hal->buff)); - - rtapi_strlcpy(inst->port, ports[i], HAL_NAME_LEN); - - retval = hal_export_functf(process, inst, 1, 0, comp_id, COMP_NAME".%02i", i); - if (retval < 0) { - rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME" ERROR: function export failed\n"); - goto fail0; - } - - retval = hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->address), 0x01, COMP_NAME".%02i.address", i); - retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->baudrate), 9600, COMP_NAME".%02i.baudrate", i); - retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->parity), 0, COMP_NAME".%02i.parity", i); - retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->txdelay), 20, COMP_NAME".%02i.txdelay", i); - retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->rxdelay), 15, COMP_NAME".%02i.rxdelay", i); - retval += hal_param_new_si32(comp_id, HAL_RW, &(inst->hal->drive_delay), 0, COMP_NAME".%02i.drive-delay", i); - retval += hal_param_new_real(comp_id, HAL_RW, &(inst->hal->rate), 0.0, COMP_NAME".%02i.update-hz", i); - retval += hal_pin_new_bool(comp_id, HAL_OUT, &(inst->hal->fault), 0, COMP_NAME".%02i.fault", i); - retval += hal_pin_new_ui32(comp_id, HAL_OUT, &(inst->hal->last_err), 0, COMP_NAME".%02i.last-error", i); - if (retval < 0) { - rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME" ERROR: failed to create one or more pins/parameters\n"); - goto fail0; - } - - inst->state = START; - - do_setup(inst); - - p = 0; // HAL pin index, not aligned to channel index - for (c = 0; c < inst->num_chans; c++){ - hm2_modbus_channel_t *ch = &(inst->chans[c]); - hal_pin_dir_t dir; - rtapi_print_msg(RTAPI_MSG_INFO, "ch %i is at %p\n", c, ch); - ch->type = channels[c].type; - ch->func = channels[c].func; - ch->addr = channels[c].addr; - ch->count = channels[c].count; - ch->start_pin = p; - dir = HAL_OUT; //default, is changed depending on function - switch (ch->func) { - case 5: // write coil - if (ch->count > 1) { - rtapi_print_msg(RTAPI_MSG_ERR, "Count > 1 invalid" - " for function 5, resetting\n"); - ch->count = 1; - } - /* Fallthrough */ - case 15: // write multiple coils - if (ch->count > 8 * MAX_MSG_LEN){ - ch-> count = 8 * MAX_MSG_LEN; - rtapi_print_msg(RTAPI_MSG_ERR,"The Modbus protocol" - " enforces a hard limit of 2008 coils per transaction" - " but with the current setup file this component is" - " limited to %i coils per message. resetting\n", - ch->count); - } - dir = HAL_IN; - /* Fallthrough */ - case 1: // read coils - case 2: // read inputs - if (ch->count > 1){ - for (j = 0; j < ch->count; j++){ - retval = hal_pin_new_bool(comp_id, dir, - &(inst->hal->pins[p++].b), - 0, COMP_NAME".%02i.%s-%02i", - i, channels[c].name, j); - } - } else { - retval = hal_pin_new_bool(comp_id, dir, - &(inst->hal->pins[p++].b), - 0, COMP_NAME".%02i.%s", - i, channels[c].name); - } - break; - case 6: // write single register - if (ch->count > 1) { - rtapi_print_msg(RTAPI_MSG_ERR, "Count > 1 invalid" - " for function %i, resetting\n", ch->func); - ch->count = 1; - } - /* Fallthrough */ - case 16: // write multiple registers - if (ch->count > MAX_MSG_LEN / 2){ - ch-> count = MAX_MSG_LEN/2; - rtapi_print_msg(RTAPI_MSG_ERR,"The Modbus protocol" - " enforces a hard limit of 123 registers per transaction" - " but with the current setup file this component is" - " limited to %i coils per messsge. resetting\n", - ch->count); - } - dir = HAL_IN; - /* Fallthrough */ - case 3: // read holding registers - case 4: // read input registers - for (j = 0; j < ch->count; j++){ - switch (ch->type){ - case HAL_U32: - if (ch->count > 1) { - retval = hal_pin_new_ui32(comp_id, dir, - &(inst->hal->pins[p].u), - 0, COMP_NAME".%02i.%s-%02i", - i, channels[c].name, j); - } else { - retval = hal_pin_new_ui32(comp_id, dir, - &(inst->hal->pins[p].u), - 0, COMP_NAME".%02i.%s", - i, channels[c].name); - } - p++; - break; - case HAL_S32: - if (ch->count > 1) { - retval = hal_pin_new_si32(comp_id, dir, - &(inst->hal->pins[p].s), - 0, COMP_NAME".%02i.%s-%02i", - i, channels[c].name, j); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->scale[p]), - 1.0, COMP_NAME".%02i.%s-%02i-scale", - i, channels[c].name, j); - retval = hal_pin_new_real(comp_id, dir, - &(inst->hal->pin2[p].r), - 0.0, COMP_NAME".%02i.%s-%02i-scaled", - i, channels[c].name, j); - } else { - retval = hal_pin_new_si32(comp_id, dir, - &(inst->hal->pins[p].s), - 0, COMP_NAME".%02i.%s", - i, channels[c].name); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->scale[p]), - 1.0, COMP_NAME".%02i.%s-scale", - i, channels[c].name); - retval = hal_pin_new_real(comp_id, dir, - &(inst->hal->pin2[p].r), - 0.0, COMP_NAME".%02i.%s-scaled", - i, channels[c].name); - } - inst->hal->buff[p] = 0; - p++; - break; - case HAL_FLOAT: - if (ch->count > 1) { - retval = hal_pin_new_real(comp_id, dir, - &(inst->hal->pins[p].r), - 0.0, COMP_NAME".%02i.%s-%02i", - i, channels[c].name, j); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->scale[p]), - 1.0, COMP_NAME".%02i.%s-%02i-scale", - i, channels[c].name, j); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->pin2[p].r), - 0.0, COMP_NAME".%02i.%s-%02i-offset", - i, channels[c].name, j); - } else { - retval = hal_pin_new_real(comp_id, dir, - &(inst->hal->pins[p].r), - 0.0, COMP_NAME".%02i.%s", - i, channels[c].name); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->scale[p]), - 1.0, COMP_NAME".%02i.%s-scale", - i, channels[c].name); - retval = hal_pin_new_real(comp_id, HAL_IN, - &(inst->hal->pin2[p].r), - 0.0, COMP_NAME".%02i.%s-offset", - i, channels[c].name); - } - p++; - break; - default: - rtapi_print_msg(RTAPI_MSG_ERR, - "Unsupported HAL pin type (%i) in mesa_modbus definition file\n", - ch->type); - goto fail0; - } // type switch - } // pin count loop - break; - default: - rtapi_print_msg(RTAPI_MSG_ERR, - "Unsupported modbus function %i in mesa_modbus definition file\n", - ch->func); - goto fail0; - } // func switch - } // channel loop - } // instance loop - hal_ready(comp_id); - return 0; - - fail0: - hal_exit(comp_id); - return -1; - -} - -static int do_setup(hm2_modbus_inst_t *inst){ - - int retval; - - if (inst->baudrate == hal_get_si32(inst->hal->baudrate) - && inst->parity == hal_get_si32(inst->hal->parity) - && inst->txdelay == hal_get_si32(inst->hal->txdelay) - && inst->rxdelay == hal_get_si32(inst->hal->rxdelay) - && inst->drive_delay == hal_get_si32(inst->hal->drive_delay)) return 0; - - if (hal_get_si32(inst->hal->txdelay) > 0xFF) hal_set_si32(inst->hal->txdelay, 0xFF); - if (hal_get_si32(inst->hal->rxdelay) > 0xFF) hal_set_si32(inst->hal->rxdelay, 0xFF); - inst->baudrate = hal_get_si32(inst->hal->baudrate); - inst->parity = hal_get_si32(inst->hal->parity); - inst->txdelay = hal_get_si32(inst->hal->txdelay); - inst->rxdelay = hal_get_si32(inst->hal->rxdelay); - inst->drive_delay = hal_get_si32(inst->hal->drive_delay); - - unsigned flg; - flg = inst->parity != 0 ? HM2_PKTUART_CONFIG_PARITYEN : 0; - flg |= inst->parity == 1 ? HM2_PKTUART_CONFIG_PARITYODD : 0; - hm2_pktuart_config_t cfgrx = { - .baudrate = inst->baudrate, - .filterrate = inst->baudrate * 2, - .drivedelay = 0, - .ifdelay = inst->rxdelay, - .flags = flg | HM2_PKTUART_CONFIG_RXEN | HM2_PKTUART_CONFIG_RXMASKEN - }; - hm2_pktuart_config_t cfgtx = { - .baudrate = inst->baudrate, - .filterrate = 0, - .drivedelay = inst->drive_delay, - .ifdelay = inst->txdelay, - .flags = flg | HM2_PKTUART_CONFIG_DRIVEEN | HM2_PKTUART_CONFIG_DRIVEAUTO - }; - retval = hm2_pktuart_config(inst->port, &cfgrx, &cfgtx, 0); - - if (retval<0) - { - rtapi_print_msg(RTAPI_MSG_ERR, COMP_NAME"PktUART setup problem: %d\n", retval); - return -1; - } - - return 0; -} - -static int send_modbus_pkt(hm2_modbus_inst_t *inst){ - hm2_modbus_channel_t *ch = &(inst->chans[inst->index]); - rtapi_u16 checksum; - rtapi_u16 fsizes[1]; - rtapi_u8 frames; - int i; - - checksum = RTU_CRC(ch->data, ch->ptr + 1); - ch->data[++(ch->ptr)] = checksum & 0xFF; - ch->data[++(ch->ptr)] = (checksum >> 8) & 0xFF; - - rtapi_print_msg(RTAPI_MSG_INFO, "Sending to %s %i bytes ", inst->port, ch->ptr + 1); - for (i = 0; i <= ch->ptr; i++) rtapi_print_msg(RTAPI_MSG_INFO, " %02X ", ch->data[i]); - rtapi_print_msg(RTAPI_MSG_INFO, "\n"); - - frames = 1; - fsizes[0] = ch->ptr + 1; - hm2_pktuart_send(inst->port, ch->data, &frames, fsizes); - return 0; -} - -static void do_timeout(hm2_modbus_inst_t *inst){ - if (inst->state != inst->old_state){ - inst->iter = 0; - inst->old_state = inst->state; - } - if (inst->iter++ > 1000){ - rtapi_print_msg(RTAPI_MSG_INFO, "\n %i TIMEOUT_RESET %i\n", inst->iter, inst->state); - hm2_pktuart_reset(inst->port); - inst->state = RESET_WAIT; - inst->iter = 0; - hal_set_ui32(inst->hal->last_err, 11); - hal_set_bool(inst->hal->fault, 1); - inst->chans[inst->index].data[1] = 0xFF; // Write invalid data to force re-send - } - rtapi_print_msg(RTAPI_MSG_INFO, "%i timeout %i\r", inst->iter, inst->state); -} - -static void process(void *arg, long period) { - static long timer = 0; - hm2_modbus_inst_t *inst = arg; - rtapi_real rate; - int r; - - rtapi_u32 rxstatus = hm2_pktuart_get_rx_status(inst->port); - rtapi_u32 txstatus = hm2_pktuart_get_tx_status(inst->port); - - switch (inst->state) { - case START: - - rate = hal_get_real(inst->hal->rate); - if (rate >= RATE_MIN && rate <= RATE_MAX && (timer -= period) > 0) break; - - rtapi_print_msg(RTAPI_MSG_INFO, "START txstatus = %08X rxstatus = %08X\n", txstatus, rxstatus); - - do_setup(inst); - - // Check for received data - if (rxstatus & 0x200000) { - inst->state = WAIT_FOR_DATA_FRAME; - break; - } - - // No incoming data, so service the outputs - - if (++(inst->index) >= inst->num_chans) { - inst->index = 0; // channel counter - } - - if (build_data_frame(inst)){ // if data has changed - r = send_modbus_pkt(inst); - inst->state = WAIT_FOR_SEND_BEGIN; - if(rate >= RATE_MIN && rate <= RATE_MAX) - timer = 1e9 / rate; - } - - break; - case WAIT_FOR_SEND_BEGIN: - // single cycle delay to allow for queued data - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_SEND_BEGIN RX %X TX %X\n", txstatus, rxstatus); - do_timeout(inst); // just to reset the counter - inst->state = WAIT_FOR_SEND_COMPLETE; - break; - - case WAIT_FOR_SEND_COMPLETE: - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_SEND_COMPLETE RX %X TX %X\n", rxstatus, txstatus); - do_timeout(inst); - if ( ! (txstatus & 0x80)){ - inst->state = WAIT_FOR_DATA_FRAME; - } - break; - - case WAIT_FOR_DATA_FRAME: - do_timeout(inst); - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_DATA_FRAME - rxmode = %X\n", rxstatus); - if ( ! ( rxstatus & 0x1F0000)) { // no data yet - break; - } - inst->frame_index = 0; - memset(inst->fsizes, 0, sizeof(inst->fsizes)); - // find the frame size - hm2_pktuart_queue_get_frame_sizes(inst->port, inst->fsizes); - inst->state = WAIT_FOR_FRAME_SIZES; - break; - - case WAIT_FOR_FRAME_SIZES: - case FETCH_MORE_DATA: - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_FRAME_SIZES Index %i Frames %X %X %X %X\n", - inst->frame_index, inst->fsizes[0], inst->fsizes[1], inst->fsizes[2], inst->fsizes[3]); - do_timeout(inst); - if ((inst->fsizes[inst->frame_index] & 0xC000) - || ((inst->fsizes[inst->frame_index] & 0x3FF) > MAX_MSG_LEN)) { // indicates an overrun - rtapi_print_msg(RTAPI_MSG_INFO, "RESET\n"); - inst->state = START; - hm2_pktuart_reset(inst->port); - break; - } - r = hm2_pktuart_queue_read_data(inst->port, inst->rxdata, inst->fsizes[inst->frame_index] & 0x3FF); - rtapi_print_msg(RTAPI_MSG_INFO, "return value %i\n", r); - inst->state = WAIT_A_BIT; - break; - - case WAIT_A_BIT: - inst->state = WAIT_FOR_DATA; - break; - - case WAIT_FOR_DATA: - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_DATA\n"); - parse_data_frame(inst); - if ((inst->fsizes[++(inst->frame_index)] & 0x3FF) > 0){ - inst->state = FETCH_MORE_DATA; - } else { - inst->state = WAIT_FOR_RX_CLEAR; - } - break; - - case WAIT_FOR_RX_CLEAR: - rtapi_print_msg(RTAPI_MSG_INFO, "WAIT_FOR_RX_CLEAR txdata = %08X\r", rxstatus); - do_timeout(inst); - rtapi_print_msg(RTAPI_MSG_INFO, "\r"); - if (rxstatus & 0x200000) break; - inst->state = START; - hal_set_bool(inst->hal->fault, 0); - break; - - case RESET_WAIT: - if (inst->iter++ > 5) inst->state = START; - break; - - default: - rtapi_print_msg(RTAPI_MSG_ERR, "Unknown State in mesa_modbus\n"); - inst->state = START; - } - -} - -static int ch_append8(hm2_modbus_channel_t *ch, rtapi_u8 v){ - int r = 0; - if (ch->ptr++ > MAX_MSG_LEN) return -MAX_MSG_LEN; - if (ch->data[ch->ptr] != v) r = 1; // flag data changed - ch->data[ch->ptr] = v; - return r; -} - -static int ch_append16(hm2_modbus_channel_t *ch, rtapi_u16 v){ - int r = 0; - r = ch_append8(ch, (rtapi_u8)(v >> 8)); - r += ch_append8(ch, (rtapi_u8)(v & 0xFF)); - return r; -} - -static int ch_init(hm2_modbus_channel_t *ch, hm2_modbus_hal_t *hal){ - int r; - ch->ptr = -1; - r = ch_append8(ch, hal_get_si32(hal->address)); - r = ch_append8(ch, ch->func); - return r; -} - -static int build_data_frame(hm2_modbus_inst_t *inst){ - hm2_modbus_channel_t *ch = &(inst->chans[inst->index]); - hm2_modbus_hal_t *hal = inst->hal; - rtapi_u8 acc = 0; - int r = 0; - int p = ch->start_pin; - int i; - - rtapi_print_msg(RTAPI_MSG_INFO, "building packet %X %X start pin %i\n", ch->func, ch->addr, p); - - ch_init(ch, hal); - - switch (ch->func){ - case 1: // Read coils - case 2: // read discrete inputs - case 3: // read holding registers - case 4: // read input registers - r += ch_append16(ch, ch->addr); - r += ch_append16(ch, ch->count); - r += 1; // trigger a read packet every time - break; - case 5: // Write single coil - r += ch_append16(ch, ch->addr); - if (hal_get_bool(hal->pins[p].b)){ - r += ch_append16(ch, 0xFF00); - } else { - r += ch_append16(ch, 0x0000); - } - break; - case 6: //Write single register - r += ch_append16(ch, ch->addr); - switch (ch->type){ - case HAL_U32: - r += ch_append16(ch, (rtapi_u16)hal_get_ui32(hal->pins[p].u)); - break; - case HAL_S32: - r += ch_append16(ch, (rtapi_s16)hal_get_si32(hal->pins[p].s)); - break; - case HAL_FLOAT: - rtapi_print_msg(RTAPI_MSG_INFO, "671 %f %f %f \n", hal_get_real(hal->pins[p].r), hal_get_real(hal->pin2[p].r), hal_get_real(hal->scale[p])); - if (hal_get_real(hal->scale[p]) <= -EPSILON || hal_get_real(hal->scale[p]) >= +EPSILON){ - r+= ch_append16(ch, (rtapi_u16)((hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r)) / hal_get_real(hal->scale[p]))) ; - } - rtapi_print_msg(RTAPI_MSG_INFO, "678\n"); - break; - default: - break; - } - break; - case 15: // Write multiple coils - r += ch_append16(ch, ch->addr); - r += ch_append16(ch, ch->count); - r += ch_append8(ch, ( ch->count + 8 - 1) / 8); - for (i = 0; i < ch->count; i++){ - if (hal_get_bool(hal->pins[p++].b)) acc += 1 << (i % 8); - if (i % 8 == 7 || i == (ch->count -1)) { // time for the next byte - r += ch_append8(ch, acc); - acc = 0; - } - } - break; - case 16: // write multiple holding registers - r += ch_append16(ch, ch->addr); - r += ch_append16(ch, ch->count); - r += ch_append8(ch, ch->count * 2); - for (i = 0; i < ch->count; i++){ - switch (ch->type){ - case HAL_U32: - r += ch_append16(ch, (rtapi_u16)hal_get_ui32(hal->pins[p].u)); - break; - case HAL_S32: - r += ch_append16(ch, (rtapi_s16)hal_get_si32(hal->pins[p].s)); - break; - case HAL_FLOAT: - if (hal_get_real(hal->scale[p]) <= -EPSILON || hal_get_real(hal->scale[p]) >= +EPSILON){ - r+= ch_append16(ch, (rtapi_u16)((hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r)) / hal_get_real(hal->scale[p]))) ; - } else { - // Prevent (near) divide-by-zero and assume scale 1.0 - r+= ch_append16(ch, (rtapi_u16)(hal_get_real(hal->pins[p].r) - hal_get_real(hal->pin2[p].r))); - } - break; - default: - break; - } - p++ ; // increment pin pointer - } - break; - default: - rtapi_print_msg(RTAPI_MSG_ERR, "Unknown Modbus instruction\n"); - } - return r; -} - -static int parse_data_frame(hm2_modbus_inst_t *inst){ - hm2_modbus_channel_t *ch = &(inst->chans[inst->index]); - hm2_modbus_hal_t *hal = inst->hal; - rtapi_u32 *data = inst->rxdata; - int count = inst->fsizes[inst->frame_index] & 0x3FF; - int i; - int w = 0; - int b = 0; - int p; - int tmp; - rtapi_u8 bytes[MAX_MSG_LEN + 4] = {}; - rtapi_u16 checksum; - - rtapi_print_msg(RTAPI_MSG_INFO, "Return packet is "); - for (i = 0; i < count; i++){ - bytes[i] = (data[w] >> b) & 0xFF; - rtapi_print_msg(RTAPI_MSG_INFO, "%02X ", bytes[i]); - if ((b += 8) == 32) { b = 0; w++;} - } - rtapi_print_msg(RTAPI_MSG_INFO, "\n"); - if ((bytes[1] & 0x7F ) != ch->func) { - rtapi_print_msg(RTAPI_MSG_ERR, "call/response function number mismatch\n"); - ch->data[1] = 0xFF; // Write invalid data to force re-send - return -1; - } - - checksum = RTU_CRC(bytes, count - 2); - if (bytes[count - 2] != (checksum & 0xFF) || bytes[count - 1] != (checksum >> 8)){ - rtapi_print_msg(RTAPI_MSG_ERR, "Modbus checksum error\n"); - rtapi_print_msg(RTAPI_MSG_ERR, "%2X%02X != %04X\n", bytes[count - 1], bytes[count - 2], checksum); - ch->data[1] = 0xFF; // Write invalid data to force re-send - return -1; - } - - p = ch->start_pin; - - switch (bytes[1]){ - case 1: // read coils - case 2: // read inputs - w = 3; - b = 0; - for (i = 0; i < ch->count; i++){ - hal_set_bool(hal->pins[p++].b, (bytes[w] & 1 << b)); - if (++b >= 8) { b = 0; w++;} - } - break; - case 3: // read holding registers - case 4: // read registers - w = 3; - for (i = 0; i < bytes[2] / 2; i++){ - switch (ch->type){ - case HAL_U32: - hal_set_ui32(hal->pins[p].u, 256 * bytes[w] + bytes[w + 1]); - w += 2; - p++; - break; - case HAL_S32: // wrap the result into the (s32) offset too - tmp = hal_get_si32(hal->pins[p].s); - hal_set_si32(hal->pins[p].s, bytes[w] * 256 + bytes[w + 1]); - w += 2; - tmp = hal_get_si32(hal->pins[p].s) - tmp; - if (tmp > 32768) tmp -= 65536; - if (tmp < -32768) tmp += 65536; - hal->buff[p] += tmp; - hal_set_real(hal->pin2[p].r, hal->buff[p] * hal_get_real(hal->scale[p])); - p++; - break; - case HAL_FLOAT: - hal_set_real(hal->pins[p].r, (256 * bytes[w] + bytes[w + 1]) - * hal_get_real(hal->scale[p]) + hal_get_real(hal->pin2[p].r)); - w += 2; - p++; - break; - default: - break; - } - } - break; - // Nothing to do for write commands 5, 6, 15, 16 ?? - case 5: // set single coil - case 6: // write single register - case 15: // write multiple coils echo - case 16: // write multiple registers echo - break; - - // The following are error codes - case 129: // 1 + error bit - case 130: // 2 + error bit - case 131: // 3 + error bit - case 132: // 4 + error bit - case 133: // 5 + error bit - case 134: // 6 + error bit - case 143: // 15 + error bit - case 144: // 16 + error bit - ch->data[1] = 0xFF; // Write invalid data to force re-send - if(bytes[2] < sizeof(error_codes) / sizeof(*error_codes)) { - rtapi_print_msg(RTAPI_MSG_ERR, "Modbus error response function %i error %s\n", - bytes[1] & 0x7F, error_codes[bytes[2]]); - } else { - rtapi_print_msg(RTAPI_MSG_ERR, "Modbus error response function %i returned invalid exception code %u\n", - bytes[1] & 0x7F, (unsigned)bytes[2]); - } - break; - default: - rtapi_print_msg(RTAPI_MSG_ERR, "Unknown or unsupported Modbus function code\n"); - } - return 0; -} - -void rtapi_app_exit(void){ -int i; -for (i = 0; i < m->num_insts;i++){ - if (m->insts[i].chans != NULL) rtapi_kfree(m->insts[i].chans); - // rtapi_kfree(m->insts[i].hal); Automatically freed as was hal_malloc-ed -} -if (m != NULL) rtapi_kfree(m); - -hal_exit(comp_id); -} - -static uint16_t RTU_CRC(rtapi_u8* buf, int len){ - uint16_t crc = 0xFFFF; - int pos; - int i; - - for (pos = 0; pos < len; pos++) { - crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc - - for (i = 8; i != 0; i--) { // Loop over each bit - if ((crc & 0x0001) != 0) { // If the LSB is set - crc >>= 1; // Shift right and XOR 0xA001 - crc ^= 0xA001; - } - else // Else LSB is not set - crc >>= 1; // Just shift right - } - } - // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes) - return crc; -} - -// vim: syn=c ts=4 diff --git a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.mod.sample b/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.mod.sample deleted file mode 100644 index 5530b6e2b79..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/mesa_modbus.mod.sample +++ /dev/null @@ -1,33 +0,0 @@ -/* -The format of the channel descriptors is: - -{TYPE, FUNC, ADDR, COUNT, pin_name} - -TYPE is one of HAL_BIT, HAL_FLOAT, HAL_S32, HAL_U32 -FUNC = 1, 2, 3, 4, 5, 6, 15, 16 - Modbus commands -COUNT = number of coils/registers to read -*/ - -#define MAX_MSG_LEN 16 // may be increased if necessary to max 251 - -static const hm2_modbus_chan_descriptor_t channels[] = { -/* {TYPE, FUNC, ADDR, COUNT, pin_name} */ -// Create 8 HAL bit pins coil-00 .. -07 supplying the values of coils at 0x0000 - {HAL_BIT, 1, 0x0000, 8, "coil"}, -// Create 8 HAL bit pins input-00 .. -07 supplying the values of inputs at 0x0000 - {HAL_BIT, 2, 0x0000, 8, "input"}, -// Create a HAL pin to set the coil at address 0x0010 - {HAL_BIT, 5, 0x0010, 1, "coil-0"}, -// Create 8 HAL pins to set the coils at 0x0020 - {HAL_BIT, 15, 0x0020, 8, "more_coils"}, -// Create a scaled floating point pin calculated from input register 0x0100 - {HAL_FLOAT, 4, 0x0100, 1, "float"}, -// Create 4 unsigned integer HAL pins from the holding registers at 0x0200-0x203 - {HAL_S32, 3, 0x0003, 4, "holding"}, -// Create a single signed int HAL pin to control the register at 0x0300 - {HAL_S32, 6, 0x0300, 1, "relay-3"}, -// Create 7 scaled FP HAL pins to control holfing registers at 0x400-0x406 - {HAL_FLOAT, 16, 0x0300, 1, "more_floats"}, -}; - -// vim: syn=c diff --git a/src/hal/drivers/mesa-hostmot2/modbus/modcompile.py b/src/hal/drivers/mesa-hostmot2/modbus/modcompile.py deleted file mode 100644 index f594a2c4ca4..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/modcompile.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/python3 - -# Build Realtime Modbus modules to use the Mesa FPGA card PktUART - -# Based on parts of halcompile - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - - -import sys -import os -import tempfile -import getopt -import shutil - -def usage(): - print("""Build and install Modbus components that use the Mesa PktUART -Usage: - modcompile [opts] device.mod... Compile and install a driver defined in - device.mod - modcompile [opts] all Compile and install all .mod definition - files in this directory. -Options: - -h|--help This message - -k|--keep Keep temporary files - -n|--noinstall Don't perform the install step - -v|--verbose Verbose compile -""") - sys.exit(2) - -modinc = None -def find_modinc(): - global modinc - if modinc: return modinc - d = os.path.abspath(os.path.dirname(os.path.dirname(sys.argv[0]))) - for e in ['src', 'etc/linuxcnc', '/etc/linuxcnc', 'share/linuxcnc']: - e = os.path.join(d, e, 'Makefile.modinc') - if os.path.exists(e): - modinc = e - return e - raise SystemExit("Unable to locate Makefile.modinc") - -def main(): - # Get the command-line options - try: - opts, args = getopt.getopt(sys.argv[1:], "hklnv", ["help", "keep", "noinstall", "verbose"]) - except getopt.GetoptError as err: - raise SystemExit(err) # Something like "option -a not recognized" - - # Check the options - verbose = "" - install = " install" - keep = False - for o, a in opts: - if o in ("-v", "--verbose"): - verbose = " V=1" - elif o in ("-n", "--noinstall"): - install = "" - elif o in ("-k", "--keep"): - keep = True - elif o in ("-h", "--help"): - usage() - else: - raise SystemExit("Unhandled option: '%s'" % o); - - if len(args) < 1: - raise SystemExit("Must have at least one 'file.mod' argument or 'all' for all."); - - if len(args) > 1 and "all" in args: - raise SystemExit("Cannot do both 'all' modules and specific modules."); - if args[0] == "all": - args = [f for f in os.listdir(".") if f.endswith(".mod")] - # 'args' now contains all modules to compile - - if len(args) < 1: - raise SystemExit("No modules found (*.mod files) to compile."); - - print("WARNING: modcompile and the mesa_modbus framework are deprecated and will be" - " removed in a future release. Use the hm2_modbus driver with mesambccc-compiled" - " .mbccb files instead.", file=sys.stderr) - - # Create a temporary directory and copy the C template into it - tempdir = tempfile.mkdtemp(prefix="modcompile") - BASE = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")) - csrc = os.path.join(tempdir, "mesa_modbus.c") - if verbose: - print(csrc) - shutil.copy(os.path.join(BASE, "share", "linuxcnc", "mesa_modbus.c.tmpl"), csrc) - - # For each module to compile... - for f in args: - modname = os.path.splitext(os.path.basename(f))[0] - # The module definition is #included as mesa_modbus.h - m = open(os.path.join(tempdir, "Makefile"), "w") - print("obj-m += %s.o" % modname, file=m) - print("%s-objs:=mesa_modbus.o" % modname, file=m) - print("include %s" % find_modinc(), file=m) - print("EXTRA_CFLAGS += -I%s" % tempdir, file=m) - print("EXTRA_CFLAGS += -DMODFILE=%s" % os.path.abspath(f), file=m) - print("EXTRA_CFLAGS += -D_COMP_NAME_=%s" % modname, file=m) - m.close() - result = os.system("cd %s && make -B -S modules %s%s" % (tempdir, install, verbose)) - if result != 0: - raise SystemExit(os.WEXITSTATUS(result) or 1) - - # Cleanup step - if keep: - print("Sources and build files kept in: %s" % tempdir) - else: - shutil.rmtree(tempdir) - -if __name__ == "__main__": - main() diff --git a/src/hal/drivers/mesa-hostmot2/modbus/relayboard.mod b/src/hal/drivers/mesa-hostmot2/modbus/relayboard.mod deleted file mode 100644 index 83d913dce94..00000000000 --- a/src/hal/drivers/mesa-hostmot2/modbus/relayboard.mod +++ /dev/null @@ -1,30 +0,0 @@ -/* Modbus definition file for a 4-channel relay board found on eBay */ - -/* -The format of the channel descriptors is: - -{TYPE, FUNC, ADDR, COUNT, pin_name} - -TYPE is one of HAL_BIT, HAL_FLOAT, HAL_S32, HAL_U32 -FUNC = 1, 2, 3, 4, 5, 6, 15, 16 - Modbus commands -COUNT = number of coils/registers to read -*/ - -#define MAX_MSG_LEN 16 // may be increased if necessary to max 251 - -static const hm2_modbus_chan_descriptor_t channels[] = { -/* {TYPE, FUNC, ADDR, COUNT, pin_name} */ - {HAL_BIT, 1, 0x0000, 8, "state"}, - {HAL_BIT, 2, 0x0000, 8, "input"}, - {HAL_BIT, 5, 0x0000, 1, "relay-0"}, - {HAL_BIT, 5, 0x0001, 1, "relay-1"}, - {HAL_BIT, 5, 0x0002, 1, "relay-2"}, - {HAL_BIT, 5, 0x0003, 1, "relay-3"}, -}; - - -/* Optionally #define DEBUG to aid with troubleshooting. - Use 3 to see a lot of information about the modbus - internal workings. 1 is default (errors only) */ - -// vim: syn=c diff --git a/src/hal/utils/Submakefile b/src/hal/utils/Submakefile index 856b8df389f..b3dcdcfd162 100644 --- a/src/hal/utils/Submakefile +++ b/src/hal/utils/Submakefile @@ -111,22 +111,13 @@ endif $(ECHO) Copying python script $(notdir $@) $(Q)(echo '#!$(PYTHON)'; sed '1 { /^#!/d; }' $<) > $@.tmp && chmod +x $@.tmp && mv -f $@.tmp $@ -../bin/modcompile: ../bin/%: hal/drivers/mesa-hostmot2/modbus/%.py - @$(ECHO) Syntax checking python script $(notdir $@) - $(Q)$(PYTHON) -m py_compile $< - $(ECHO) Copying python script $(notdir $@) - $(Q)(echo '#!$(PYTHON)'; sed '1 { /^#!/d; }' $<) > $@.tmp && chmod +x $@.tmp && mv -f $@.tmp $@ -../share/linuxcnc/mesa_modbus.c.tmpl: hal/drivers/mesa-hostmot2/modbus/mesa_modbus.c.tmpl - $(ECHO) Copying Modbus template $(notdir $@) - $(Q)cp -f $< $@ - ../bin/mesambccc: ../bin/%: hal/drivers/mesa-hostmot2/%.py @$(ECHO) Syntax checking python script $(notdir $@) $(Q)$(PYTHON) -m py_compile $< $(ECHO) Copying python script $(notdir $@) $(Q)(echo '#!$(PYTHON)'; sed '1 { /^#!/d; }' $<) > $@.tmp && chmod +x $@.tmp && mv -f $@.tmp $@ -TARGETS += ../bin/halcompile ../bin/elbpcom ../bin/modcompile ../share/linuxcnc/mesa_modbus.c.tmpl ../bin/mesambccc +TARGETS += ../bin/halcompile ../bin/elbpcom ../bin/mesambccc objects/%.py: %.g @mkdir -p $(dir $@) $(Q)$(YAPPS) $< $@