Skip to content
This repository has been archived by the owner on Sep 1, 2022. It is now read-only.

Lib for Arduino #189

Closed
ricardolima91 opened this issue Jan 9, 2017 · 17 comments
Closed

Lib for Arduino #189

ricardolima91 opened this issue Jan 9, 2017 · 17 comments

Comments

@ricardolima91
Copy link

Where is the lib for Arduino ? In the past I know it exist, but now don't appear in any place in repo. Any reason ? Thank you

@jadamcrain
Copy link
Member

I don't maintain it anymore.

If you want to play around with it, it still exists at the 2.0.1 tag:

https://github.com/automatak/dnp3/tree/2.0.1/embedded

@ricardolima91
Copy link
Author

ricardolima91 commented Jan 9, 2017 via email

@jadamcrain
Copy link
Member

The toolchain used is Atmel Studio:

http://www.atmel.com/Microsite/atmel-studio/

Yes, it's based on the Visual Studio user interface.

There is no precompiled version.

@ricardolima91
Copy link
Author

ricardolima91 commented Jan 10, 2017 via email

@emgre
Copy link
Member

emgre commented Jan 12, 2017

I compiled OpenDNP3 for the Texas Instruments MSP432 a few times ago, and it was fairly straightforward. The tag pointed by Mr. Crain is a good starting point. If I remember correctly, a few classes have changed, but it's easy to find your way trough it.

