How to layout arduino code files with external unit tests - arduino

I have three code files for an arduino project:
main.ino <-- main sketch
helper.cpp <-- helper functions, no avr code
helper_test.cpp <-- unit test for helpers
Arduino will attempt to include helper_test.cpp, and will be confused by its inclusion of the unit test library header files (which happen to be google test). If the unit test contains a C main function it will skip everything in main.ino and try to use only that.
I know there are dedicated arduino unit test frameworks, these are just regular c++ unit tests for math functions that don't touch any avr-related code.
How can I lay these files out or make this so arduino won't try to include helper_test.cpp but will include helper.cpp?

Just let him include it, but exclude all the code. I mean:
File test_enablers.h
#define INCLUDE_HELPER_TEST
File helper_test.cpp
#include "test_enablers.h"
#ifdef INCLUDE_HELPER_TEST
... your helper test code
#endif /* INCLUDE_HELPER_TEST */
You can add as many test files as you want; just add the flags in the .h file
If you want to disable the test file just comment the #define and the file won't be compiled.
If you want to exclude some code in some other files (e.g. the setup and loop functions in the main, since you are already implementing it in the test, just write
File main.ino
#include "test_enablers.h"
#ifndef INCLUDE_HELPER_TEST
... your production setup and loop
#endif /* INCLUDE_HELPER_TEST */
(note the ifndef in place of the ifdef)

If you want to unit test, simply create code that is going to execute one task. One can purchase a Logic Analyzer and examine the ports' outputs to see if the right signal is being delivered. Unit Testing has to be done differently in most cases due to the nature of Arduinos. Hope this helps.

I don't think the Arduino compiler (and related systems) are set up to handle unit testing, I had to build my own framework to do this that I've written about in this answer to a related Arduino-unit-testing question.
For this to work, you'd need to put the bulk of your code in a library, and the unit tests would be stored as a subdirectory of that library called test/. You could test the complete sketches by putting them in the examples/ directory of the library, but only compilation can be tested on those.

You need to create two separate projects. One project will contain your production code. It will have these files:
main.ino <-- main sketch
helper.h <-- header for helper functions
helper.cpp <-- implementation for helper functions
and all other files necessary to create your arduino app. You will build it when you want to create the app itself. The other project will be a standard executable that will run unit tests:
main_test.cpp <-- main
helper_test.cpp <-- unit test for helpers
../arduino_project/helper.h <-- header for helper functions
../arduino_project/helper.cpp <-- implementation for helper functions
Every time you add new function or make change to some helper function, you build this executable and run it to see if all tests pass.As you can see, this project will add files (that contain function which will be tested) from your main project. The best way would be to add the location of source files from the main project as additional include directories for unit tests project.

Related

Preprocessor makes function name unaccessabel

I have to create a SQLite database using System.Data.SQLite and using C++/CLI but I run into problems. Unfortunately, using C# is not an option, if it was then there is no problem. (Please don't advise me not to use C++/CLI, it is not an option in this project.)
In C# the following code works without any problem.
using System.Data.SQLite;
void CreateDb(String file)
{
SQLiteConnection.CreateFile(file);
}
The equivalent code in C++/CLI is not without its problems.
using namespace System::Data::SQLite;
void CreateDb(System::String ^file)
{
SQLiteConnection::CreateFile(file); // error C2039
}
The exact error txt for C2039 is:
// error C2039: 'CreateFileA' : is not a member of 'System::Data::SQLite::SQLiteConnection'
If I take a closer look at the definition of CreateFile I get the following choice
#define CreateFile CreateFileW - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9292)
#define CreateFile CreateFileA - c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\WinBase.h(9294)
Which leads to the following lines in WinBase.h
#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE
The Microsoft SDK is muddling with exact the name that I need and SQLite does not provide me with CreateFile[AW] versions.
So I tried this before the code calling SQLiteConnection.CreateFile(file) and I do this isolated so that other code is affected by it.
#ifdef CreateFile
#undef CreateFile
#endif
It solves my problem (for now) but how safe is this?
Is there a better way of solving this problem?
Your advise is much appreciated.
The #undef is how I've always handled this.
how safe is this?
This is safe.
You may have this problem again if you have other name collisions. The compile errors resulting from such a name collision are easy to diagnose, now that you know what you're looking for, so it will be easy to add additional #undef directives if needed.
If you need to call the Win32 CreateFile, you will need to type CreateFileA or CreateFileW explicitly, but that's not a big hassle.
Is there a better way of solving this problem?
Yes, but it's not always possible.
The better way is to not #include <Windows.h> in the files where you use SQLite. This avoids the problem entirely. However, it's not always possible to organize your program like this, so #undef is usually the solution.
(This next paragraph doesn't apply to your scenario with SQLite: You're using the managed version, so there's no headers. This next bit applies to C++ libraries that include library headers. I'm including it for completeness in case someone is writing plain C++.)
One other thing to watch out for here is #include-ing the Windows headers before library headers. In that case, the class definition itself will have CreateFile renamed to CreateFileA. If you use #undef with that, you'll get the opposite error from what you showed. You can leave the #define in place, which will sometimes end up working, but this is rather fragile, so I would avoid this scenario.
(I ran into this once with MFC headers in a C++ application: The changed method name ended up everywhere, even Intellisense showed the name as ending in "A". It worked anyway because the vTable was initialized inside the MFC DLL, and so all that mattered in the calling application was that the vTable pointed at the right method, which it was.)

SBT run code in project after compile

we need to run some code after the compile step. Making things happen after the compile step seems easy:
compile in Compile <<= (compile in Compile) map{x=>
// post-compile work
doFoo()
x
}
but how do you run something in the freshly compiled code?
More info on the scenario: we are using less for css in a lift project. We wanted lift to compile less into css on the fly (if needed) to help dev, but produce less using the same code, during the build, before tests etc run. less-sbt may help but we are interested in how to solve this generally.
You can use the triggeredBy method like this:
yourTask <<= (fullClasspath in Runtime) map {classpath =>
val loader: ClassLoader = ClasspathUtilities.toLoader(classpath.map(_.data).map(_.getAbsoluteFile))
loader.loadClass("your.class.Here").newInstance()
} triggeredBy(compile in Compile)
This will instantiate your class that has just been compiled, using the runtime classpath for your application, after any compile.
It would probably help if you explained your use scenario for this, since there are some different possible solution paths here and choosing between them might involve considerations that you haven't told us.
You won't be able to just write down an ordinary method call into the compiled code. That would be impossible since at the time your build definition is compiled, sbt hasn't looked at your project code yet.
Warning: rambling and thinking out loud ahead.
One trick I can suggest is to access testLoader in Test to get a classloader in which your compiled classes are loaded, and then use reflection to call methods there. For example, in my own build I have:
val netlogoVersion = taskKey[String]("...")
netlogoVersion := {
(testLoader in Test).value
.loadClass("org.nlogo.api.Version")
.getMethod("version")
.invoke(null).asInstanceOf[String]
}
I'm not sure whether accessing testLoader in Test will actually work in your case because testLoader loads your test classes as well as your regular classes, so you might get a circular dependency between compile in Compile and compile in Test.
If you want to try to make a classloader that just has your regular classes loaded, well, hmm. You could look in the sbt source code at the implementation of createTestLoader and use it for inspiration, modifying the arguments that are passed to ClasspathUtilities.makeLoader. (You might also look at the similar code in Run.run0. It calls makeLoader as part of the implementation of the run task.)
A different path you might consider is to reuse the machinery behind the run task to run your code. You won't be able to call an arbitrary method in your compiled code this way, only a main method, but perhaps you can live with that, if you don't need a return value back.
The fullRunTask method exists for creating entire run-like tasks. See "How can I create a custom run task, in addition to run?" from http://www.scala-sbt.org/0.13.1/docs/faq.html . fullRunTask makes it very easy to create a separate task that runs something in your compiled code, but by itself it won't get you all the way to a solution because you need a way of attaching that task to the existing compile in Compile task. If you go this route, I'd suggest asking it that last piece as a separate question.
Consider bypassing fullRunTask and just assembling your own call to Run.run. They use the same machinery. In my own build, I currently use fullRunTask, but back before fullRunTask was added by sbt, here was what my equivalent Run.run-based code looked like:
(..., fullClasspath in Compile, runner, streams, ...) map {
(..., cp, runner, s, ...) =>
Run.run("name.of.my.MainClass",
cp.map(_.data), Seq(), s.log)(runner)
}
Pardon the sbt 0.12, pre-macro syntax; this would look nicer if redone with the 0.13 macros.
Anyway, hopefully something in this brain dump proves useful.

Flex conditional compilation-Is it possible to have conditional compilation in flex library project?

Using Flex, created a desktop and web application in that used conditional compilation. It runs successfully. Now, I Would like to have the single swc file for both Desktop and web. So created the library project for satisfying that condition. While using conditional compilation in flex library project getting many issues like conflicts variable name and duplicate functions and so on, which I haven't faced while using flex projects without swc file.
So the question arises now: Is it possible to have conditional compilation on a flex library project?
When compiling your SWC, you can specify compile constants by passing them in a -define argument. This will however, only include whatever code you've added using that constant - i.e. you can't reset the const in a project that includes the SWC to get a different result.
Below is the code for a bat file for creating an SWC. Copy it into a new file, and save it with the extension .bat. Replace the file paths as necessary.
#echo off
set flexroot=D:\Program Files\FlashDevelop\Tools\flexsdk\
set proj=D:\Dev\TestSWC\
cd %flexroot%bin\
compc.exe -source-path %proj%src -is %proj%src -optimize -define CONFIG::debug false -define CONFIG::release true -output %proj%bin\TestSWC.swc
pause
I used this to build a SWC file containing a single class, like so:
package
{
public class TestClass
{
public function sayHello():void
{
CONFIG::debug
{
trace( "Hello debug" );
}
CONFIG::release
{
trace( "Hello release" );
}
}
}
}
I then created another project, included the SWC and set the CONFIG::debug flag to true, and called the sayHello() function. It traced "Hello release" as the SWC was compiled with the CONFIG::release flag as true.
Quoting the docs:
The mxmlc compiler lets you pass the values of constants to the application at compile time
It does not mention compc, so I'm pretty sure it is not possible. I also wonder how that would work technically since you include/exclude parts of the code during compilation. The compiled SWC would no longer contain the conditional code.

Arduino: issue including ShiftPWM library in custom library

I recently came across ShiftPWM, which is optimized to control RGB LEDs using shift registers.
I downloaded the source code and was able to run the example provided on my breadboard no problem. I even tweaked the sketch a bit and feel comfortable using the functions in the ShiftPWM library.
I would like to include the ShiftPWM functionality in a current project I'm working on, which already has a ton of library files. I'd like to #include "ShiftPWM.h into my Registers.h file, so that I can use my own syntax and object-oriented hierarchy to light up my LEDs.
In the example arduino sketch, I need to define a few constants before including the ShiftPWM library file:
#define SHIFTPWM_NOSPI
const int ShiftPWM_latchPin = 2;
const int ShiftPWM_dataPin = 4;
const int ShiftPWM_clockPin = 3;
const bool ShiftPWM_invertOutputs = true;
const bool ShiftPWM_balanceLoad = false;
#include "ShiftPWM.h"
So I figured I could simply copy these lines into my Registers.h file, as well as the setup code and other functions that go about lighting up the LEDs.
But, when I do this and try to compile my arduino sketch, which only includes Registers.h, my compiler gives me the following (abbreviated) errors:
multiple definitions of '__vector_11'
.../ShiftPWM/ShiftPWM.h:175 first defined here
multiple definitions of 'ShiftPWM'
.../ShiftPWM/ShiftPWM.h:175 first defined here
The line it is referring to is this:
ISR(TIMER1_COMPA_vect) {
ShiftPWM_handleInterrupt();
}
My research indicates this line of code has something to do with the timers used by the arduino to run interrupts. People often get the 'multiple definitions of __vector_11' error when they try to run the arduino Servo and Tone library, for instance, because they both attempt to use timer1.
I am wondering why I am getting this error simply by attempting to link to the ShiftPWM library from my own custom library. Nowhere in my code do I manually set any sort of timer. I am assuming it stems from some linking issue, but I really can't figure out what that may be.
Any help is appreciated.

Cannot link Arduino project to include Simulink Code

At work, I recently took training on MATLAB/Simulink, including the Simulink Coder that can generate C code for embedded applications. I wanted to try my hand at it, so I bought an Arduino, and dove in. I am able to write simple sketches with no problem, but have been hitting a brick wall when trying to integrate the code generated by Simulink.
I initially used the Arduino IDE, then Eclipse with the Arduino plug-in, and finally Xcode with the embedXcode templates. (My work machine with Simulink is a PC, but I'm not allowed to install "unauthorized software", so I did the rest on my home Mac.) All three use the same avr-gcc compiler.
All three had the same point of failure: "Undefined Reference" errors on the generated function calls. I believe this to be a linker issue rather than basic syntax or header inclusion, as the Eclipse and Xcode code-completion are working OK, and if I change the call signature in any way, the error changes. I can make references to the data structures OK.
As far as I can tell, the default makefiles are set up to compile and link any files within the folder. A "mass_model2.o" file is being created, at least with Xcode. Finally, if I manually write a separate "myFunction.c" and "MyFunction.h" file with a simple function call, this does compile and run on the device as expected.
In desparation, I copied the entire contents of the generated ".c" file, and pasted them in the main sketch file after my setup() and loop() functions, keeping the same ".h" references, and removed the ".c" file from the project. This actually did compile and run! However, I should not have to touch the generated code in order to use it.
What do I need to do to get this to compile and link properly?
The Simulink code is quite verbose, so here are the key parts:
mass_model2.h excerpts:
#include "rtwtypes.h"
#include "mass_model2_types.h"
/* External inputs (root inport signals with auto storage) */
typedef struct {
int16_T PotPos; /* '<Root>/PotPos' */
} ExternalInputs_mass_model2;
/* External outputs (root outports fed by signals with auto storage) */
typedef struct {
int16_T ServoCmd; /* '<Root>/ServoCmd' */
} ExternalOutputs_mass_model2;
/* External inputs (root inport signals with auto storage) */
extern ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
extern ExternalOutputs_mass_model2 mass_model2_Y;
/* Model entry point functions */
extern void mass_model2_initialize(void);
extern void mass_model2_step(void);
mass_model2.c excerpts:
#include "mass_model2.h"
#include "mass_model2_private.h"
/* External inputs (root inport signals with auto storage) */
ExternalInputs_mass_model2 mass_model2_U;
/* External outputs (root outports fed by signals with auto storage) */
ExternalOutputs_mass_model2 mass_model2_Y;
/* Model step function */
void mass_model2_step(void)
{
// lots of generated code here
}
/* Model initialize function */
void mass_model2_initialize(void)
{
// generated code here
}
The other referenced headers, "rtwtypes.h" and "mass_model2_private.h" define specific types that are used by the generated code, like int16_T. These files are included in the project, and I do not receive any errors associated with them.
In my sketch file, the setup() function calls mass_model2_initialize(). loop() reads my input (a potentiometer), sets the value in mass_model2_U.PotPos, and calls mass_model2_step(). It then gets mass_model2_Y.ServoCmd and writes the value to a servo for output, and finally has a delay().
You can use this download, http://www.mathworks.com/matlabcentral/fileexchange/24675, with Simulink, Simulink Coder and Embedded Coder. Make sure you have the correct version numbers of each tool.
The #include "Arduino.h" statement is required on the main sketch.

Resources