GithubHelp home page GithubHelp logo

bakerstu / openmrn Goto Github PK

View Code? Open in Web Editor NEW
57.0 57.0 28.0 16.54 MB

OpenMRN (Open Model Railroad Network)

License: BSD 2-Clause "Simplified" License

Makefile 3.43% C++ 80.14% Assembly 0.81% C 14.23% Python 0.97% Shell 0.28% HTML 0.01% GDB 0.01% JavaScript 0.05% Awk 0.01% Pawn 0.06% CMake 0.02%

openmrn's People

Contributors

atanisoft avatar bakerstu avatar balazsracz avatar bobjacobsen avatar bosluc avatar dpharris avatar heikens avatar johnfflanagan avatar johnsl avatar kaster14 avatar kennethalong avatar kiwi64ajs avatar myciodan avatar rilull avatar robertpheller avatar smcharg avatar szabodabo avatar toholio avatar trainzluvr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openmrn's Issues

alias map crash in insert() with allocator being full

Seen in production: an assertion failure during the remote alias map insert.
Likely cause is that there was no free entry in the StlMap allocator for the AliasMap class even though there was exactly one entry on the freelist for the metadata list. During the next add the entry was taken from the freelist, but the StlMap allocator (which is a fixed-size allocator) crashed with an std::bad_alloc exception (turning into an assert).

mDNS freezes in the constructor when avahi-daemon is not running

Under linux the constructor of the MDNS class waits on a semaphore, which will get notified from the mdns thread.
If there is an error starting the mdns client (for example because avahi-daemon is not running), the semaphore never gets notified, thus the main thread hangs.

pic32mx: create generic board directory

For other architectures (e.g. tiva) we have a generic board directory which hosts the files shared between different boards based on the same MCU. We should do the same for the PIC32MX.

FreeRTOS NUM_OPEN_FILES

Find a way to configure this option at link time to tailor the footprint to the application.

CC32x Socket Shutdown

Currently, there is a convoluted process to shutdown a CC32x socket. The process needs to be simplifies and documented.

Tiva: recover from CAN bus-off and send out alias acquisition

A developer (@BigBearBrian) reported the issue: if the tiva-based IO board is booted up while the CAN-bus is unplugged, then the board does not recover at a later point even when wiring is OK and valid CAN packets are transferred on the bus.

For recovery we need to check and possibly fix two things (whichever is wrong):

  • the CAN driver works to recover from a bus-off
  • when we exit from bus-off we also call the node reinitialization routine to send out alias acquisition and node init complete messages.

Python tkinter GUI Wrapper on Utilities

Write a Python GUI wrapper for several of the OpenMRN utilities including hub and CDI simulator. A binary distribution can then be created for Linux, MacOS, and Windows, etc...

Duplicate type node_t

openmrn/include/nmranet_types.h:43:15: error: conflicting declaration 'typedef void* node_t'
openmrn/src/freertos_drivers/common/devtab.h:74:3: error: 'node_t' has a previous declaration as 'typedef struct node node_t'

consider publishing pre-built doxygen doc on github pages

GitHub pages might be a good opportunity to publish the generated doxygen documentation. I think it would involve a separate repository on which to enable github pages and some Makefile magic for updating it.
Updating would be a manual task.

thoughts?

add new base class for callable state flows

We have a bunch of state flows that can be run using invoke_and_wait().
These have a bunch of code duplication, including helper functions like return_ok() etc.

code duplication leads to incinsistency, such as the same function being called input() in one flow, request() in the other and message()->data() in the third.

We should unify these and establish a new base class similar to StateFlow that removes this code duplication.

Leaking file descriptors

in fileio.c the implementation of open() can realize when there is not such file and report an appropriate error.
However, at the time of reporting the error, the fd is not released for further use.

It seems that the current freertos port relies on the fact of this fd leaking by allocating fd 0,1 and 2 without checking the return value.

I'm adding an explicit note about the leaked file descriptor and make sure that nulldevice is attached.

CC3220 SL_NETAPP_EVENT_IP_COLLISION

This event is presently unhandled. It is to indicate that an IP collision has occurred. I am getting this event whenever I am running in AP mode and have a connected STA that is requesting more than a single AP (for example, it has a bridge behind it).

I'm not sure if the CC3220 supports assigning more than one IP per connected station. I need to investigate this further.

For the average user, this is not a common use case. However, for me personally, this is a very common use case.

Usability problem with events API