However, I would recommend you using the GCC based compiler provided by TI (available here: http://www.ti.com/tool/MSP430-GCC-OPENSOURCE ). I tried using TI's proprietary compiler, but I had a few issues and couldn't achieve it.

Also, note that the resulting code takes a fair bit of space. On the MSP432 Launchpad, with 256KB, I had to use all -Os to have all my code fit into the memory (I had other libraries as well).

Please note that my program wasn't doing much and barely interacted with OpenDNP3. It was more of a test of FreeRTOS then OpenDNP3 actually... But still, it is feasible.

@ricardolima91
Copy link
Author

Hi Emgre, Thanks for your answer. I'am new at this kind of thing, The msp430 GCC only works with command line right? I'am not finding the correct way to work with this(http://www.ti.com/lit/ug/slau646b/slau646b.pdf checking this info). Do you can create a repo with that info ? Can be useful to more people :) Thanks for you help

@emgre
Copy link
Member

emgre commented Jan 13, 2017

The GCC compiler can be used Inside TI Code Composer Studio (the Eclipse-based IDE). It's simply a matter of selecting the right compiler when you create the project.

The code that I worked on is on my old laptop hard drive, since it was merely a test. I'll try to reinstall it on my laptop this weekend, but I can't promise you that I'll have time.

@ricardolima91
Copy link
Author

Thanks for your precious help. I will wait.
I'am also trying to see how it works on arduino (MEGA) and in atmel studio when I send it to arduino it is giving me this error(I create a external tool to send it to arduino MEGA)

avrdude.exe: Device signature = 0x1e9801 (probably m2560)
avrdude.exe: reading input file "C:\Users\IEUser\Downloads\dnp3-2.0.1\dnp3-2.0.1\embedded\atmelavr\openpal\Debug\libopenpal.hex"
avrdude.exe: can't open input file C:\Users\IEUser\Downloads\dnp3-2.0.1\dnp3-2.0.1\embedded\atmelavr\openpal\Debug\libopenpal.hex: No such file or directory
avrdude.exe: read from file 'C:\Users\IEUser\Downloads\dnp3-2.0.1\dnp3-2.0.1\embedded\atmelavr\openpal\Debug\libopenpal.hex' failed

Any ideia ? thank you

@jadamcrain
Copy link
Member

@emgre Very cool to know you got things going with the TI toolchain.

@ricardolima91 I did get things running on the AtMega2650, but you may have to tweak the solution file b/c of hardcoded paths, etc. It's just not something I can support.

The problem you're going to run into on the Mega is SRAM. It only has 8KB and I had to dial back all the buffer sizes to make it run... Even then, it barely fit and without profiling you run the risk of stack/heap collisions. I would't recommend even attempting a port onto anything with less than 16KB. Flash was not a problem. If I recall it used ~128 of 256kb leaving plenty of space for an application. Perhaps not so much if you also have to fit in an RTOS :(.

In general, the 2.0.x has migrated away from supporting MCUs easily. Certain C++ types like unique_ptr / and std::function<void ()> have creep-ed into the code, although you could easily write your own simplified definitions for these.

-Adam

@emgre
Copy link
Member

emgre commented Jan 17, 2017

I found my original code, but it was based on an earlier version of OpenDNP3 and it was full of not related stuff, so I decided to create a new project from the beginning.

I have something that compiles, but at runtime, it stops at OutstationContext.cpp:299, and by looking trough the debugger, it seems that StateIdle::instance (in OutstationStates.cpp) is not initialized properly (the _vptr are set to 0x00). My guess is that some optimisations discard this static variable (and its cousins). However, I can't slack the optimisations, otherwise the code won't fit on the Flash. I'm using GCC (arm-none-eabi) with -Os -ffunction-sections -fdata-sections (with the corresponding -Wl,--gc-sections on the linker) to reduce the size as much as I can.

By the way, the latest version is definitely harder for MCUs, especially with the unique_ptr/shared_ptr a bit everywhere that forces the creation on the heap, instead of the stack.

The code is available here : https://github.com/emgre/opendnp3msp432

Émile Grégoire

@ricardolima91
Copy link
Author

Thank you so much Émile Grégoire for sharing your code. I will explore that info :) i'am new at this but I will try.
Thank you also Adam.

@jadamcrain
Copy link
Member

@emgre Interesting about the static initializers. I've seen some embedded toolchains (the esp8266 C++ compiler) that didn't call static initializers prior to invoking main(). Perhaps this is the cause?

I'm probably going to make those flyweights initialize lazily in the getters since this requires less code. I wonder how the embedded toolchain treats each method of initialization....

@emgre
Copy link
Member

emgre commented Jan 23, 2017

@jadamcrain I fixed the issue with the static initializers and a whole bunch of other issues. I pretty simply had to call the _mainCRTstartup symbol generated by GCC to initialize the static variables. It does all the boilerplate (setting the SP, zeroing the BSS, initializing the static variables), but it doesn't copy the .data segment for an unknown reason. Anymay, I wrote the little loop myself and now it's working.

There was also an issue from TI's default linker script where the stack pointer would point to the wrong end of the stack, making it overlapping the heap, then the BSS. That was a nice challenge to find. Also, the _init symbol would get optimized out unless we explicitely tell the linker script to not do so (but that's my fault... I think...)

I have the MSP432 sending the first unsollicited null response succesfully. I just need to fix the Executor so that the MSP432 keep talking to the master. I haven't pushed anything yet on the repo, I want to have a working code. I hope to have time to finish it this week, but university is draining my time.

By the way, doing this is a nice academic lesson on the ARM architecture and on code generation. I had great fun debugging that stuff.

Émile

@jadamcrain
Copy link
Member

That's awesome. Sounds a lot like my experience on the Atmel SAM3X8E.

Did you write your own limited stubs for std::{unique_ptr, shared_ptr, function} or did your toolchain have something for these?

@emgre
Copy link
Member

emgre commented Jan 23, 2017

I got it working! It took me just a few minutes the fix the rest of the code. The interaction with OpenDNP3 was clearly the easy part of this, getting the whole thing compiling as it should was the hard part. You can check the latest commit on my repo.

Having the flyweights initialized lazily could help debugging the code. If a constructor fails, at least we will be able to locate it easily with the debugging information. Right now, if the constructor fails, we are still in initialization code (before the main), and you pretty much have to debug it instruction by instruction, walking in his shoes, just to find out what's going wrong.

For std::unique_ptr et al., they are provided by the standard library, so no need to provide stubs. I'm linking with newlib-nano, and they seem pretty lightweight (the malloc seems very minimalistic, but it works).

Here's a screenshot of the MSP432 talking like a chap via the serial port to a master built with OpenDNP3 and running on my computer.
dnp3msp432

Émile

@jadamcrain
Copy link
Member

Looks great. I'll be sure to point folks towards this as an example of porting the library to MCUs.

-Adam

@Matheus-Garbelini
Copy link

Matheus-Garbelini commented Oct 28, 2018

It's really a shame that no one from the opendmp3 community tried to organize this for a normal Arduino library already.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants