Programming Teensy 3.5/6 form scratch.

Status
Not open for further replies.

DiJuMx

Member
Hi all,

I want to learn how to program the Teensys (Teensies?) from the ground up. Partly because I want to have greater control, and partly because I want to learn so I can apply the skills to a couple of Cypress PSoC devices I have.
I've had a look through some of the source files included with the teensyduino source, and I've had a glance at the Reference manuals.

While I can see what Is being done, I have no reference for why or how important it is for baseline operation. For example:
  • I can go through kinetis.h and mk20dx128.c and cross reference the settings with the reference manual, but I have no idea what I can "cut out" (or alternatively NEED to include).
  • There is a webpage which explains baremetal assembly on the teensy. The linker script on that page is much shorter than mk64fx512.ld or mk66fx1m0.ld, but there's no explanation for the extra sections in the local linker scripts.

I need some direction on how to start this enormous task.
Can someone point me in the right direction?
Are there any resources or guidelines for getting started?
 
You'll don't have greater control (why do poeple think that? that's wrong. - i'd really like to know... really, i have no idea) , and learning is more easy with things that are known to work....
Sorry, If you don't know what to "cut out" or where you can find the needed information - its better to use Arduino!
Direction ?
a) write Ardino-programs to learn the basic things
b) Read and understand the reference manual, and ARM Cortex manual :)
c) write your own libs
...
zzz) try it without ardino
 
Last edited:
but I have no idea what I can "cut out" (or alternatively NEED to include).

Why cut out anything at all, especially from kinetis.h? It's just a long list of addresses for the many peripherals in the chip.

But if you *really* want to cut stuff out, just start deleting lines and click Verify in Arduino. Or run the compiler manually or with your makefile or whatever build system you're using. If the compiler gives you an error about undefined symbols, then you cut something you needed. Best to use a text editor with an undo feature! ;)

Obviously some of the peripherals don't exist in the MK20DX256 chip, like the ethernet mac, usbhs, and mpu. You can also safely delete the interrupt defs for the other chips. What that gains you, I just don't know. It's still a huge file that you can't view on your screen. These modern chips simply have thousands of hardware registers.

Are there any resources or guidelines for getting started?

You've seen this list, right?

https://forum.pjrc.com/threads/25395-Teensy-Quick-Reference-Code-Examples-Tips-and-Tricks
 
You'll don't have greater control (why do poeple think that? that's wrong. - i'd really like to know... really, i have no idea)
I think I'll have greater control over what extraneous code gets included into the final binary

and learning is more easier if you can rely on things are known to work....
Which is why I started looking in the existing code in teensyduino (since it works)

Sorry, If you don't know what to "cut out" or where you can find the need information - its better to use Arduino, for sure.
Yeah, but as I said "I want to apply the skills to Cypress PSoC devices", which don't have an Arduino interface. I also want to gain experience so I'm ready for embedded programming at work (where there also happens to be no Arduino IDE)

a) write Ardino-programs to learn the basic things
I have some experience with PICs and the aforementioned Cypress PSoCs; please don't assume I am completely new to programming embedded.
I also have (admittedly only a handful of years of) experience with C and C++.

b) Read and understand the reference manual, and ARM Cortex manual :)
At least it's a start. But are you suggesting I must read all ~1000 pages of the ARM Cortex manual, and then all ~1800 pages of the K64 reference manual, and then all ~2200 pages of the K66 reference manual before starting?
Just to pick a few modules from the K64 RM: I may not need the built in ethernet, or the CAN bus, or the SDHC controller for my first few projects must I necessarily understand how those work when I don't need them?

c) write your own libs
I probably will, when I have something to interface with.

zzz) try it without ardino
Why can't I be at this stage already?


If someone came by and posted something like "I'm new to C in linux", would you give links to tutorials and references, or would you say "Oh no, please use Windows and Visual Studio", or "Please read and understand the GCC Manual"?
----
Sorry If I've come across as a bit condescending, but I don't like it when I get brushed aside and effectively told "you can't do this because I don't think you can". I am new to this type of embedded programming, and am asking for help in that regard. I'm also somewhat tired.
 
Well, i guess, you want to know what you are doing, so cutting out things you don't understand is not a good way.
If you read trough the code of the both files you mentioned, you'll see many registers-accesses and so on. I bet you want to know what these lines are doing before removing them..
so.. sorry.. you have to read the manual and look up the needed parts :)

Why do you want to remove parts ?
 