There are two calls with the same prototype and the name just differing in one character:
void nmranet_event_producer(node_t node, uint64_t event, unsigned int state);
void nmranet_event_produce(node_t node, uint64_t event, unsigned int state);

But there is a major difference in where and how to use them. This very easily leads to bugs on the application side.

I recommend renaming the former call to
register_nmranet_event_producer(...)
and similarly the register consumer call for consistency (although there the API confusion does not hold).

pic32mx: CAN driver portability

The CAN driver in PIC32MX is not very portable across different chips.
It is using macro defines like INT_CAN2 that are only defined for certain processors.
We need to make all of those be conditionally compiled for processors that actually have two CAN controllers.

too long datagrams causes assertion failure

in the below scenario two OpenMRN nodes were talking to each other via CANbus. Node A tried to send a too long datagram to node B. (Actually several of them.) This was rejected by node B with permanent error. Something in this process caused node A to crash.

here is a stack trace of a crash:
#0 0x00020314 in resetblink (pattern=2147536074)

at /home/bracz/train/openlcb/openmrn/boards/ti-bracz-cs-connected/HwInit.cxx:139

#1 diewith (pattern=pattern@entry=2147536074)

at /home/bracz/train/openlcb/openmrn/boards/ti-bracz-cs-connected/HwInit.cxx:168

#2 0x0001fe28 in abort () at /usr/local/google/home/bracz/train/openlcb/openmrn/src/os/os.c:553
#3 0x0000e5f6 in Timer::trigger (this=)

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/Timer.hxx:208

#4 0x00014df0 in nmranet::CanDatagramClient::handle_response (this=0x200042f0, message=message@entry=0x200169e8)

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/nmranet/DatagramCan.cxx:348

#5 0x00014c26 in nmranet::CanDatagramClient::ReplyListener::send (this=, buffer=0x200169d8,

priority=<optimized out>) at /usr/local/google/home/bracz/train/openlcb/openmrn/src/nmranet/DatagramCan.cxx:233

#6 0x00005a84 in DispatchFlow<Buffernmranet::NMRAnetMessage, 4>::send_transfer (this=)

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/Dispatcher.hxx:244

#7 0x0000a8e0 in DispatchFlowBase<4>::iteration_done (this=0x20001670 <stack+368>)

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/Dispatcher.hxx:400

#8 0x000071e0 in StateFlowBase::run (this=0x20001670 <stack+368>)

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/StateFlow.cxx:82

#9 0x00005de6 in ExecutorBase::entry (this=this@entry=0x20001500 )

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/Executor.cxx:220

#10 0x000201c0 in thread_body (this=0x20001500 )

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/executor/Executor.hxx:284

#11 loop_executor (this=0x20001500 )

at /usr/local/google/home/bracz/train/openlcb/openmrn/src/nmranet/SimpleStack.hxx:230

#12 appl_main (argc=argc@entry=1, argv=argv@entry=0x20006e90)

at /usr/local/google/home/bracz/train/openlcb/private_openmrn/cs/targets/cs.tiva/main.cxx:482

#13 0x00020d9e in main_thread (arg=) at /usr/local/google/home/bracz/train/openlcb/openmrn/src/os/os.c:650

and the CAN-bus trace:

:X1B6F9C95NF2245261696C636F;
:X1C6F9C95N6D20302043483120;
:X1C6F9C95N6461746128353336;
:X1C6F9C95N383735303936293A;
:X1C6F9C95N2030783939202830;
:X1C6F9C95N783038292C203078;
:X1C6F9C95N6135202830783033;
:X1C6F9C95N292C206164726C6F;
:X1D6F9C95N773D33;
:X19A286F9N0C9500;
:X1B6F9C95NF2245261696C636F;
:X1C6F9C95N6D20302043483220;
:X1C6F9C95N6461746128353336;
:X1C6F9C95N383735303936293A;
:X1C6F9C95N2030786163202830;
:X1C6F9C95N783030292C203078;
:X1C6F9C95N6163202830783030;
:X1C6F9C95N292C203078306620;
:X1C6F9C95N2830786664292C20;
:X1C6F9C95N3078306620283078;
:X19A486F9N0C951000;
:X1C6F9C95N6664292C20307830;
:X19A486F9N0C952040;
:X1C6F9C95N6620283078666429;
:X19A486F9N0C952040;
:X1C6F9C95N2C20307830662028;
:X19A486F9N0C952040;
:X1D6F9C95N30786664292C20;
:X19A486F9N0C952040;
:X1B6F9C95NF2245261696C636F;
:X1C6F9C95N6D20302043483120;
:X1C6F9C95N6461746128353336;
:X1C6F9C95N383735303936293A;
:X1C6F9C95N2030783231202830;
:X1D6F9C95N786666292C20;
:X19A286F9N0C9500;
:X1B6F9C95NF2245261696C636F;
:X1C6F9C95N6D20302043483220;
:X1C6F9C95N6461746128353336;
:X1C6F9C95N383735303936293A;
:X1C6F9C95N2030783662202830;
:X1C6F9C95N786666292C203078;
:X1C6F9C95N6538202830783236;
:X1C6F9C95N292C203078653820;
:X1C6F9C95N2830783236292C20;
:X1C6F9C95N3078653820283078;
:X19A486F9N0C951000;
:X1C6F9C95N3236292C20307866;
:X19A486F9N0C952040;
:X1C6F9C95N3820283078666629;
:X19A486F9N0C952040;
:X1D6F9C95N2C20;
:X19A486F9N0C952040;

