Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Microprocessor Requirements

Expand

The microprocessor and memory requirements are modest. An 8 or 16-bit microcontroller running at a clock speed of 8MHz and having a total of 128kB of program memory and 16kB of SRAM should be able to easily accommodate the CWL.

Program Memory and RAM Estimates

Expand
titleProgram Memory and RAM Estimates

To generate some useful estimates, the CWL was integrated onto a 16-bit MSP430 platform having 128KB of program memory and 16KB of SRAM. The baseline program memory and RAM usage was recorded before library integration. The following table is generally illustrative of the additional memory requirements the CWL imposes.

Configuration

Program Memory (KB)

RAM (KB)

# 1: Full w/File Transfer and w/Standard Buffers

+20

+3.0

0.5 of the 3.0 is only used during a file transfer and could be dynamically allocated

#2: Full w/o File Transfer and w/Standard Buffers

+18

+2.5

#3: Full w/o File Transfer and w/Small Buffers

+17

+1.5

The compiler optimization level was set to high to derive these estimates.

Depending on the application complexity an additional 1-5KB of program memory may be required to complete a controller implementation.

In configuration #1 file transfer is supported and the additional RAM usage is 3.0KB. However, 0.5KB of the 3KB is only used as a temporary buffer during a file transfer from the OKC to the OKE system. This temporary buffer could be dynamically allocated from the heap by the application and freed when the transfer ends. This would put the additional fixed RAM cost of the CWL at 2.5KB.

The CWL does not directly use dynamic memory, so no additional burdens are placed on system heaps. However, some systems may need to increase the stack size of the main loop or task/thread that executes the CWL. Generally, a total stack size between 1-2KB is more than enough. Implementors must account for additional RAM usage if stack size must be increased. As always implementors should exercise their systems and verify that the system stacks have ample safety margin.

Also, the CWL requires a minimum of CW_PORT_MIN_SERIAL_RX_BUFFER_SIZE + CW_PORT_MIN_SERIAL_TX_BUFFER_SIZE bytes of software-based serial receive and transmit buffering, currently a total of 512 bytes. Many systems will already have software receive and transmit buffering that meets this requirement. If not, then implementors must account for the additional RAM usage to implement the required serial buffering.

Taking all these possible factors into account, in a sub-optimal situation the CWL may require up to +25KB of code space, +4KB RAM, and +0.5KB temporary heap usage.

While it is strongly recommended for OKE systems to implement the full CWL including file transfer, we understand that some legacy systems will have extreme memory constraints. For these systems the CWL can be configured to use as little as +17KB program memory and +1.5KB of RAM while still providing OpenKitchen compatibility.

It should be noted that in many instances implementors will be able to remove existing code that interfaces to other management systems, and easily achieve the program memory and RAM savings that completely offset the needs of the CWL.

OS Requirements

Expand

There are no minimum OS requirements. It is adaptable to any bare metal, RTOS, or Linux OS environment. The CWL does not directly use dynamic memory and does not directly rely on any OS task synchronization primitives.

Linux Port

The default port of the CWL is for Windows, which can be built and debugged using Visual Studio for implementors who want to experiment before starting their port.

A Linux port of the OKE simulator is available as well. To build the Linux port change directory to _OpenKitchenEquipment_OKE and run the _OpenKitchenEquipment_OKE.sh build script. The oke simulator will be created by the build process. Running the oke simulator is the same as running and using the Windows oke.exe simulator. See the Simulation section later in the document for information on how to run the oke and oke.exe simulators.

Linux versions of the CWM and OKC simulators are not available at this time. However, it is possible to run the CWM and OKC simulators on Windows and connect to the Linux oke simulator via a serial connection.

Endianness

Expand

To ensure interoperability between platforms the byte ordering of multi-byte integer values must be considered. Little-endian means that the least significant bytes of a multi-byte integer come before the most significant bytes as address values ascend. Big-endian, also known as network byte order, means that the most significant bytes of a multi-byte integer come before the least significant bytes as address values ascend.

When applicable the CWL internals will use network byte order. Controller specific application data is not required to use network byte order, although it is strongly recommended in cases where it is applicable; usually when using the %H formatter.

Equipment platforms must minimally provide ntohs() and htons() functions. If your platform does not already provide these functions the following C marcos can be placed in cwport.h:

Code Block
languagec
#define htons(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))

#define ntohs(x) htons(x)

Recursion

Expand

During the generation of certain JSON messages some functions, in particular MJPrintf(), will be called recursively. The depth of the recursion is a function of the number of levels of object and array nesting in a generated JSON string. Implementors are encouraged to minimize nesting both to reduce stack utilization on constrained platforms and to flatten OKMs that helps minimize cloud overhead when processing OKMs.