Two things:

First, you should get Joseph Yiu's book. There are many important ARM architecture details which are documented but not actually explained by any of ARM's official documentation (and aren't mentioned at all by Freescale or Cypress in their manuals). This book really is the only good source if you're trying to learn such things:

https://www.amazon.com/dp/0124080820

Second, while your point about condescending comments has some merit, you really ought to reflect on how claiming you wish to learn the deeper details while complaining about the large number of pages of documentation and lines of source code comes across.
 
In response to both you (Frank) and Paul about the cutting out.... sorry that was the wrong phrase to use.

I don't want to remove parts from Pauls existing files. I want to start with my own blank files and build them up.
I want to know what needs to be included for basic execution, and why.

As I mentioned, I found a "bare metal assembly" page which has a linker script only 17 lines in length, but the provided ones (mk64fx512.ld and mk66fx1m0.ld) have around 79 lines. What are all the extra lines for?
Okay, one of those lines references the .vectors section; mk20dx128.c puts a lot of ISRs in that location. Are all of those ISRs necessary? or did Paul include them so others just need to overwrite the function prototype and not attempt what I am trying to do with learning to underlying process?

etc. etc.

These are the types of questions I have.
 
1) I'll have a look at the book. In fact I'm ordering it now.

2) I understand. But I'm not complaining about the number of pages (the Cypress PSoC4 TRM has 10K fyi), I'm complaining about being told "your answer is somewhere in these pages have fun". If you say "Basic operation can be achieved with sections 1,2,3.... etc", that's much better. A little bit more guidance was all I was asking for.
 
.... but the provided ones (mk64fx512.ld and mk66fx1m0.ld) have around 79 lines. What are all the extra lines for?

Each thing supports some particular feature.

For example, there's a few special program sections which cause memory meant for DMA to be allocated in the lower portion of the RAM. If you read Freescale's manual, you'll find info about the RAM having 3 ports, two which map to the ARM core buses, and a 3rd to the crossbar switch. The general idea is to get the DMA into one bank and the stack into the other, based on the assumption most of the CPU's heavy use of RAM will be to stack-allocated local variables.

Are all of those ISRs necessary? or did Paul include them so others just need to overwrite the function prototype....

If you do everything with polling, then no ISRs are necessary.

Yeah, these things are defined because Teensyduino is meant to be a platform where code developed by many different people can be used together. If you're making your own system from scratch, obviously you don't need such things. But then again, what's the harm or overhead in having function names defined? Does reclaiming a few hundred bytes of flash memory used by the interrupt table really matter? Maybe as a learning tool messing with this stuff may help you, but I'm doubtful there's any practical benefit.

But I'm not complaining about the number of pages ...

It kinda sounds like complaining ...
 
Last edited:
Good on you, I say. It’s nice to see a newbie to embedded software who wants to get their hand dirty at the low level. Anyone can get projects working using someone else’s libraries when all the hard stuff is done for you, but are they really learning the skills that are unique to embedded software that distinguishes it from other forms of software…

That book that has been recommended is worth the money IMO, also is the ARM system developers guide by Sloss, Symes and Wright. It covers slightly wider subject matter pertinent to cortex A also, e.g. MMUs. Both books are good reading but quite advanced subject matter, I must say.

I would point out that you don’t need to have any detailed knowledge of ARM cortex designs to program bare metal Kinetis micros. Most of what you’re working with is the peripherals, so I’d recommend diving into the GPIO chapter of the k22f/k64f/k66f reference manual and just see if you can get pins toggling by writing directly to registers, then move on to handling interrupts or writing basic drivers for simple peripherals like I2C, SPI, UART etc.

My development tool of choice is Rowley Crossworks for ARM, which I highly recommend. It is a commercial tool, but you can use the free version with no time limit if your programs are less than 16k of code. There is a project wizard that will create you the bare minimum of bare metal code to get you to main(), so you can see how little there is to the boot procedure. Worth taking the time to fully understand what it is doing before main().

You will need a JTAG/SWD module, something cheap like LPC-Link2 will suffice, or butcher a Freedom board and load it with CMSIS-DAP.s19.
 
Does the LPC-Link2 work with a Teensy (3.5/3.6) ?
I have a cheap china ST-Link V2 (somewhere in my chaos.. did not try it) - will it work, too ?
 
LPC-Link2 programmed with CMSIS-DAP firmware works with the Kinetis chipset, I can confirm that. It should work with any modern ARM core.