this contains the last successful datagram sent and then a few failures before the crash.

Obvious workaround is to not send too long datagrams (e.g. reject them at the outgoing stage) but a crash should not happen nevertheless.

pic32mx: check if ISRwrapper is needed

I'm wondering if the extra save & restore code that we have in ISRwrapper.inc is actually necessary for the PIC32MX.
We seem to only use this for two core FreeRTOS interrupts, which should be coded in assembly and correctly saving and restoring task context anyway.
The rest of the interrupts are declared in GCC with attribute((interrupt)) which should have the necessary preamble anyway.

deadlock producing events from timer

I wrote a small piece of code that polls a GPIO pin from a recurring timer, and does nmranet_event_produce if it sees some changes.

This code deadlocked upon initialization. The deadlock occurred on nodeMutex.

The mutex holder was thread.main with the following stacktrace:
#0 sleep (seconds=seconds@entry=1) at ../../..//src/os/os.c:732
#1 0x00001858 in upstream_alias_setup (node_id=11936128518282651045, can_if=0x8002ccca)

at ../../..//src/if/nmranet_can_if.c:436

#2 can_write (nmranet_if=0x8002ccca, mti=, src=, dst=..., data=0x1000563c)

at ../../..//src/if/nmranet_can_if.c:496

#3 0x00004262 in nmranet_node_write (node=node@entry=0x10004ff0, mti=mti@entry=368, dst=..., data=data@entry=0x1000563c)

at ../../..//src/core/nmranet_node.c:555

#4 0x0000432c in verify_node_id_number (node=node@entry=0x10004ff0) at ../../..//src/core/nmranet_node.c:293
#5 0x00004788 in nmranet_node_initialized (node=0x10004ff0) at ../../..//src/core/nmranet_node.c:181
#6 0x0000036c in appl_main (argc=argc@entry=1, argv=argv@entry=0x200809f8) at ../../main.cxx:300
#7 0x00004832 in main_thread (arg=) at ../../..//src/os/os.c:837

And the timer Svc deadlocked with the following stacktrace:
#0 0x00005436 in xQueueGenericReceive (xQueue=0x8002ccca, xQueue@entry=0x10004fa0, pvBuffer=0xa5a5a5a5,

pvBuffer@entry=0x0, xTicksToWait=xTicksToWait@entry=4294967295, xJustPeeking=-1515870811, xJustPeeking@entry=0)
at /home/bracz/FreeRTOS/Source/queue.c:1146

#1 0x0000548a in xQueueTakeMutexRecursive (xMutex=0x10004fa0, xBlockTime=xBlockTime@entry=4294967295)

at /home/bracz/FreeRTOS/Source/queue.c:508

#2 0x000036ec in os_mutex_lock (mutex=0x1000014c) at ../../..//src/os/os.h:383
#3 os_mutex_lock (mutex=0x1000014c) at ../../..//src/os/os.h:364
#4 0x00003a54 in nmranet_event_produce (node=0x10004ff0, event=, state=0)

at ../../..//src/core/nmranet_event.c:294

#5 0x00000502 in MemoryBitProducer::PerformUpdate (this=0x20080980)

at ../../src/common_event_handlers.hxx:145

#6 0x000005cc in TimerUpdater::callback (object=) at ../../src/timer_updater.hxx:27
#7 0x000048a4 in timer_callback (timer=0x100055b0) at ../../..//src/os/os.c:164
#8 0x00006240 in prvProcessExpiredTimer (xTimeNow=200, xNextExpireTime=200) at /home/bracz/FreeRTOS/Source/timers.c:347
#9 prvProcessTimerOrBlockTask (xListWasEmpty=, xNextExpireTime=200)