Reset

Expand
Code Block
languagec
void CWPortExeReset(void);

The CWPortExeReset() function must force a full warm start of the OKE controller. The function must ensure that the serial transmit software and hardware buffers are empty before resetting. This function should not return to the caller.

It is strongly recommended that the reset function call the CW_ERROR() macro to force the reset. If the assertion handler is implemented to log the assertion, then the cause of the reset will be traceable to a deliberately commanded action rather than a spurious problem.

MSP430 Pseudocode Example

In this example port to an MSP430 platform, the CWPortExeReset() function first waits for the transmit software queue to empty, then waits 10ms for the hardware buffers to finish transmitting on the wire. Finally, an assertion is forced. The assertion handler ensures the file and line number is logged and then performs a warm reset.

Code Block
languagec
Void CWPortExeReset(void)
{
    while (TxDataQueueIsEmpty() == false);
    DelayMs(10);
    CW_ERROR();
}

Flush

Expand
Code Block
languagec
void CWPortExeFlush(void);

The CWPortExeFlush() function is intended to permit the OKC to clear out persistent/non-volatile data such as accumulated logs or other data that could backlog or inhibit the desired operation of the equipment.

Primarily this function applies to the CWM that has very deep non-volatile queues, that in some cases the OKC needs to empty.

For many OKE implementations this function may not take any action.

Versions

Expand
Code Block
languagec
bool CWPortGetVersion(uint8_t index, int8_t **typeStr, int8_t **fwverStr, int8_t **hwrevStr) ;

The CWPortGetVersion() function returns platform type, software/firmware version, and hardware revision information about the OKE. The function allows the CWL to sequentially read zero or more sets of version information about the platform so that it can be reported to the OKC.

This means it is possible for a controller running the CWL to report versions for multiple components of the system. This is particularly important so the OKC can determine if firmware updates must be applied. Even when a component is not in-system upgradeable, having an inventory of the versions is critical for remote asset management. So, when in doubt report the version information of as much of the OKE system as possible.

The CWL reports version information to the OKC automatically, and calls the CWPortGetVersion() to fetch the versions. The CWL will call the CWPortGetVersion() in a loop initially passing an index of 0. If there is version information for index 0, which should always be the case, then the CWPortGetVersion() will set the parameter pointers to static strings for the type, firmware, and hardware NULL terminated strings, and then return true. It is important that the string buffers are not on the stack frame of the CWPortGetVersion() function, since they must be accessible after the function returns. Next the CWL will invoke CWPortGetVersion() again with an index of 1. If there are additional versions to report then the pointers will be updated and the function will return true, then the CWL will then ask for index 2. Else the function will return false and the CWL will know that no more version information is available. When CWPortGetVersion() returns true, all of the pointers must point to a valid NULL terminated string.

The type, software/firmware version, and hardware revisions are NULL terminated strings. The CWL does not impose any restrictions on the format of any of the version strings. However, it is recommended that implementors consider how the version information will be handled by the OKC. The goal is for the OKC to reliably detect what version is running and initiate configured firmware updates. This means the type and firmware version strings should be unambiguous and consistent across versions. In some cases, the hardware revision of a component may not be known, in this case a pointer to an empty string "" should be returned.

Pseudocode Example

In this example code the CWPortGetVersion() function returns two sets of version information. The first time the CWL calls the function with an index of 0, *typeStr is set to point to "TCHEF", *fwverStr is set to point to "1.3.42", and hwrevStr is set to point to "A1", and true is returned. The second time the CWL calls the function with an index of 1, *typeStr is set to point to "TCAB", *fwverStr is set to point to "4.2.c1", and hwrevStr is set to point to "REV3", and true is returned. The last time the CWL calls the function it returns false.

Code Block
languagec
Bool CWPortGetVersion(uint8_t index, int8_t** typeStr, int8_t** fwverStr, int8_t** hwrevStr) 
{
    static const int8_t *type[] = {"TCHEF","TCAB"} ;
    static const int8_t *fwver[] = {"1.3.42","4.2.c1"} ;
    static const int8_t *hwrev[] = {"A1","REV3"} ;

    CW_REQUIRE(typeStr != NULL);
    CW_REQUIRE(fwverStr != NULL);
    CW_REQUIRE(hwrevStr != NULL);

    /* There are only 2 versions to report */
    if (index >= 2) return false;

    *typeStr = (int8_t *) type[index];
    *fwverStr = (int8_t *) fwver[index];
    *hwrevStr = (int8_t *) hwrev[index];

    CW_ENSURE(*typeStr != NULL);
    CW_ENSURE(*fwverStr != NULL);
    CW_ENSURE(*hwrevStr != NULL);

    return true;
}

...