native c/c++ compilier

Status
Not open for further replies.

mjhilger

Member
I'm new here and just ordered the 3.1 version. I know the arduino IDE is the main path to create code, but does it compile down into ARM op codes or just into run time interpreted code. Is writing in the arduino the best way to create ARM code? How easy is it to create interrupt routines in that?

I am more versed in writing c/c++ for microchip controllers. So I am not familiar with this method and looking for answers.

Sorry if this is common knowledge, I searched the forum and I didn't see anything that seemed to answer my question.

Thanks
Mitch
 
The Teensy add-on to the Arduino IDE (v1.0x only, not 1.5) uses the GNU/GCC ARM compiler. ARM code is generated of course. Teensyduino is a large library improvements and new features, many of which are ARM-specific.

Some more advanced users prefer to use a different IDE such as MS's Visual Studio Community edition (windows only). Add to that the VisualMicro (VM) plugin and you have a great IDE. Both of these are free. VM has an optional $30 non-hardware debugger. Teensy 3 hardware does not allow use of SWD or JTAG debugging.

There are other IDEs, some supporting Macs and Linux, some based on the eclipse IDE.
There's VisualGDB a new low cost great ARM IDE that uses MS Visual Studio and is more generalized than VisualMicro.

Of course there are the professional and expensive IDEs including IAR, Keil, and some GCC/ARM add-ons like Rowley and Atollic. These aren't inherently Arudino-library focused.
And unrelated to Teensy there is CMSIS and each vendor's Hardware Abstraction Libraries (HALs), from Freescale and ST and tools such as CubeMX. But these aren't for the hobbyist or student.
 
Last edited:
Thank you Steve, that answers my question. I want to be able to take advantage of the full speed of the hardware and really like the cost, size and ability to use existing libraries/device drivers. Some of the other high performance arduino implementations seem to run an OS that emulate the code. This seems like a fantastic platform to use for prototyping using an ARM based controller.

Thanks and I look forward to playing with the hardware.
 
I'm new here and just ordered the 3.1 version. I know the arduino IDE is the main path to create code, but does it compile down into ARM op codes or just into run time interpreted code. Is writing in the arduino the best way to create ARM code? How easy is it to create interrupt routines in that?

As Steve said, a native ARM GCC is used which generates ARM Cortex-M4 native code including support for ARM DSP instructions. Its a fast, optimising compiler and will not hold you back in terms of speed. This MCU does not have a hardware floating point unit and thus double and float operations are done in software.

The Arduino environment provides access to a large number of libraries and also conveniences like simplified linking/includes. In addition to the .ino Arduino files you can also add .h. .c, and .cpp on additional IDE tabs and these follow the normal rules for C or C++ respectively.

Its also possible to configure the IDE to use an external editor if you wish to use a more powrful text editing environment.

The code is running on the bare metal MCU without any OS, RTOS, or interpreter. In the IDE you can enable an option to keep intermediate files, which allows you to see the precise machine instructions generated by the compiler.

Yes, you can create ISRs and you can also specify the interrupt priority level and use nested interrupts.
 
Likely, you'll not need to develop interrupt handlers as most anything you need exists in the teensyduino libraries.
 
As others have said, yes, Arduino is simply running gcc, which produces optimized native code.

If you're used to PIC programming, perhaps the biggest difference is focus on libraries that provide higher level functionality. Of course, you're not required to use libraries, and if you really wanted you could avoid all of the built-in stuff and code everything from scratch. But pretty much all the info you'll find online is about using that stuff.

The most commonly needed interrupt is a timer. For that, Teensy 3.x has IntervalTimer.

If you want to write your own interrupts, you can. There's 2 ways to do so. The older way involves using one of the pre-defined function names. They're in kinetis.h. These names are pre-populated into the interrupt vector table, so if you just use the right name, the linker automatically puts your function's address into the table while compiling the final file.

The other way involves the newer attachInterruptVector() function, which lets you use name. Starting with 1.20, Teensyduino allocates the vector table in RAM. The pre-populated addresses are copied from flash. You can change the RAM-based vector table with attachInterruptVector().

On most microcontrollers, like PIC and AVR, you have to do something special for functions that are interrupt handlers, so the compiler will save registers and status on entry to the function, and restore them when returning. If you're used to doing that, Cortex-M4 might be a little hard to believe, but indeed the hardware does all that for you. No special compiler stuff is needed to make an interrupt routine. It's just an ordinary function, compiled exactly the same as ordinary code. ARM designed a special return address that tells the hardware to do the return from interrupt, so no special compiler support is needed in the actual interrupt routine.