at /home/bracz/FreeRTOS/Source/timers.c:394

#10 prvTimerTask (pvParameters=) at /home/bracz/FreeRTOS/Source/timers.c:367

after a few seconds my watchdog kills the process.

I don't understand the specific details of the alias setup routine, but I guess that the timer svc being blocked on a mutex probably means that the nmranet alias setup process will never terminate and thus will never release the nodeMutex.

FreeRTOS tasks crash at first timeslice

In the freertos port the TaskApplicationTag is used to swap in and out the struct _reent pointer. There is code at the end of FreeRTOSConfig.h that runs inside the kernel scheduler; whenever a task is swapped in, it looks up the applicaiton task tag, takes it as a struct pointer and looks up the _reent pointer in that struct.

However, the application task tag is first set when the thread is actually running; in the stubs os_thread_start and main_thread, before the application code gets to run.

This means that at the first time the task gets a timeslice, it will be swapped in with a zero task tag, so there will be a null-pointer dereference.

Luckily enough, you can dereference a nullptr on the ARM chips we used so far, because it just points to the interrupt vector table. In other architectures however, this will lead to a deterministic crash when starting any task.

Fix is trivial, I will commit it.

Incorrect NMRAnetNode.hxx, NMRAnetMessageID.hxx, NMRAnetIf.hxx in Stream.[hc]xx

Hi,

There are still three includes that reference obsoleted files. In openlcb/Stream.cxx openlcb/Stream.hxx you can still find the following:

`
$ grep -n NMRAnet src/openlcb/* | grep include

src/openlcb/Stream.cxx:35:#include "openlcb/NMRAnetNode.hxx"

src/openlcb/Stream.cxx:36:#include "openlcb/NMRAnetMessageID.hxx"

src/openlcb/Stream.hxx:37:#include "openlcb/NMRAnetIf.hxx"

`
These files are missing from the repo since 2014 at commits:

316e43f08

race condition at task exit causing crashes

In FreeRTOS:
there is a race condition between the task existing, and it unlinking the taskList entry and deleting it, and the IDLE thread iterating through the task list. It is possible that the iteration is on the deleted task, causing the linked list traversal to venture off into freed memory.

hub: connect via mDNS

there should be a way to connect from the hub application to an upstream hub via mDNS service address.

sl_Recv() results in unhandled SL_ERROR_BSD_EBADF

This issue occurs when a socket in a blocking receive is asynchronously closed in another thread. It was observed when using the hub. The socket is closed on the writer flow at the same time the read thread is in a blocking receive.

I'm still investigating the proper POSIX behavior and whether a change to the hub implementation is needed. Most of my past experience is single threaded with select().

Verify Node ID Global with Node ID Payload

The Verify Node ID Global message (as described in the Message Network S & TN) is allowed to contain a Node ID in the payload of the message. If the Node ID is present, only a node with a matching Node ID is supposed to respond. It looks as though in our case, all of our nodes respond regardless as to whether the Node ID is present. The Node ID payload does not appear to be validated in OpenMRN.

I've verified that the RailStars and RR-CirKits nodes do not have this issue.

Here is the Python test trace:

   connect to  localhost : 12021
   send    :X19490AAAN020199FF001E;
   receive :X191705F9N020199FF001E;
   send    :X19490AAAN;
   receive :X19170149N02015700003E;
   receive :X19170060N050201020211;
   receive :X19170065N050201020214;
   receive :X191705F9N020199FF001E;
   send    :X19490AAAN000000000001;
   receive :X191702A8N060100000002;
Global verify with wrong node ID should not receive reply but did:  :X19170149N02015700003E;

Possibly revisit threading model

I have been trying to add various features to OpenMRN and I am repeatedly running into issues around the threading model. It basically boils down to needing to start a large number of threads.

Examples:

  1. If I were to have multiple virtual nodes, I would need a separate processing thread for each of them.

  2. Every physical device needs its own reading thread. can0, can1, uart, usbserial, just to name a few.
    Device driver writing is rather complicated in order to avoid needing a separate TX thread, but it seems that can be done.

3a) Every virtual device will need a thread of its own.
For example if I create a pipe (a virtual loopback device) for exposing a /dev/stdout to the program that takes the characters written there [use-case: debug] and sends them off through some physical device (my candidate would be usb-serial, but a CAN-based logger would do as well).