I don't have a ST-LinkV2, so cannot say. Is it CMSIS-DAP or some ST proprietary thing?

I ordered a couple of Loglow's breakout boards yesterday as I want to port a project from a k64f-FDRM board to Teensy 3.5. When they arrive, I'll have a little play with some of the debugger modules I have kicking around and see what works.
 
Getting down to the ground on Teensy 3 in order to learn how to handle PSoC devices, I dont think that will work so well.
If it is a PSoC 5LP or a 4M then they use a CortexM3 / M0 processor that is related to the one used on Teensy, and it is programmed
using the same gcc-arm toolchain. So there are many similarities. Getting the most out of a PSoC chip without using the PSoC creator software
will be hard, if not impossible. The PSoC analog and digital subsystems are controlled by registers, but finding the register definitions and
how to use them to do what the preprogrammed components do will keep you busy for the next couple of years.

I understand and I think its good to try and program these platforms from 'the basics' this is a great way to learn what is going on, at the same time I agree with others that if you want to build functioning application code it is much more efficient to use the existing platforms Arduino/Teensy or PSoC creator. So if you want to roll your own, either use existing code and remove, or use existing code as templates to build your own.

As far as references with specific sections into documentation, well it takes quite some time even for experienced coders around here to give exact such information, especially when the question is as open and general as you started out with.
 
Good on you, I say. It’s nice to see a newbie to embedded software who wants to get their hand dirty at the low level. Anyone can get projects working using someone else’s libraries when all the hard stuff is done for you, but are they really learning the skills that are unique to embedded software that distinguishes it from other forms of software…

I totally agree! Too often I find lots of resistance in this forum for people trying to go back to the basics.
Personally I think if you've come to the Teensy, then that is the more logical thing to do :
* if you are a beginner, you're probably better of with an Arduino-family member
* if you want to write on top of an OS, then you'd choose a RaspberryPi

I selected the Teensy because of the possibility to have high performance HW (core and peripherals), while still being able to code for it with maximum efficiency.
I'd rather re-write a few simple 'libraries', rather than ending up with lots of code I don't trust.

My development tool of choice is Rowley Crossworks for ARM, which I highly recommend. It is a commercial tool, but you can use the free version with no time limit if your programs are less than 16k of code. There is a project wizard that will create you the bare minimum of bare metal code to get you to main(), so you can see how little there is to the boot procedure. Worth taking the time to fully understand what it is doing before main().

Great tip! I will do that immediately.
If it creates a .hex file, why is there the need for a HW programmer/debugger. Could I not just upload using the Teensy Loader CLI ?
 
Yeah, I guess you probably can.

You'll only need a SWD/JTAG tool if you want to do single step debugging.
 
I totally agree! Too often I find lots of resistance in this forum for people trying to go back to the basics.
Personally I think if you've come to the Teensy, then that is the more logical thing to do :
* if you are a beginner, you're probably better of with an Arduino-family member
* if you want to write on top of an OS, then you'd choose a RaspberryPi
I also like how the products line up between the lower end Arduinos and with Linux based Arm processors like RPI or Odroid or...

Resistance? Often it may depend on how the person comes up here (or other forums). For example:

a) If you come up here and say I am completely new to embedded boards and would like to learn... Then yes most of us will suggest that you start off using the Arduino IDE and learn the basics. Once you have some of this working then really go under the covers of Arduino code, which is great as you have all of the source code installed by Teensyduino... Also if you turn on verbose compile and link, you can see the exact commands that are issued to build your program. Once you understand this, you can choose to rewrite some or all of this.... i.e. what Frank suggested in #2... I don't personally see this as Resistance.

b) If instead you come up here and say something like: I have been trying to do Blah with the T3.6 and I am finding difficulties with doing some function. Either the current code appears to be buggy or limited in some way or I think it can be done more efficiently... In most cases there are several people up here (especially Paul) who will try to help out, including maybe even buy hardware. And if in the end they fix a bug or find a better way to do stuff, hopefully those changes can be folded into the next version(s) of the software so all of us can take advantage of it.

c) If you come up here and say I have been working with the Teensy now for awhile and would now like to develop a new set of code, for example some form or RTOS for it.... You will probably find a lot of people up here who say great, let me know when you have something we can play with.

d) I am not suggesting that this is the case here or any other specific cases! But if however someone comes up here sounding like, all of the current stuff is a piece of .... and only I can do it right.... Then it is probably human nature to resist... And I know that I sometimes I come across this way :eek: And in most cases the writer did not intend it this way, but was simply choice of words!

