Using a port of ChibiOS for the Teensy 3 series, my goal is to run it on Teensy 3.6.
ChibiOS example modified to use latest Teensy 3 SD library.
ino - 5.17 kB - 12/03/2016 at 23:48
One of the cool features of the Teensy 3.6 is that it has an SD card slot. The slot is supported by the SD library which you can get here (add link to github). The ChibiOS demos for Arduino include a chFifoDataLogger program which uses a version of the SDfat library. The logical thing to do is to replace the SDfat library with the new SD library made for the Teensy 3.6.
So that's what I did.
First, I ran the CardInfo Example program from the SD package to be sure I could see my SD card on the Teensy. For the 3.6, I made sure that the chipSelect was set to BUILTIN_SDCARD. The program ran using two different 4Gig cards and a 32Gig card.
Since the SD library works a little differently than the SDfat library, I compared the Datalogger program from the SD package to the chFifoDataLogger program from SDfat in the ChibiOS package and made some appropriate changes. The main changes were:
The file t36chFifoDataLogger is the result of my efforts. It needs a bit of clean up, but the code works. In addition to showing how to use the SD library, it also shows how to use ChibiOS semaphores to solve the Reader-Writer problem using an RTOS. More on this later.
The chContextTime program is provided to measure the context switching time. Using Arduino, I compiled, loaded, and ran chContextTime. Then I measured the times the LED pin was high. One time was turning the LED on and off without a context switch; the other time involved a context switch. (Look at the code for this program - sketch if you will - and its operation will be obvious.) Using the cursors on my Rigol DS1074Z, I measured 124nS without a context switch and 816nS with a context switch. The context switch took 692nS. I estimate the confidence band to be +/- 10nS. Much quicker than the 15 to 16uS on an AVR Mega328 (Arduino UNO). And of course it should be since the Teensy 3.6 uses an ARM running at 180MHz.
I also tested chDataSharing which ran as expected. It is deserving of more discussion since it reports stack usage per task - a useful debugging tool.
EDIT 1/5/17: Screenshots from my DS1074Z follow showing the cursor measurements. Interestingly, these were made after the revisions I made to properly handle floating point. As I mentioned in the edited version of my first log, the push and pop of the floating point registers had to be added. You will note that the context switch time is now 1.000uS, up from 816nS. (The task without the context switch measures 120nS now - within the +/- 10nS error band.) So the context switch measures 880nS; up from 692nS, but still toasty!
The above is for the narrow pulse. Look at BX - AX for the pulse width. Below is the wide pulse measurement. Read the same datum.
Needless to say, the first step will be to blink a LED with ChibiOS. So how do we get there?
First things first. Let's download and "install" ChibiOS. Since Bill Grieman has done the heavy lifting, download from his github. I downloaded as a zip, then moved the ChibiOS_ARM library into the library area for Teensy at arduio-1.6.12/hardware/teensy/avr/libraries. Seemed like a good place to put it. Started up Arduino (I'm using 1.6.12) and looked for ChibiOS as an Example. Not there!
A little digging located the problem: The library.properties for ChibiOS_ARM has architecture = sam. Changing "sam" to "*" solves the problem. Just keep in mind that this won't work for other architectures! Restart Arduino and all the ChibiOS_ARM stuff appears.
Bring in Examples -> ChibiOS_ARM -> chBlink. If you attempt to build (Verify) it, you'll get an error having to do with "Compiler generates FPU instructions for a device without an FPU". As near as I can tell, this is a bogus error. In the process of tracking this down, I discovered that the version of core-cm4.h in the ChibiOS area is not the same as that in the Teensy area. Without trying to resolve the problem (and believing that it was an artifact), I removed it by adding "-D__FPU_PRESENT 1U" to the boards.txt file in arduino -1.6.12/hardware/teensy/avr in the 3.6 area.
Change the line (line 25 in my version of boards.txt):
teensy36.build.flags.defs=-D__MK66FX1M0__ -DTEENSYDUINO=131 -D__FPU_PRESENT=1U
Now chBlink builds, but there is still a bunch of warnings related to redefing "true". I fixed this with an obvious modification in arduino -1.6.12/hardware/teensy/avr/cores/Teensy3/wiring.h, line 143.
Change the line:
#define true (!false)
#define true (!false)
#endif // true?
OK! chBlink now builds and runs happily! Changing the timing of the blink duration works as expected.
Let's push our luck and try chBlinkPrint. It should build without problem with the fixes detailed above. Download it to the Teensy 3.6, then start the Serial Monitor and enter any character. The program begins sending the expected data. Woo-hoo!
EDIT: As noted in the comments below, Floating Point does not work, even though things compile just fine with FPU_PRESENT defined. The problem is easy to demonstrate by simply trying to print a floating point value instead of an int in chBlinkPrint. The reason is that CORTEX_HAS_CPU is hard coded to 0 in cmparams.h (line 46). This suppresses the code that saves the floating point registers during a context switch! Here's how to fix it:
Replace the line 46 in arduino -1.6.12/hardware/teensy/avr/libraries/ChiibiOS_ARM/src/utility/cmparms.h:
#define CORTEX_HAS_FPU 0 // WHG
with the following:
#if __FPU_PRESENT == 1
#define CORTEX_HAS_FPU 1 // jkl
#define CORTEX_HAS_FPU 0
#endif // FPU_PRESENT == 1
So far, the floating point tests I've tried using ChibiOS work correctly. But I don't claim to have tested extensively and will be interested in any failures people might find.
Note that all I've said should apply to Teensy 3.5 as well. Just change the 3.5 area of the boards.text file. Since I don't have a 3.5, I can't test it, but I can't see why it wouldn't work.