3b) other example for virtual devices is the virtual CAN devices.
Let's take the example that we want to connect multiple independent functions of code to the same CAN device. Each function needs to process all CAN packets that come in through the physical link, and any packet generated by any virtual node will need to be sent to all other virtual nodes as well as the physical link.
The use-case for this is to create a CAN-USB implementation that lives in the OpenMRN node but looks like a gridconnect interface to the host.
Another example is that I have a piece of code that drives a CANbus-connected throttle that speaks a legacy protocol. This would need to be running on a virtual device, since OpenMRN does not expose an API to the application for processing unknown CAN packets.
Such a virtual CAN device could be implemented very nicely using the file abstraction. However, that would need for N virtual devices an additional N threads (next to the already existing N threads that the various components are running in order to read).

So it seems to me that a set of functionality that I had previously packed into a 8-bit PIC with 4K of RAM (quite comfortably) suddenly needs something like 15 threads running.

auto-detect OPENMRNPATH

In general when someone starts a make from somewhere inside the openmrn directory, we should know exactly where we are and be able to deduce the root directory of openmrn from there.

This is in general achieved the following way:

  • for a Makefile in an application target directory we do
-include ../../config.mk

and delegate the responsibility to find the OPENMRNPATH.

  • for a config.mk in the application/XXX directory we can do the following:

    • if OPENMRNPATH is set, use it
    • do a -include openmrnpath.mk which allows someone to add a file called "openmrnpath.mk" without checking into git to set the proper path.
    • set OPENMRNPATH ?= $(realpath ../..)

    This strategy is represented by default_config.mk in the applications directory.

There are two TODO items here:

  • Ensure that we have full coverage. (I added a bunch of these by hand, but apparently some were missed).
  • We should extend this strategy to cover every directory in which we have a Makefile. Probably the intermediate directories in our tree should have something like
OPENMRNPATH ?= $(realpath ../../..)

at the beginning of their Makefile, with the appropriate number of ..

Event state handling: state of consumed events is not updated; states can get out of sync.

There is a provision in the event codebase for keeping the state of produced and consumed events.

This state is initialized during the call to
nmranet_event_consumer(node, 0x05020102a8650012ULL, EVENT_STATE_INVALID);
nmranet_event_producer(node, 0x0502010202000000ULL, EVENT_STATE_INVALID);

The state is sent out in response to producer_identify and consumer_identify commands.

For events produced, the produce call will update the state as it is remembered in the node's events_produced list.

There are a bunch of problems however:

  1. For events consumed, the initial state is never changed in the program. This means that with whatever initial state an event was entered, that state will be sent out to the bus every time a consumer_identify message is sent.

  2. Also if a node both produces and consumes an event, the states can get out of sync.

  3. If there are multiple virtual nodes, the produced and consumed states of the same event can be arbitrarily out of sync there.

  4. There is no user-facing API to query the last state of events.

  5. There should be an API to set the state of consumed events, too. For example if there is a pair of events setting/clearing a bit, that should be possible to be reflected in the internal states of OpenMRN.

  6. I think the linear search for eventIDs that are assigned to virtual nodes could turn into a problem of efficiency in the case there is a larger number of events being listened to.
    For example I am planning to create cue nodes which will be listening to hundreds of events.

replace _NMRANET_ in include guards

Wereplaced the namespace and the directory name from nmranet to openlcb.
We need to clean up the #ifndef include guards and replace those with OPENLCB as well.

Add support for compiling for the host

We should have an etc/host_cc.mk that defines a bunch of variables helping to compile for the host (instead of any specific target).

We need host compilation in two cases today:

  • compiling and running the tests (the targets/cov which is a special target)
  • creating the compile_cdi binary from config.hxx that dumps the cdi.xml.

ideally the host_cc.mk should expose things like HOST_CC, HOST_CXX, HOST_CXXINCLUDES or something the like. It should operate on both linux and macos. (Of particular interest is the necessary include for for endian.h for the macos).

remove type IncomingDatagram

this type should be replaced by the standard NmraNetMessage, which is already used by the outgoing datagram senders.
There is no reason why the incoming and outgoing datagram should have different type; furthermore, having them the same type would allow a datagram hander to "turn around" the incoming datagram buffer and send it straight back as a response datagram.

Auto reboot on crash

Today when the openmrn stack crashes, it stops forever in the crash handler, blinking according to various patterns.