I selected the Teensy because of the possibility to have high performance HW (core and peripherals), while still being able to code for it with maximum efficiency.
I'd rather re-write a few simple 'libraries', rather than ending up with lots of code I don't trust.
I also choose the Teensy for the higher performance HW. But I also choose it for it's level of support. That is there are very few other boards I have used where the owner/main developer was so accessible and working so hard to improve the products.

As for re-writing a few simple libraries, to me, it depends on your goals and how much time you have to do this. For example a long long time ago I wrote all of my own code sort-of from scratch to run on simple AVR processors (atmega8 atmega32)... I also did some of this for BasicMicro Arc32 board (Renasis H8...) And I totally agree this is a great learning experience.

But for me writing the full set of code for the Teensy 3.6 (or 5) from scratch would be a Huge undertaking, especially if you wish to take advantage of the many parts of the processor, like USB, host USB, networking, SDCard... This is way beyond my pay grade (which is currently free). :D
 
Many, many times we've had people show up here insisting they would accomplish an ambitious project doing everything from scratch, sometimes even with assembly, for maximum efficiency. We've also had a tremendous number of people build pretty amazing projects by leveraging libraries (sometimes adding to them), using Arduino or another system like Visual Micro or PlatformIO, compiling pretty much the same libraries as Arduino. If I had to draw a Venn diagram, the would be very little overlap between these 2 groups.

Still, many many times I've written lengthy replies about how some particular low level thing really works, or why some part of the code was written a particular way, for the benefit of someone wishing to really dig into the details.

In theory, it should be possible to do at least as much and very likely more by optimizing everything from the lowest levels. But in practice, rarely do things work out that way on these modern chips. Most tasks are I/O bound, not limited by computational power. Fully leveraging the sophisticated peripherals is the way to get best performance for many projects. That's much easier said than done. Even the very capable libraries we have today didn't happen overnight. Many of them have slowly grown. Some had subtle bugs that didn't get really uncovered and fixed until they were used by a very large number of people. Again, in theory someone working at the lowest levels could write all new bug-free highly optimized code from scratch. In practice, it just doesn't seem to work out that way.

We've also had quite a number of these folks express what seems like, quite frankly, a bad attitude. I'm particularly skeptical of people who want to focus on assembly language and clock cycle counting, but have little or no interest in learning how advanced timer features or DMA really works.

Still, if someone really wants to dig into low level details for the sake of learning, I'm happy to help. If their purpose is merely doing a specific project with best performance, I still help, but I don't feel like indulging their desire to reinvent wheels is a good way to really assist with their goal.
 
You could also look around the NXP site and forums for tips on low-level programming the K64 or K66, e.g. https://community.nxp.com/docs/DOC-102540
Besides the teensy core, you could also look at other development environments, MBED has K64 support (lots of abstraction/layers).
Then you could gather the pieces needed to init the clocks and such, and see if you can toggle a GPIO pin.

Once you have a working startup base, then you'll start experimenting with the various peripherals and their registers. But you can do those experiments starting with Teensyduino, having the benefit of Serial.print and symbol definitions in kinetis.h (or maybe you prefer hex constants). I've enjoyed learning about various teensy peripherals with small test sketches that depend little or not at all on the teensy core. Others have implemented their own versions of peripheral libraries, e.g. i2c_t3 and pedvide's ADC lib, Franks FastCRC, Ethernet, CAU, RNG, ... then you could weave your peripheral codes into your bare-metal startup base.
 
Last edited:
From your other threads, it sounds like you are wanting to program in embeded C... So the first question would be what compiler are you using? Does it already have header files these processors?

Personally unless you find a real need/desire to reinvent the wheel, I would start off with the Arduino IDE and get an understanding of how it works... Then go to makefiles... Or use some other IDE, like eclipse, or ...

Yes kinetis.h has a lot of the nice things like register addresses and defines for some of the bits...

Also unless you really want the pain to look at schematics and the like, I would also look at .../teensy3/core_pins.h as this gives you the mappings from the logical pin number marked on the boards to the IO ports and pins associated with these.

Also depending on what it is you are really trying to do, I would look over lots of other files as well, to help understand how things work. Things like if you are going to use a Serial port, you need to certain things that may not be obvious, like enable the addresses to talk to the specific hardware serial port registers...
 
Status
Not open for further replies.
Back
Top