Skip to content
Stuart W Baker edited this page May 23, 2015 · 10 revisions

Welcome to the Open Model Railroad Networking (OpenMRN) wiki!

Overview

OpenMRN is a portable library implementing a protocol stack for model railroads. It follows the standards in development at OpenLCB, which have been adopted by the NMRA (National Model Railroad Association) under the name of NMRAnet. As transport layer this protocol stack currently uses CAN-bus and TCP/IP. There are plans to support other model railroad control buses, such as LocoNet, Xpressnet etc., but no code has been written for that yet.

The OpenMRN source tree also provides a set of example ports and a couple of simple applications. The intention is that hardware and application developers use OpenMRN as a basic stack, and link their application-specific logic together with it to create their production software or firmware.

OpenMRN provides a basic runtime environment, including a hardware and OS abstraction layer that allows applications to be easily ported between dramatically different platforms (medium to upper-scale microcontrollers, Linux, MacOS, Windows). The abstraction layer mostly operates on POSIX principles, and OpenMRN implements a file interface using file descriptors and read-write-ioctl calls in an MCU environment.

OpenMRN is multi-threaded and uses a combination of collaborative and preemptive multitasking. Threading is part of the OS abstraction layer, which allows threaded application logic to be ported between different operating systems, including running threaded application code on microcontrollers. Current ports use FreeRTOS on MCUs.

License

OpenMRN is open-sourced under a very liberal 2-clause BSD license. This allows you to use OpenMRN in a commercial application, including making changes to it and linking together with other (including proprietary) code under different licenses to form a final product. For details about licensing, please see the LICENSE.txt file and the header comments available in every source file.

Ports

OpenMRN is currently ported to the following hardware and software environments:

  • Linux
  • MacOS
  • Windows using MinGW
  • FreeRTOS with 32-bit MCUs.

The FreeRTOS port is hardware-specific, and currently works on the following hardware:

  • ARM Cortex-M3/M4, Texas Instruments Stellaris/Tiva LM4F120 and TM4C123 (from TI Stellaris/Tiva LaunchPad evaluation kits)
  • ARM Cortex-M3, NXP LPC1768 (from mbed 1768 and LPCXpresso 1768)
  • ARM Cortex-M3, ST Microelectronics's STM32F103 (from LeafLabs Maple and Olimexuino STM32)
  • ARM Cortex-M0, NXP LPC11C24 (from LPCXpresso 11Cxx; limited functionality due to small flash)
  • ARM7TDMI, NXP LPC2368 (from FEZ Panda II)
  • MIPS4K, Microchip's PIC32MX (from Olimex DuinoMite Mega)

Resource requirements

The OpenMRN stack in its current form for a simple node should fit comfortably into microcontrollers with 128 kbytes of flash and 20 kbytes of ram. Under these limits one might need moderate to significant effort in optimizing the compiling and linking process, removing features (for flash space savings), or optimizing the threading usage and runtime buffers (for RAM savings). The smallest MCU that has ever run OpenMRN had 32kB of flash and 8 kB of RAM, but these specs did not fit a standards-compliant stack anymore.

More complex tasks (e.g. a command station) might need more code and data space. For development we also recommend more RAM and flash (for debugging features and to allow not caring for compiler and linker optimizations at initial stages).

No-one has ever tried to port OpenMRN to 16 or 8-bit MCUs.

Status and Features

OS abstraction layer

  • thread creation
  • mutexes (recursive and non-recursive) including __malloc_lock
  • semaphores
  • message queues

FreeRTOS-specific features

  • POSIX device driver model (implementation of open, read, write, ioctl POSIX api)
  • thread-specific allocation of struct reent
  • device drivers for serial ports, CAN-bus ports and USB-serial stack for the completed ports

Utility libraries support

  • allocation of buffers and freelist-handling

  • queuing of buffers, fixed-band priority queues

  • cooperative multitasking scheduler

  • state machines integrated with the cooperative multitasking scheduler

  • asynchronous calls for buffer allocation, queue and freelist management, timeouts, and asynchronous calls into the stack, all integrated with the state machine concept and/or the scheduler.

  • virtual CANbus, GridConnect protocol parsing and decoding, CANbus hub. These features allow OpenMRN to function as CAN-USB adapter, CAN-CAN bridge, or a TCP-based CAN-bus hub out of the box without application logic (and also without the need for an OpenLCB stack).

OpenLCB/NMRAnet support

  • One or more virtual nodes running in one process

  • Loopback interface allows VNodes to talk to each other without bus traffic

  • CANbus interface with unaddressed packets and addressed packets

  • Splitting and assembling addressed messages to/from multiple frames

  • Alias allocation

  • Alias resolution for remote nodes and alias caches

  • Verify Node ID protocol (including verify global)

  • Node initialization complete

  • Event protocol, including event report, event identify, handing event identified replies

  • Global and Addressed Identify All Events

  • Event handler classes for single bit (via two events) producer, consumer, PC; for a block of bits (via 2*block-size consecutive events) producer, consumer, PC; for block of bytes (via bock of 256 consecutive events per byte) PC. No support yet for event teaching/learning.

  • Traction protocol for virtual nodes with set and query speeds, set and query functions; no support yet for reservation commands. No support for traction proxy protocol.

Missing pieces:

  • Currently Datagram protocol is broken (fix planned for v0.9 release), accordingly memory config protocol doesn't work either. Stream protocol support is planned for v1.0.
  • No support yet for protocol identification protocol (PIP) and Simple Node Identification Protocol (SNIP).

DCC support

There are simple utilities for track packet rendering. These can be used with appropriate hardware drivers for implementing command stations. The application developer needs to add value in train database management, update loop management and packet prioritization, train discovery and throttle proxy functions, and the actual timing-sensitive logic for generating the track signal.

  • DCC short and long addresses
  • DCC speed commands (28 and 128 speed steps)
  • DCC function commands for FN1-FN28.
  • Marklin-Motorola packets for MM1 protocol (80 addresses, speed + light, no direction)
  • Marklin-Motorola packets for MM2 protocol (80 addresses, speed + direction + light, FN1-FN4)

Example applications

The OpenMRN source tree contains a few example applications as a starting point for application developers. These are described in more detail on the Applications page.

  • can_usb acts as a GridConnect adapter via virtual serial port. Runs on MCUs with usb and CAN ports.
  • hub act as a GridConnect network interface, listening on a TCP port and forwarding packets between all clients.
  • blink_raw blinks a LED, and can be used for debugging problems with new or existing ports, including crashes in the OS abstraction layer.
  • async_blink brings up an OpenLCB stack on a virtual or physical CANbus, produces events periodically, and listens to the same events to turn a LED on and off. Demonstrates usage of the OpenMRN stack, CAN interfaces, event producers and consumers.