For production purposes this is not good; we need to get back to a working situation as soon as possible; this may involve rebooting the MCU.

Global identify events will cause packet loss

The current implementation of global identify events is as follows:

  • the event packet is picked up by the CANbus RX thread.
  • it ends up in nmranet_if_rx_data
  • which calls nmranet_event_packet_global
  • that iterates over all virtual nodes and calls nmranet_event_packet_addressed on it
  • each node in turn will traverse its event list
  • and generate an identify message for each of them
  • which will be put into the tx queue
  • the TX queue will not be processed due to the likely packet collisions on the bus
  • the TX queue will get full and the next write will block the RX thread
  • while there are lots of incoming packets coming from the network from other nodes
  • eventually overflowing the RX queue.

The first of those incoming packets will be processed only once all the event identify packets have been enqueued into the TX queue.

need to cache off-bus remote nodes

The addressed message send flow has a bunch of internal stages that look up aliases for remote nodes that are not in the remote alias cache.
For remote nodes that are not replying (ie., they are off bus) there are timeouts in this flow. When the timeout is reached the message gets dropped to the floor.
It takes quite a while though (1-3 seconds), and during that time the flow is not available for sending other addressed messages. A burst or a continuous stream of addressed messages to such dead nodes can "clog the line" in that no other addressed messages can effectively be sent to the bus since the flow is busy. The messages get enqueued and will eventually be sent, but the delay is unpredictable and could be very long (minutes).

We need to enter into the remote alias cache when the remote node is unresponsive and there is no alias on the record. This will allow us to drop those messages very quickly. When the unknown node comes back online, we will ideally know that from the alias AMD frame. Any further addressed message can then be delivered directly.

Event Identify Range not produced on Identify Events Global

Global:

   connect to  localhost : 12021
   send    :X19970AAAN;
   receive :X19547065N0502010202140010;
   receive :X19547060N0502010202000000;
   receive :X19547060N0502010202000001;
   receive :X19547060N0502010202000002;
   receive :X19547060N0502010202000003;
   receive :X19547060N0502010202000004;
   receive :X195472A8N0101000000000303;
   receive :X19547060N0502010202000005;
   receive :X19547060N0502010202000006;
   receive :X19547060N0502010202000007;
   receive :X19547060N0502010202000008;
   receive :X19547060N0502010202000009;
   receive :X19547060N050201020200000A;
   receive :X19547060N050201020200000B;
   receive :X19547F57N0101000000000303;
   receive :X19547060N050201020200000C;
   receive :X19547060N050201020200000D;
   receive :X19547060N050201020200000E;
   receive :X19547060N050201020200000F;
   receive :X194C7060N0502010202000000;
   receive :X194C7060N0502010202000001;
   receive :X194C7060N0502010202000002;
   receive :X19547C06N0101000000000303;
   receive :X194C7060N0502010202000003;
   receive :X194C7060N0502010202000004;
   receive :X194C7060N0502010202000005;
   receive :X194C7060N0502010202000006;
   receive :X194C7060N0502010202000007;
   receive :X194C7060N0502010202000008;
   receive :X194C7060N0502010202000009;
   receive :X194C55F9N010000000000FFFE;
   receive :X194C45F9N010000000000FFFF;
   receive :X194C7060N050201020200000A;
   receive :X194C7060N050201020200000B;
   receive :X194C7060N050201020200000C;
   receive :X195B45F9N0502010202000000;
   receive :X194C7060N050201020200000D;
   receive :X194C7060N0201570000400006;
   receive :X194C7060N0201570000400007;
   receive :X19547065N0502010202140011;
   receive :X195445F9N010000000000FFFF;
   receive :X195455F9N010000000000FFFE;
   receive :X194C45F9N010000000000FFFF;
   receive :X194C55F9N010000000000FFFE;
   receive :X19547065N0502010202140012;
   receive :X19547065N0502010202140013;
   receive :X19547065N0502010202140014;
   receive :X19547065N0502010202140015;
   receive :X19547065N0502010202140016;
   receive :X19547065N0502010202140017;
   receive :X19547065N0502010202140018;
   receive :X195445F9N0502010202000000;
   receive :X195455F9N0502010202000001;
   receive :X19547065N0502010202140019;
   receive :X19547065N050201020214001A;
   receive :X19547065N050201020214001B;
   receive :X19547065N050201020214001C;
   receive :X19547065N050201020214001D;
   receive :X19547065N050201020214001E;
   receive :X19547065N050201020214001F;
   receive :X194C7065N0201570000400006;
   receive :X194C7065N0201570000400012;
   receive :X195242A8N090099FF00000000;
   receive :X194C7065N0502010202140022;
   receive :X194C7065N0502010202140023;
   receive :X194C7065N0502010202140024;
   receive :X19524F57N090099FF00000000;
   receive :X194C7065N0502010202140025;
   receive :X194C7065N0502010202140026;
   receive :X194C7065N0502010202140027;
   receive :X19524C06N090099FF00000000;
   receive :X194C7065N0502010202140028;
   receive :X194C7065N0502010202140029;
   receive :X194C7065N050201020214002A;
   receive :X194C7065N050201020214002B;
   receive :X194C7065N050201020214002C;
   receive :X194C7065N050201020214002D;
   receive :X194C7065N050201020214002E;
   receive :X194C7065N050201020214002F;
   receive :X19547149N02015700003E0006;
   receive :X19547149N02015700003E0007;
   receive :X19547149N02015700003E0012;
   receive :X19547149N02015700003E0013;
   receive :X19547149N02015700003E001E;
   receive :X19547149N02015700003E001F;
   receive :X19547149N02015700003E002A;
   receive :X19547149N02015700003E002B;
   receive :X19547149N02015700003E0036;
   receive :X19547149N02015700003E0037;
   receive :X19547149N02015700003E0042;
   receive :X19547149N02015700003E0043;
   receive :X19547149N02015700003E004E;
   receive :X19547149N02015700003E004F;
   receive :X19547149N02015700003E005A;
   receive :X19547149N02015700003E005B;
   receive :X19547149N02015700003E0066;
   receive :X19547149N02015700003E0067;
   receive :X19547149N02015700003E0072;
   receive :X19547149N02015700003E0073;
   receive :X19547149N02015700003E007E;
   receive :X19547149N02015700003E007F;
   receive :X19547149N02015700003E008A;
   receive :X19547149N02015700003E008B;
   receive :X19547149N02015700003E0096;
   receive :X19547149N02015700003E0097;
   receive :X19547149N02015700003E00A2;
   receive :X19547149N02015700003E00A3;
   receive :X19547149N02015700003E00AE;
   receive :X19547149N02015700003E00AF;
   receive :X19547149N02015700003E00BA;
   receive :X19547149N02015700003E00BB;
   receive :X195B45F9N0502010202000001;