Of course, like any chip, you also need to enable the hardware to generate the interrupt, and there's special bits to enable/disable each interrupt. This stuff is all documented in the reference manual, and you can find several already-written examples in hardware/teensy/cores/teensy3 and in some of the libraries.

But usually with Arduino, the way things are done involves mostly using already well developed libraries. It's sort of half way between a conventional operating system (where you must use drivers and os functions) and fully bare metal programming, where all examples and code mention every hardware register.
 
Thank all of you for your replies. I like to setup a 1ms timer interrupt on most projects that allows me to maintain somewhat consistent timings.

So given what everyone has said I have a couple of questions, I'm sure they are answered in the reference material, but if you could provide a couple of answers, it will save me a lot of reading, which I will still need to do.
1) Since the ISR vector takes care of the registers, is it a true save onto the stack where multiple interrupts within low and high priority can nest or is it similar to the old Z80 and other microcontrollers that only have a fixed set or fixed stack (even microchip stack has a limit on entering return addresses)?
2) In timer ISR intended for timer ticks, normally you will need to turn off interrupts and take into consideration the negative number in the counter to correctly load the timer to minimize jitter and drift, is that capability possible in this timer/counter implementation? (in other words, the interrupt is set as the counter decrements from 0 to -1[roll of the cascade counters] or does it hard stop when it triggers the interrupt?

Clearly even with an extensive library and support, a good understanding of the internal resources and specifics yields proper software. Through reading some of the other posts about ISR's, are the error ISR's default implemented with some kind of flag with error cause or interrupt trigger stored somewhere? Conditions like invalid opcode, invalid address, I don't know all the conditions supported by the ARM processor - I need to read more about them I understand.

I think some of the disconnect I find in the Arduino line of hobby boards and serious use is the specifics that allow bounding timings and error recovery (watchdog timers?). Do the various libraries that handle particular things like serial or other comms just poll or are they interrupt driven (as quality software would be). I see the fantastic power provided by these low cost boards and the high performance applications possible with some of the shields and such. Similar to when Xilinx first entered the market with their FPGA and cut into the PAL market.

Thank all of you for your warm introduction to some remarkable products and effort spent on libraries and code snippits.
 
You may want to move your thinking up a level or two.. using the libraries discussed here, you almost never have to write an ISR, though you could, for drill.
The timer libraries in Teensyduino have several ways to create intervals, get call-backs from library ISRs at a certain interval, etc.

The Teensyduino (and belatedly most Arduino) serial UART drivers use interrupts and ring buffers for input and output. Some Teensy 3 peripherals optionally use the ARM direct memory access (DMA) controller channels. And so on.

Peruse the libraries to get a feel for this.

It's not like bare-metal AVRs and PICs, at all.
 
Last edited:
Wow, that's an impressive number of detail-oriented technical questions to pack into one message!

Before answers any, I'd like to repeat the notion that Arduino programming is somewhat like PC operating system programming, where normally you use higher level functions and libraries. It's also like a PC operating system in that numerous software components come from many different people. Much like on Windows, Linux, and MacOS, you can't just ask about worst-case interrupt response latency for all cases, because there's a virtually limitless number of combinations of software components that might be combined from numerous different sources, few of which specify such details.

1) Since the ISR vector takes care of the registers, is it a true save onto the stack where multiple interrupts within low and high priority can nest or is it similar to the old Z80 and other microcontrollers that only have a fixed set or fixed stack (even microchip stack has a limit on entering return addresses)?

Yes, it's a true RAM-based stack, limited in size only by the available RAM you're not using for other stuff.

Many of the old PIC chips use a small, fixed-size stack in dedicated registers. ARM uses RAM.

Similarly, Microchip's PIC architecture has numerous "features" which are efficient for small programs carefully crafted by a single programmer, usually in assembly, or in C with a very detailed focus on the specific hardware. It's been a long time since I've programmed a PIC, but I remember well the pain of the tiny stack, limited direct addressible RAM (and bank swapping), using a single pair of special registers for indirect address, running everything through the "W" accumulator, complex sequences of skip instructions needed for efficient 16 & 32 bit math, and lots of other stuff that makes sense for small, assembly-oriented development of fairly simple programs, but becomes rather horrible when scaled up to larger programs with complex algorithms.

ARM's architecture is generally the exact opposite. It's designed to scale. All registers are 32 bits. All registers can act as pointers to the entire 4 Gbyte memory space. All peripherals are memory mapped into that single 4 GB address space (no special memory regions). Internally, the CPU implements dual 32 bit buses, which feed into a multi-master switched bus matrix, allowing simultaneous access to both CPU buses, the DMA engine, and DMA-based peripherals like USB. All math operations use any combination of registers, push and pop can handle any combination of registers in a single instruction, special if/else handling allows common small conditionals to not incur extra cycles from branching. It's extremely well thought-out for C compilers. From a CPU design perspective, it's pretty much exactly the opposite of Microchip's earliest PIC designs. For small and simple code, there's extra overhead. For larger, complex software, it performs extremely well.

