mesambccc - Utility for compiling hm2_modbus command control description files
mesambccc [-h|--help] [-v|--verbose] [-o file|--output=file] <filename.source.mbccs>
The mesambccc utility is used to compile hm2_modbus driver command control description files for running Modbus devices with Mesa cards using the PktUARTs. The MBCCS source file is an XML formatted document which describes the devices connected, pins to create and commands to issue to the PktUART port using the Modbus protocol. See MBCCS FILE FORMAT below.
-h, --help
Show a brief help message and exit.
-o file, --output=file
Save the compiled output to file. The file name mesamodbus.output.mbccb is used if no file is specified on the command line.
-v, --verbose
Output a verbose list of configuration parameters, devices, Modbus messages and HAL pins.
The Modbus command control source file (mbccs file) is an XML formatted document describing the communication parameters, connected devices, HAL pins and command functions to be sent over Modbus. The overall layout is as follows:
<?xml
version="1.0" encoding="UTF-8"?>
<mesamodbus [attributes...]>
<devices>...</devices>
<initlist>...</initlist>
<commands>...</commands>
</mesamodbus>
The <devices> tag must be defined before either <initlist> or <commands> are defined.
Attribute values are generally case insensitive, except for the name attributes, which should always be lower case.
Boolean attributes accept values "false" and "0" for false and "true" and "1" for true. Integer numerical values can be entered in decimal, hexadecimal, octal or binary form. The latter three require the value to be prefixed with "0x", "0o" or "0b" respectively. Floating point values follow standard rules for floating point values.
All values are checked to be within an acceptable range. Errors and warnings are emitted when values are out of bounds. In case of a warning they may be clamped to the acceptable range.
A subset of the Modbus functions is supported (with function number in parentheses):
• R_COILS (1): Maps to 1..2000 HAL output pins of type HAL_BIT.
• R_INPUTS (2): Maps to 1..2000 HAL output pins of type HAL_BIT.
• R_REGISTERS (3): Maps to 1..125 HAL output pins depending haltype and scale attributes.
• R_INPUTREGS (4): Maps to 1..125 HAL output pins depending haltype and scale attributes.
• W_COIL (5): Maps to single HAL input pin of type HAL_BIT.
• W_REGISTER (6): Maps to single HAL input pins depending haltype and scale attributes.
• W_COILS (15): Maps to 1..2000 HAL input pins of type HAL_BIT.
• W_REGISTERS (16): Maps to 1..125 HAL input pins depending haltype and scale attributes.
You can use the function’s symbolic name or numerical value in <command> in the function attribute (as in function="W_REGISTERS" or function="16").
The modbustype attribute declares the interpretation of values to or from a Modbus device’s registers. They can be a signed integer (S), unsigned integer (U) or a floating point value (F). The size of the value can be 16-bit, 32-bit or 64-bit and the byte-ordering must be specified. The Modbus default, when speaking in "register" quantities, is an unsigned 16-bit value in big-endian (U_AB).
Modbus devices may implement other interpretations covering multiple consecutive registers to create larger or other types. In doing so, multiple device vendors have created some different interpretations of the data that needs to be covered. Differences are primarily byte-ordering.
The byte-ordering is specified with one of the following suffixes:
• _AB, _BA
• _ABCD, _BADC, _CDAB, _DCBA
• _ABCDEFGH, _BADCFEHG, _CDABGHEF, _DCBAHGFE, _EFGHABCD, _FEHGBADC, _GHEFCDAB, _HGFEDCBA
Modbus standard byte-ordering is big-endian, which is the first in each list (_AB, _ABCD and _ABCDEFGH). Little-endian is the last in each list. The user may use any of the byte-orderings necessary and required because some device vendors have not paid attention to the proper on-wire ordering.
The byte-ordering suffix is prefixed with S (signed), U (unsigned) or F (float) to complete the modbustype attribute value. For example, a 32-bit float in big-endian is named F_ABCD. A 64-bit signed integer value in little-endian is S_HGFEDCBA.
The types have following ranges and will be clamped to the min/max values if the clamp attribute is set in the <command>:
• 16-bit:
• float16 [-65504.0..+65504.0] (F_AB, F_BA)
• signed integer [-32768..+32767] (S_AB, S_BA)
• unsigned integers [0..65535] (U_AB, U_BA)
• 32-bit:
• float [-3.4e38..+3.4e38] (F_ABCD...F_DCBA)
• signed integer [-2147483648..+2147483647] (S_ABCD...S_DCBA)
• unsigned integer [0..4294967296] (U_ABCD...U_DCBA)
• 64-bit:
• double [-1.7e308..+1.7e308] (F_ABCDEFGH...F_HGFEDCBA)
• signed integer [-9223372036854775808..9223372036854775807] (S_ABCDEFGH...S_HGFEDCBA)
• unsigned integer [0..18446744073709551615] (U_ABCDEFGH...U_HGFEDCBA)
The main enclosing tag <mesamodbus> contains the communication parameters and other setup values as attributes:
baudrate [1200..1000000]
Communication speed. Any speed over 460800 will result in side-effects because the internal hardware timers may overflow to keep track of the Modbus protocol requirements. Default 9600.
drivedelay [auto, 1..31]
The delay, in bit-times, before transmission begins after enabling the transmitter hardware output driver. Default auto.
duplex [full, half]
Whether 2-wire (half duplex) or 4-wire (full duplex) communication is set. Default half.
icdelay [auto, 1..255]
The maximum allowed inter-character delay between two received characters in bit-times. Default: auto.
interval [0..3600000000]
The default command repeat interval in micro-seconds. This is effectively the time between repeating the <commands> list (sending writes and receiving reads from the Modbus devices). An interval shorter than the time it takes to work through the <commands> list will just repeat the <commands> list as fast as possible.
The interval may be overridden in the individual <commands><command> instructions. Default 0.
parity [N, O, E]
Communication parity none (N), odd (O) or even (E). Default E.
rxdelay, txdelay [auto, 1..1020]
Inter frame delay between packets sent/received. The value is in bit-times. The appropriate value will be calculated automatically when this attribute is omitted. If set manually, the txdelay value should generally be larger than rxdelay value. The value is limited to [1..255] for PktUART V2. Default auto.
stopbits [1, 2]
Communication number of stopbits. This attribute requires PktUART V3+ to have any effect. Default 1.
suspend [Boolean]
Start with suspended communication when set. This enables you to setup pin, scale and offset values in the HAL file(s) using setp/sets commands before data is written to any Modbus device. Default false.
timeout [auto, 10000..10000000]
The standard time a command may take in micro-seconds (send request plus handling plus receive reply) before the command is deemed lost. The special value of auto will calculate an appropriate timeout value from the request and reply sizes. The timeout value can be overridden in the <command> definitions. Default auto.
writeflush [Boolean]
Set to true when the very first round of write commands must be flushed to synchronize the internal state to the pin state. This flush happens either once when the module starts or each time the module comes out of suspend.
The write flush is necessary when you need to ensure proper and correct pin data is present before the Modbus commands start sending potentially harmful or invalid data because the pins have not yet been initialized to their proper values. When set, only pin values that are changed from their initial values are propagated in Modbus write commands.
This value represents the global default used buy the individual commands from the <commands> section and can be overridden in the individual <command> instructions. Default true.
The default parameters, without any attributes defined in <mesamodbus>, are half duplex serial setup using 8E1@9600 and running all commands as fast as possible. Timeouts and other timing parameters are calculated automatically.
Each connected device to the physical bus must be declared in a <device> tag with a name and an address attribute. A device with name broadcast is implicitly added with address zero (0). Device entries may include a <description> tag, which serves as a user’s comment.
<devices>
<device address="0x01" name="binbox"
/>
<device address="0x02"
name="vroom">
<description>Round and round and
round...</description>
</device>
<device address="0x66"
name="clickies">
<description>Many, many relays</description>
</device>
</devices>
Recognized <devices>/<device> attributes:
address [1..247]
The Modbus slave device ID. The Modbus reserved address range 248..255 is accepted, but a warning is emitted.
name
The name of the device. The name must be in lower case ASCII and adhere to the HAL specification comprising of letters and numbers with optional dash and period. It is strongly advised to use letters only in a descriptive word. The device’s name is used to construct the HAL pin names.
The <initlist> tag contains a list of <command> tags that are only sent once at the startup of the system. The commands can be used to initialize any devices on the bus prior to normal operation. Commands can be both read and write functions. Write functions must have data defined to be sent. Each <command> entry may include a <description> tag, which serves as a user’s comment.
Note: if the driver starts in suspended mode (supend="true" in <mesamodbus>), then the <initlist> commands are first sent when the driver comes out of suspend.
<initlist>
<command device="scd30"
function="W_REGISTER"
address="0x0034">
<description>Soft reset</description>
<data value="1" />
</command>
<command device="relay"
function="W_COILS" address="0">
<data value="0" />
<data value="1" />
<data value="1" />
<data value="0" />
<description>Four relays set to
off-on-on-off</description>
</command>
<command device="boombox"
function="W_COIL" address="0">
<data value="0xff00" />
<description>Single output set to on to hear the
boombox</description>
</command>
<command delay="2000000">
<description>Wait for reset to
finish</description>
</command>
<command device="fltbox"
function="W_REGISTERS"
address="0xcafe">
<data modbustype="F_ABCD"
value="0.53" />
<data modbustype="F_ABCD"
value="99.999" />
<description>Send four 16-bit words: 0x3f07 0xae14
0x42c7 0xff7d
(floats in binary, big-endian)</description>
</command>
</initlist>
A <command> is either a delay instruction, a communication parameter change or a Modbus transaction to perform. Only the delay attribute is supported in case of a delay instruction and all activity is suspended during the specified delay. A communication parameter change can use any communication related attribute from the <mesamodbus> tag and must revert to the defaults set in the <mesamodbus> tag at the end on the <initlist>.
Modbus write functions must include one or more <data> tags to encapsulate the data to send. The <data> tag has a mandatory attribute value to capture the value to send. An optional modbustype attribute models the data to send to the format of the modbustype. The default is U_AB if the type is not specified.
The write coils Modbus function W_COILS (15) further restrict the value to zero (0) or one (1). The write coil W_COIL (5) has a fixed type of U_AB and expects a value of 0x0000 or 0xff00. Other values may be given, but a warning will then be emitted.
The Modbus read functions R_COILS (1), R_INPUTS (2), R_REGISTERS (3) and R_INPUTREGS (4) are supported in the <initlist>/<command> but the returned data is ignored and discarded. Read functions are supported because some devices require a read function as a trigger.
Recognized <initlist>/<command> attributes when sending Modbus commands:
address [0..65535]
The Modbus coil/input/register starting address.
bcanswer [Boolean]
Set to true if a device sends an answer on broadcast, which must be ignored. Default false.
count [1..2000]/[1..125]
Modbus read functions R_COILS (1), R_INPUTS (2), R_REGISTERS (3) and R_INPUTREGS (4) must specify the number of coils, inputs, registers or inputregs to read. Write functions do not require the count attribute because the <data> tags dictate the size of the packet to send.
device
The Modbus device to communicate with. The device attribute references <device>[name].
The device name broadcast will send the command to all devices on the bus.
function [see MODBUS FUNCTIONS]
The attribute value is one of the supported Modbus functions.
noanswer [Boolean]
Set to true if a device does not return a reply to a command. This can be intentional if you send a command to a non-existing device. Default false.
timeout [auto, 1..60000000]
The override timeout of <mesamodbus>[timeout] for this command in micro-seconds (send request plus handling plus receive reply) before the command is deemed lost. See also timeoutbits below. Default <mesamodbus>[timeout].
timeoutbits [0..1000000]
The override timeout of <mesamodbus>[timeout] for this command in bit times (send request plus handling plus receive reply) before the command is deemed lost. The actual timeout is automatically calculated and scaled by the <mesamodbus>[baudrate] setting. See also timeout above. Default use timeout attribute.
timesout [Boolean]
Set to true if the command is known to (periodically) timeout and no error should be emitted when it does. This differs from noanswer in that a reply may be expected within the timeout period but not after the timeout expires. This may be required for flaky devices. Default false.
Delay instruction
Recognized <initlist>/<command> attributes in delay commands:
delay [0..60000000]
Communication will be suspended by delay micro-seconds.
Communication parameter change
Communication parameters may be temporarily changed to perform live setup of Modbus devices to change their own communication parameters. Some devices will start with a fixed rate and must be reprogrammed at start to change to a different rate. The default setup from <mesamodbus> must be restored if one or more parameters were changed or a warning will be emitted.
Recognized <initlist>/<command> attributes in communication parameter change commands. Attributes not specified will be taken from the <mesamodbus> tag’s attributes:
baudrate [1200..1000000]
Communication speed override.
drivedelay [auto, 1..31]
The TX driver delay override.
icdelay [auto, 1..255]
The inter-character delay override.
parity [N, O, E]
Communication parity override.
rxdelay, txdelay [auto, 1..1020]
Inter frame delay override.
stopbits [1, 2]
Communication number of stopbits override.
Initialization data
Recognized <initlist>/<command>/<data> attributes:
modbustype [see MODBUS TYPES]
The destination format and translation of the value attribute.
value
The numerical value of the data to send. The format defaults to unsigned 16-bit integer but depends on the modbustype attribute and the range of acceptable values depends on the Modbus function.
A <command> in the <commands> section maps to one or more HAL pins with specific type using the haltype attribute. Recognized are:
• HAL_BIT
• HAL_FLOAT
• HAL_S32
• HAL_U32
The types are also recognized without the HAL_ prefix. Note that coil and binary input functions R_COILS (1), R_INPUTS (2), W_COIL (5) and W_COILS (15) can only map to HAL_BIT and do so implicitly.
The HAL_BIT and HAL_U32 types always map to one single HAL pin.
The HAL_FLOAT and HAL_S32 types can generate one single pin or can generate multiple pins with offset and scale. Output pins with R_REGISTERS (3) and R_INPUTREGS (4) can add a scaled pin to the set.
Mapping HAL pins to commands requires a modbustype attribute to encode the format and necessary conversions. Register functions R_REGISTERS (3), R_INPUTREGS (4), W_REGISTER (6) and W_REGISTERS (16) may map to HAL_BIT only when using unsigned modbustype where a value of zero (0) is false and any other value is true for write functions or one (1) for read functions.
Note on 64-bit integer types
The haltype names HAL_S64 and HAL_U64 are recognized but generate an error. The integer 64-bit types are not supported in the 2.9 branch because they are lacking in the API. You need a newer LinuxCNC version for full 64-bit support.
As a consequence, 64-bit integer Modbus types can only map to 32-bit HAL pins, which will reduce accuracy. A warning is emitted when you map the larger 64-bit integer Modbus types to a smaller 32-bit HAL type.
The <commands> section defines one or more <command> tags to describe the Modbus function(s) to execute in a periodical way. Each <command> tag maps to one or more HAL pins and specifies data conversion between device data and HAL pin data.
A delay command may be added using the delay attribute causing the communication to be suspended for the specified time. This may be required in broadcast situations where the Modbus devices must have time for internal processing before the next data is sent or requested.
The <command> entries may include a <description> child-tag, which serves as a user’s comment. Additionally, the <command> tag may have one or more <pin> child-tags to create user-defined HAL pin names. Each <pin> tag may again include a <description> child-tag.
Modbus read functions R_COILS (1), R_INPUTS (2), R_REGISTERS (3) and R_INPUTREGS (4) will always be sent at the specified interval. However, the Modbus write functions W_COIL (5), W_REGISTER (6), W_COILS (15) and W_REGISTERS (16) are only sent when the source data (pin value) changed. You must specify the resend attribute to force repeated writes at the specified interval.
<commands>
<command device="wavebox"
function="R_COILS" address="0x0000"
count="4" name="state" />
<description>Type is implicit HAL_BIT, will become HAL
pins:
- (out) hm2_modbus.0.wavebox.state-00
- (out) hm2_modbus.0.wavebox.state-01
- (out) hm2_modbus.0.wavebox.state-02
- (out) hm2_modbus.0.wavebox.state-03
</description>
</command>
<command device="scd30"
modbustype="F_ABCD" haltype="HAL_FLOAT"
function="R_REGISTERS"
address="0x0028" scale="0">
<pin name="co2"><description>Too much
will kill you...</description></pin>
<pin name="temperature" />
<pin name="humidity" />
<description>Will become HAL pins:
- (out) hm2_modbus.0.scd30.co2
- (out) hm2_modbus.0.scd30.temparature
- (out) hm2_modbus.0.scd30.humidity
Count will automatically be calculated (6 Modbus 16-bit
registers).
</description>
</command>
<command device="broadcast"
function="W_COILS" address="0x1234"
count="2"
name="anyandall" bcanswer="1">
<description>Will create HAL_BIT pins:
- (in) hm2_modbus.0.anyandall-00
- (in) hm2_modbus.0.anyandall-01
The bcanswer flag signifies that a device erroneously sends
a reply on
broadcast (oopsie), which needs to be ignored .
</description>
</command>
<!-- A delay is suggested after a broadcast to allow
devices to handle the data -->
<command delay="10000" />
<command device="watcher"
function="W_REGISTER" haltype="HAL_U32"
modbustype="U_AB"
address="0x1ee7" noanswer="1"
resend="1">
<pin name="watcher" />
<description>Will create a HAL_U32 pin
- (in) hm2_modbus.0.watcher
The 'count' is implicit 1. The data is mapped to U_AB and is
clamped.
The data is sent every time (resend=1), regardless whether
the HAL pin
changed. No answer is expected to be received (noanswer=1).
This
command generates a (valid) Modbus packet on the bus and
nothing more.
You must be sure that no reply is sent from the device or
errors will
occur (for example silent watchdog).
</description>
</command>
</commands>
Recognized <commands>/<command> attributes:
address [0..65535]
The Modbus coil/input/register starting address.
bcanswer [Boolean]
Set to true if a device sends an answer on broadcast, which must be ignored. Default false.
clamp [Boolean]
Conversion from larger to smaller types are automatically clamped to their maximum/minimum values. It works in both ways: read â HAL-out and write â HAL-in. Setting this to false can result in truncated values. Default is true.
count [1..2000]/[1..125]/[1..62]/[1..31]
The count specifies the number of HAL pins to create. The data from these pins is read from or written to the Modbus device. Alternatively, you can specify the HAL pins using the <pin> child-tags. If both count and <pin> are specified and count is larger than the number of <pin> tags, then additional HAL pins will be created to match the count.
(the range depends on haltype and modbustype)
delay [0..60000000]
Suspend activity and delay the next <command> by delay micro-seconds.
device
The Modbus device to communicate with. The device attribute references <device>[name].
The device name broadcast will send the command to all devices on the bus.
function [see MODBUS FUNCTIONS]
The attribute value is one of the supported Modbus functions.
haltype [see HAL TYPES]
The HAL pin type for interactions. You do not need to specify this attribute for the Modbus functions read/write coil(s) or inputs, R_COILS (1), R_INPUTS (2), W_COIL (5) and W_COILS (15), as these always use the HAL_BIT type.
interval [once,0..3600000000]
The command repeat interval in micro-seconds. This is the time between repeating this <command>. An interval shorter than the time it takes to work through the <commands> list will just repeat this <command> as fast as possible.
A special value of once will run this command only once. However, it will be retried is an error occurred. You normally do not need the value once and it may be better to use an entry in the <initlist>. But sometimes you need to have other periodic commands before a once marked command that cannot be achieved in the <initlist> sequence. Default <mesamodbus>[interval].
modbustype [see MODBUS TYPES]
The Modbus data mapping from/to register(s) for Modbus functions read/write register(s) R_REGISTERS (3), R_INPUTREGS (4), W_REGISTER (6) and W_REGISTERS (16). The default is U_AB if not specified.
name
The name for HAL pin names.
Example: if count="2" and name="myname", then the pins will have names myname-00 and myname-01, unless one or more <pin> tags override the name.
noanswer [Boolean]
Set to true if a device does not return a reply to a command. This can be intentional if you send a command to a non-existing device. Default false.
resend [Boolean]
Resend Modbus write command even though no HAL pin change (data to send change) was detected. Normally, only data changes are sent using Modbus write commands. Some devices require a constant "reminder" (like watchdogs) and you need to send the data regularly. Default false.
scale [Boolean]
Add scaling HAL pins. Modbus read functions R_REGISTERS (3) and R_INPUTREGS (4) add extra HAL pins pin.name.offset (in, 64-bit haltype), pin.name.scale (in, HAL_FLOAT) and pin.name.scaled (out, HAL_FLOAT).
The Modbus write functions W_REGISTER (6) and W_REGISTERS (16) create extra HAL pins pin.name.offset (in, 64-bit haltype) and pin.name.scale (in, HAL_FLOAT).
The scale attribute is only supported for HAL_FLOAT, HAL_S32 and HAL_S64. Default is true for HAL_FLOAT and false for others. The scale pin is initialized to one (1.0) and the offset pin is initialized to zero (0).
Scaling is always multiplicative to prevent division-by-zero. The offset is always subtracted before scaling. The scaling action performed and subject to clamping is:
• read: pin.name = "readvalue"
• read: pin.name.scaled = ("readvalue" - pin.name.offset) * pin.name.scale
• write: "sendvalue" = (pin.name - pin.name.offset) * pin.name.scale
timeout [auto, 1..60000000]
The override timeout of <mesamodbus>[timeout] for this command in micro-seconds (send request plus handling plus receive reply) before the command is deemed lost. See also timeoutbits below. Default <mesamodbus>[timeout].
timeoutbits [0..1000000]
The override timeout of <mesamodbus>[timeout] for this command in bit times (send request plus handling plus receive reply) before the command is deemed lost. The actual timeout is automatically calculated and scaled by the <mesamodbus>[baudrate] setting. See also timeout above. Default <mesamodbus>[timeout].
timesout [Boolean]
Set to true if the command is known to (periodically) timeout and no error should be emitted when it does. This differs from noanswer in that a reply may be expected within the timeout period but not after the timeout expires. This may be required for flaky devices. Default false.
writeflush [Boolean]
The override the writeflush value. See <mesamodbus>[writeflush] for details. Default <mesamodbus>[writeflush].
Pins
Defining <pin> tags allows for custom naming schemes and allows reducing read and write function overhead. Using <pin> tags enables you to combine different modbustype and haltype values to be read or written to or from consecutive addresses. A warning is emitted if 32-bit and 64-bit values are not aligned to their native boundary (it may be an error, depending device). The attributes of the <command> tag set the defaults for the <pin> tag attributes and can be overridden by adding them to the <pin> tag.
<command
device="booboo"
function="R_REGISTERS"
address="0x0240"
haltype="HAL_FLOAT"
modbustype="F_ABCD"
scale="1">
<!-- addr: 0x0240-0x0241; disable scaling pins -->
<pin name="speed" scale="0" />
<!-- addr:0x0242; one register to bit-->
<pin name="ping" haltype="HAL_BIT"
modbustype="U_AB" />
<!-- Align the next value -->
<pin skip="1" />
<!-- addr: 0x0244-0x0245; use defaults from this command
-->
<pin name="afloat" />
<!--
The above <command><pin> tags read 6 registers
and generate pins:
hm2_modbus.0.speed HAL_FLOAT (out)
hm2_modbus.0.ping HAL_BIT (out)
hm2_modbud.0.afloat HAL_FLOAT (out)
hm2_modbud.0.afloat.offset HAL_FLOAT (in)
hm2_modbud.0.afloat.scale HAL_FLOAT (in)
hm2_modbud.0.afloat.scaled HAL_FLOAT (out)
-->
</command>
Recognized <commands>/<command>/<pin> attributes:
clamp [Boolean]
The clamp setting override for this pin.
haltype [see HAL TYPES]
The HAL type override for this pin.
modbustype [see MODBUS TYPES]
The Modbus type override for this pin.
name
Specifies the pin name overriding the default <command>[name]-xx sequence. This makes the HAL names more human readable.
scale [Boolean]
The scale setting override for this pin.
skip [0..24]
Skip a number of registers ignoring them for read functions and writing zero (0) for write functions. There can not be other attributes if the skip attribute is used.
Using a skip value larger than 11 will emit a warning. Large skips make the transfers less efficient and skipping 12+ registers may be better off by splitting the function in two commands. An exception may be atomicity where the device allows access to the intermediate (unused) register addresses and only guarantees atomicity in a single read/write transaction.
Beware that the skipped registers must be readable or writable (depending function). The skipped values must be transferred in the Modbus transaction and the target device must allow read or write access to the skipped register addresses.
Beware: using skip in write commands writes value zero (0) to the skipped registers.
linuxcnc(1), hm2_modbus(9).
https://linuxcnc.org/docs/stable/html/drivers/mesa_modbus.html
This man page written by B.Stultiens, as part of the LinuxCNC project.
Report bugs at https://github.com/LinuxCNC/linuxcnc/issues
Copyright © 2025 B.Stultiens
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.