was briefly considered for a smart sensor protocol to
use with the Data Acquisition project, but has subsequently been
abandoned in favour of CANopen. FreeMODBUS was ported to the STM32F103
as an exercise and was tested successfully. It is possible to
incorporate FreeRTOS but this hasn't been done. The firmware library
is libopencm3 which, when mature, should allow porting to a number of
Cortex M3 or M4 microcontrollers.
The code may be found on GitHub.
The following files are present in the package:
main file modbus.c contains callback functions to react to requests for
(eMBRegInputCB), Holding Register (eMBRegHoldingCB), Coil Register
(eMBRegCoilsCB) and Input Discrete Register (eMBRegDiscreteCB). These
form the MODBUS command set and define the data formats. The main
program is here and a call to a hardware configuration function is made
at the start.
The hardware configuration file stm32.c contains initialization code.
A makefile is provided for use with GNU make, and calls on the gcc ARM bare metal port
arm-none-eabi-gcc. This contains references to library locations
specific to the installation. These will need to be changed to suit
users' implementations. The LDSCRIPT variable refers to a linker script
that must be included to define the memory mappings. These scripts are
provided in the libopencm3 lib directories for each of the subfamilies
of devices. An appropriate one must be selected for the device being
used. Examples are given in the package here which define the memory
sizes for the STM32F103RBT6 and STM32F103RET6 devices, and include the generic linker script from the library.
file portother.c has two essential functions vMBPortEnterCritical() and
vMBPortExitCritical() needed by FreeMODBUS to ensure that certain code
blocks are not interrupted. These require the functions getprimask()
and setprimask(), which are defined here although they should appear in
libopencm3 eventually. These functions read and enable/disable the
global interrupt enable control.
has functions that manage the serial link. This includes setup,
initialization, get, put and an ISR. In the STM32 series, USART
interrupts are mapped to a single interrupt, so a single ISR
must determine what caused the interrupt. The Rx and Tx interrupts here are
checked and the pxMBFrameCBByteReceived() and
pxMBFrameCBTransmitterEmpty() callback functions respectively are invoked.
has code for timer initialization, enable, disable and a single ISR.
The STM32 families provide a large range of timers with a rich functionality. Here a basic
timer TIM2 is set to interrupt when the counter reaches a preset value.
This is used to time the gap between message bits. In MODBUS a gap of
more than 3.5 bit periods signals the end of a message. As such the
function vMBPortTimersEnable() must not only enable the timer, but also
reset its value to the initial count (in this case zero as an up
counter is used). This was a point I found unclear in the FreeMODBUS instructions.
- portevent.c is taken unchanged from the bare port. This implements the event queue and would need attention if an RTOS were to be used.
FreeMODBUS API documentation is found here. In
this page, under Related Pages, a description of the requirements for
porting to another archiecture is given, including the incorporation of
an RTOS. Many of the examples provided with FreeMODBUS contain ports
for FreeRTOS and include ARM Cortex M3 devices. These generally use the
proprietary peripheral libraries provided by the manufacturer. There is
among the examples a "bare port" that provides a framework for a new