2) In timer ISR intended for timer ticks, normally you will need to turn off interrupts and take into consideration the negative number in the counter to correctly load the timer to minimize jitter and drift, is that capability possible in this timer/counter implementation?

Oh how this brings back long-forgotten PIC memories from the mid-1990s!

Technology has changed, quite a lot, since those days. Imagine someone from the 1960's seeing today's televisions. They're color, and flat, and hi-def, and stream digital video from a global computer network.

Likewise, as transistor density has increased and IC design has moved from transistors and gates to very high level synthesis languages, once-exotic timer features like automatic reload became standard fare. The modern microcontroller market is highly competitive, and with everyone licensing the same ARM CPU core, peripheral features are a place vendors can add extra value for little extra cost. Like TVs, hardware timers these days come with tons of advanced features.

Truly, implementing manual reload with careful cycle counting is a relic of the past, much like black and white television!

Clearly even with an extensive library and support, a good understanding of the internal resources and specifics yields proper software.

Certainly you can learn about all the hardware resources in the reference manual.

http://www.pjrc.com/teensy/K20P64M72SF1RM.pdf

Most of those peripherals already have good software support for the most common usages, so there's probably not a lot of value studying the reference manual, unless you're using the timers directly for their advanced features. Well, the other case where you'd need to study the details is using the DMA engine in highly creative ways, to move data between peripherals.

Probably the more important reference, if you're really concerned about proper software design, would be regarding the ARM CPU. For that, you really want this book:

http://www.amazon.com/Definitive-Cortex®-M3-Cortex®-M4-Processors-Edition/dp/0124080820

If you read this book, comparing to the old PIC chips, the level of capability and sophistication in the ARM Cortex-M chips is pretty astounding. Especially the NVIC's automatic handling of prioritized interrupt nesting and hardware optimizations like tail chaining are features pretty much unimaginable in the old world of 8 bit PIC chips!

Do the various libraries that handle particular things like serial or other comms just poll or are they interrupt driven (as quality software would be).

Each peripheral is handled differently. Some have multiple libraries.

The 3 serial ports are interrupt driven, with RAM-based buffers. Two of those also use hardware FIFOs, to reduce the number of interrupts during continuous data flow.

The USB port is DMA-based for extremely efficient operations, double-buffered for packets at the hardware level, and extended to a larger pool of packet buffers by interrupts.

SPI is usually polled.

I2C uses a mix of polling and interrupts.

ADC usage by analogRead is polled.

I2S, ADC and DAC for audio (the audio library) use DMA and interrupts.

I see the fantastic power provided by these low cost boards and the high performance applications possible with some of the shields and such.

Yes, indeed.

Imagine trying to use an old PIC chip to play 30 Hz video from SD card to 4320 RGB LEDs (which requires a special, tight-timing 800 kbps waveform), while also streaming 44.1 kHz audio:

http://community.arm.com/groups/embedded/blog/2014/05/23/led-video-panel-at-maker-faire-2014

Teensy 3.1 can do it pretty easily!

Imaging trying to develop all that from scratch based only on the hardware registers, working out all the details of DMA transfers and interrupts. Leveraging existing libraries makes the software side of such projects fairly easy.
 
Last edited:
@mjhilger,
I used to program PICs at an assembler level so I sort of remember some of what you are asking about. What I have found with the Teensy 3.1 is that I can read through Paul's libraries and datasheet for the micro to get some ideas how to accomplish something. There are LOTS of features for just about every peripheral. Often I needed some more low level control so I would dive into a library created by Paul that does most of what I want and pull out what I need. This is has been a great starting point for my projects. You will find some of the familiar #defines in there for different pieces of the hardware registers in those libraries. Then you can cross reference with the datasheet to see how the libs are setup. I did this with the DMA code I was messing with. I think you will find this processor (Teensy 3.1) is a breath of fresh air to develop with. You can mock up your code quickly with the supplied libs and then find what needs to change to accomplish your task. That is when I would dive into the libs to see what needs to change for your specific needs. I think you will find you will get %95 of what you need that way.
 
Again thanks for all the responses. Yes, I have been in this for a while and have lived through the slow low capability stuff (we did some amazing things with that stuff); Z-80,64180,80186, 80386SX, 8031, 8051, PIC 8,16,32 a few mot/freescale. But now my day job has me coding C# and its been a while since I have written micro code other than playing with stuff in my home lab. So, as I said earlier, I'm really looking forward to enjoying the power of the ARM and the software libraries that provide so much power at such a low price. I doubt I will have anything nearly as cool as some of the projects I see posted on the site projects page for quite some time. But everyone here seems very open to helping and I feel if I have any questions, they will be answered quickly.
 