<none>
Timeout
  Found 4 consumer events
  Found 4 producer events

Addressed:

   connect to  localhost : 12021
   send    :X19968AAAN05F9;
   receive :X194C55F9N010000000000FFFE;
   receive :X194C45F9N010000000000FFFF;
   receive :X195445F9N010000000000FFFF;
   receive :X195455F9N010000000000FFFE;
   receive :X194C45F9N010000000000FFFF;
   receive :X194C55F9N010000000000FFFE;
   receive :X195445F9N0502010202000000;
   receive :X195455F9N0502010202000001;
   receive :X194A45F9N090099FF00000000;
   receive :X195B45F9N0502010202000001;
<none>
Timeout
  Found 4 consumer events
  Found 4 producer events
  Found Consumer Range 90099ff00000000 - 90099ffffffffff

set search order consistently in etc/path.mk

The search order specified for directories in etc/path.mk is inconsistent. Some searches have $(HOME)..... as a first entry, while others have it last. When used $(HOME) should have the highest precedence which would allow the user to provide a local override for any default system directory.

for example:

################ tivaware ##################
ifndef TIVAWAREPATH
SEARCHPATH := \
  /opt/ti/TivaWare/default \
  /opt/TivaWare/default \
  /opt/TivaWare \
  $(HOME)/TivaWare

should be

################ tivaware ##################
ifndef TIVAWAREPATH
SEARCHPATH := \
  $(HOME)/TivaWare \
  /opt/ti/TivaWare/default \
  /opt/TivaWare/default \
  /opt/TivaWare

EEPROM Emulation not building in LPC40xx targets

/home/openmrn/openmrn/targets/freertos.armv7m/lib/libfreertos_drivers.a(EEPROMEmulation.o): In function EEPROMEmulation::EEPROMEmulation(char const*, unsigned int)': /home/openmrn/openmrn/src/freertos_drivers/common/EEPROMEmulation.cxx:59: undefined reference to EEPROMEmulation::SECTOR_SIZE'
/home/openmrn/openmrn/targets/freertos.armv7m/lib/libfreertos_drivers_lpc_chip_175x_6x.a(Lpc17xx40xxEEPROMEmulation.o): In function LpcEEPROMEmulation::flash_program(unsigned int, unsigned int, unsigned long*, unsigned long)': /home/openmrn/openmrn/src/freertos_drivers/nxp/Lpc17xx40xxEEPROMEmulation.cxx:144: undefined reference to EEPROMEmulation::SECTOR_SIZE'
/home/openmrn/openmrn/targets/freertos.armv7m/lib/libfreertos_drivers_lpc_chip_175x_6x.a(Lpc17xx40xxEEPROMEmulation.o): In function LpcEEPROMEmulation::block(unsigned int, unsigned int)': /home/openmrn/openmrn/src/freertos_drivers/nxp/Lpc17xx40xxEEPROMEmulation.cxx:98: undefined reference to EEPROMEmulation::SECTOR_SIZE'
/home/openmrn/openmrn/targets/freertos.armv7m/lib/libfreertos_drivers_lpc_chip_175x_6x.a(Lpc17xx40xxEEPROMEmulation.o): In function LpcEEPROMEmulation::LpcEEPROMEmulation(char const*, unsigned int)': /home/openmrn/openmrn/src/freertos_drivers/nxp/Lpc17xx40xxEEPROMEmulation.cxx:82: undefined reference to EEPROMEmulation::SECTOR_SIZE'
collect2: error: ld returned 1 exit status
make[4]: *** [async_blink.elf] Error 1
make[4]: Leaving directory /home/openmrn/openmrn/applications/async_blink/targets/freertos.armv7m.lpc1769-lpcxpresso' make[3]: *** [build-freertos.armv7m.lpc1769-lpcxpresso] Error 2 make[3]: Leaving directory /home/openmrn/openmrn/applications/async_blink/targets'
make[2]: *** [build-targets] Error 2
make[2]: Leaving directory /home/openmrn/openmrn/applications/async_blink' make[1]: *** [build-async_blink] Error 2 make[1]: Leaving directory /home/openmrn/openmrn/applications'
make: *** [build-applications] Error 2

xTaskGetApplicationTaskTag used in service handler context

In FreeRTOSConfig.h there is the following code that handles switching the newlib reentrancy structure for the current thread:

define traceTASK_SWITCHED_IN() \

{
TaskSwitchedIn task_switched_in;
task_switched_in = (TaskSwitchedIn
)xTaskGetApplicationTaskTag(NULL);
_impure_ptr = task_switched_in->reent;
}

The quoted macro gets called from a service handler context, during yield and the system tick IRQ.

However, it seems to me that at least on the LPC23xx port of FreeRTOS it is not safe to call xTaskGetApplicationTaskTag from a service handler context. The reason is that internally it uses a critical section, and at the exit of that critical section (since critical nesting seems to be zero in a service handler context) the IRQ_enable bits are reset. This allows interrupts during the service context which leads to various forms of corruption.

Should we rename nmranet in the codebase?

The name 'nmranet' was sunset two years ago by the NMRA.

We have extensive occurrences in our codebase -- a directory 'nmranet', a namespace 'nmranet' and the core buffer type called NMRANetMessage.

Should we rename these? If yes, rename to what? Reasonable options are:

  • LCC
  • OpenLCB

This is probably a massive undertaking that has to span multiple repositories in one go.

[please add your comments to this issue thread]

Rename style-incompliant virtual methods in the event handlers

The event service has a bunch of style-incompliant method names, e.g.
the Bit class has SetState() and GetState()
as well as the EventHandler object has all the event handler functions incorrectly named.

These names are virtual and need to be renamed in a single change which will span across repositories, and thus takes a single large effort.

better Makefile support for generated cdi.xml

In the io_board Makefiles we use a generated cdi file. It's called cdi.nxml and there are custom commands to link it into the binary.

Two TODO items here:

  • the name should change: cdi.nxml is the wrong name, it should be cdi.xmlout
  • we should probably have first-class support in prog.mk for generating the CDI so that the application target directory does not need a customized Makefile.

Add OpenOCD command to STM32F072-Discovery board Makefile for FLASHing

Looking at one of the Tiva boards as a reference, enhance the board Makefile to add a make target for downloading code. The OpenOCD command will be something like:

"openocd --file /usr/share/openocd/scripts/board/stm32f0discovery.cfg"

...to start the GDB Server. Consideration must be given to multi OS host support.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.