Interesting Discussion.
I am also interested in using KL26 registers and bit names for some functions (input capture, RS485, and ISRs). I have to admit being old school has left me with the urge of knowing the operations taking place under the hood. I am looking for a document that list the registers names that can be directly accessed. If not can the register names used in Freescale document can be used as is? It will be wonderful, if there is a simple example illustrating the direct use of registers.

Thanks,
Sudhir Gupta
 
Interesting Discussion.
I am also interested in using KL26 registers and bit names for some functions (input capture, RS485, and ISRs). I have to admit being old school has left me with the urge of knowing the operations taking place under the hood. I am looking for a document that list the registers names that can be directly accessed. If not can the register names used in Freescale document can be used as is? It will be wonderful, if there is a simple example illustrating the direct use of registers.

Thanks,
Sudhir Gupta
If you get into the habit of learning/using libraries, and follow examples and others' work, you'll find that never do you have to grunge round in machine code, registers, interrupt vectors, etc. Doing so was the way of microprocessors in the 1980s and 1990's, a la PIC. Not so in the last 5+ years.

That's what Paul was saying... using the Teensy 3 and Arm Cortex in general (e.g., the vendor's plentiful I/O device libraries) - is more like libraries in operating systems like Windows, Linux. Less sophisticated, but these libraries relieve you from muddling in the muck.

If you want to put on hip boots and wade into the muck... read the Freescale user reference guide for the KL family. It's on the order of 1,000 pages. Same for other vendors' documentation. The alternative to using Arduino/Teensyduino libraries is using Freescale's libraries (or ST Micro's libraries for their Coretex M chips). With that, you'd not use the Arduino IDE/build tools but instead, something like the free version of IAR (32KB code size limited if free), or Keil has the same, or perhaps better if you're not anti-Windows, use visual GDB wich is a great IDE with GCC targeting ARMs from many vendors. There's also Eclipse for Linux (not my choice... too much of a PITA to config/use).

Here's a circa 2012 manual. It's not a one-semester read. That's why vendors are providing (free) libraries for more professional work, rather than Arduino which is a community of sometimes buggy work.

https://www.google.com/url?sa=t&rct...77OfTroBSyGLZdcTw&sig2=Fnwol6eL62v8ZueXiZ5SyA


Depends on if you want to stay in the Arduino lane, or not.
 
Last edited:
Interesting Discussion.
I am also interested in using KL26 registers and bit names for some functions (input capture, RS485, and ISRs). I have to admit being old school has left me with the urge of knowing the operations taking place under the hood. I am looking for a document that list the registers names that can be directly accessed. If not can the register names used in Freescale document can be used as is? It will be wonderful, if there is a simple example illustrating the direct use of registers.

Thanks,
Sudhir Gupta

Hi,

there are some interesting resources:

- The best: Source files on your harddisk - you will see, that it is already pretty low-level. Start with "mk20dx128.c" in Arduino/hardware/teensy/avr/cores/teensy3
- The ARM Manual for Cortex-M0+ for the core. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0484c/index.html
- the KL26 Reference Manual (Stevech linked the one for Teensy3, not LC), you can find it on the freescale site (sorry,I don't have a link at hand)

I like "low Level" too, but Pauls "core" is pretty good, and there are not much reasons to invent a new wheel. Most of the interesting stuff is already on your harddisk :)
But in some rare cases it makes sense to dig into the lower-level stuff!
 
Last edited:
Hi Frank,

I do believe Paul does a good job but it is an old habbit. I certainly do wish to reinvent the wheel, but I like to be able to develop code using any of the existing perpherals. It is reassuring to know that the information is there.

Thank You,
Sudhir
 
Right. You can use most any of the MCU peripherals and find there's an existing library for it. Or varying libraries, e.g., SPI with different devices like flash memory, RF transceivers, etc.

The baseline Teensy has a 1KHz interrupt with a function to get the tick count (a la Arduino) millis(), and a delay(n) ticks, and do elapsed tick count, and so on.
Libraries for pulse width modulation, analog to digital and digital to analog, some using DMA. and on and on.

Not like ye old bare-metal PIC.
 
Correction (post #16) :

Sorry Guys. I just re-read my own email. I stand corrected.

I do believe Paul does a good job but it is an old habbit. I certainly do NOT wish to reinvent the wheel,....

Sorry Again,

Sudhir
 
Status
Not open for further replies.
Back
Top