Author Topic: Cortex M3 hand holding tutorial  (Read 13169 times)

0 Members and 1 Guest are viewing this topic.

Offline TheBrick

  • Regular Contributor
  • *
  • Posts: 58
Cortex M3 hand holding tutorial
« on: June 15, 2014, 07:56:06 pm »
Hi, I've bought ,my self a M3 development board (LPC-P1343) and Jtag cable / unit. I've set up my tool chain but I'd like to read though some tutorials about that step my though some code. There are some example that come with the code by not real explanation of what is being done. Running though my head are questions like "where did that function come from?", "what are you setting to 0X00000000F and why?", " Can I use the same .s file for everything and it is just some set-up  for this device or do I have to customise it for every project".

I've done some AVR programming before and the tutorials I found for that have been excellent. Stepped me through what was being done from blinking LEDs to UART to interrupts e.t.c. I've read some intro to cortex M3  documents and introductions (e.g. http://www.egr.msu.edu/classes/ece331/mason/web_files/ARM_CortexM3.pdf, some othe pdf from ARM)  that tell me that its Harvard architecture and there are 15 general purpose registers e.t.c but all of the tutorials seem to be aimed aimed at specific boards or I feel like I've walked in to a conversation half way through. I thought that with CMSIS things should have a standard interface? I just need a dummies intro to get me rolling on some basic task then I will understand what bits I need to google to go further.

Hoping someone can help point me in the right direction.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #1 on: June 15, 2014, 08:02:06 pm »
They are all highly alike, aside from the peripherals. So once you know how to set up one, you know how to set up another.

Your issue looks like you need to know how to set up yours. That can be difficult without knowing specifically what tools you are using.
================================
https://dannyelectronics.wordpress.com/
 

Offline Tris20

  • Regular Contributor
  • *
  • Posts: 84
  • Country: gb
Re: Cortex M3 hand holding tutorial
« Reply #2 on: June 15, 2014, 09:19:41 pm »
There's a good book called "Fast and effective embedded systems design - applying the ARM mbed" which I got a while ago. It goes with the LPC1768 which also runs off the M3 and has a decent amount of good beginner code and descriptions. Not sure how useful the book will be for JTAG but it can certainly help you get used to a new embed provided you're happy to make a few minor changes to the code (mostly just pin outs) to get things to work.
 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
Re: Cortex M3 hand holding tutorial
« Reply #3 on: June 17, 2014, 08:17:52 pm »
Welcome to ARM.  This appears to be the rite of passage for anyone learning them.  It seems you're supposed to blindly jump in and start modifying code until you start to see the patterns for yourself.  Does that function exist in every example, even those from different vendors?  Then it's probably CMSIS.  That kind of thing.

The crappy orientation doesn't seem to be an impenetrable barrier, as Cortex Ms are pretty much the rage these days.  But, as you can tell, Arduino it isn't.

Just start digging in.  Read the data sheet sections for I/O pins and the peripheral you want to use.  Tweak the code and compile it, see if it works.  It's foreign right now, but if you immerse yourself in it, you'll get there.  I assume.  I'm still logging time in the co-pilot's seat myself.
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #4 on: June 17, 2014, 08:44:51 pm »
There are quite a few decent tutorials online. One thing that helps you a lot is to be familiar with the gcc toolchain - most ARM toolchains are derived from it. 

Most of the stuff I have is for STM32, but for LPCs there are some as well - just adapt to your micro:

http://www.dreamislife.com/arm/
http://tenuki.fr/nio101/?page_id=67
https://code.google.com/p/cortex-m3-tutorials/
http://www.meatandnetworking.com/tutorials/arm-cortex-mx-quickstart/
http://www.meatandnetworking.com/tutorials/lpc1114fn28-with-open-source-tools/

These are pretty good overview of gcc, linker scripts, debugging with OpenOCD and gdb. It is for STM32 but most things are pretty much the same for the LPC chips too - you may just need a different configuration here and there.

http://hertaville.com/the-stm32f0discovery-board/
http://hertaville.com/2012/06/29/alternative-tutorials-for-setting-up-a-gcc-based-development-environment/


There are likely some more. For JTAG, gdb and similar - have a look at OpenOCD and/or the website of the vendor of your JTAG tool.

There are also a lot of videos and tutorials on Youtube, explaining the architecture, how to set up the toolchain, etc.

For example:


 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
Re: Cortex M3 hand holding tutorial
« Reply #5 on: June 17, 2014, 11:46:43 pm »
That (the video) is a really good tutorial series.  It starts out with the typical pointless and inevitably incomplete guide to how to use installation programs and write C code, but goes pretty quickly into useful info, assuming this isn't your first time using a computer.

I really like how it works up from reading / writing memory to explaining the concept of memory maps and GPIO registers.  Great approach to demystifying the inner workings.

Good stuff, thanks for posting the link.   :-+
 

Offline azrobbo

  • Newbie
  • Posts: 3
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #6 on: June 18, 2014, 12:18:48 am »
It sounds like something is wonky with your IDE & CMSIS setup.   Since you're using an LPC MCU, you might check out NXP's free IDE:  http://www.lpcware.com/lpcxpresso

The video linked off of that page is about an hour demo of setting up and using the IDE - hopefully that will get you going.

Cheers.
 

Offline nuhamind2

  • Regular Contributor
  • *
  • Posts: 138
  • Country: id
Re: Cortex M3 hand holding tutorial
« Reply #7 on: June 18, 2014, 02:34:59 am »
I'm in the same boat. Have been reading a few document but never actually write a code. Lately I'm wondering about every file automatically included when I start a project and what purpose they serve. This PDF explain CMSIS and the level they are used.
http://www.doulos.com/knowhow/arm/CMSIS/CMSIS_Doulos_Tutorial.pdf
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #8 on: June 18, 2014, 10:11:25 am »
There are generally 3 types of files involved in a CMSIS start-up:

1) the start-up file: it lays down the interrupt vector table, calls SystemInit() and then _main()/main(). Tpically written in assembly;
2) the device file: it defines the interrupt vector table specific to the device and provides a set of clock management functions (SystemInit(), SystemCoreUpdate() and some basic nvic functions). Typically done in C. The .h file here is very important.
3) the core file: defines a set of routines across CMx chips and key register mapping.

For the most part, they are transparent to the programmer.
================================
https://dannyelectronics.wordpress.com/
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #9 on: June 19, 2014, 09:15:00 am »
Here is another good general ARM tutorial, explaining the toolchain, the linker scripts etc.
http://www.bravegnu.org/gnu-eprog/index.html

And a very decent but brief walkthrough from compiling down to JTAG, but for STM32:
http://www.triplespark.net/elec/pdev/arm/stm32.html

I don't have issues with IDEs like LPCxpresso, but those things often hide everything behind an impenetrable wall of "black magic". OK if you want to get going quickly, but not when you are trying to learn and understand what is actually going on.

There is also another thread going with a lot of good pointers:
https://www.eevblog.com/forum/microcontrollers/arm-begginer-questions/

 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
Re: Cortex M3 hand holding tutorial
« Reply #10 on: June 19, 2014, 06:56:23 pm »
I gotta say, I'm a gcc fan but IAR looks like a nice package.  From the YouTube videos above, it seems focused on getting down to business.  Every little thing in LPCXpresso (Eclipse) is obscured by wizards and step-by-step dialogs that do who-knows-what.  Ugh.  Like you said, impenetrable black magic.  I find that much harder to understand than compiling things by hand on the CLI, for e.g.

Thanks everyone for the great links and such.  Keep it coming.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #11 on: June 19, 2014, 07:11:43 pm »
Quote
And a very decent but brief walkthrough from compiling down to JTAG, but for STM32:

Way too complicated, in my view.

Depending on where I start, I can do the blinky and/or the FPU examples there within 15 minutes for sure, and likely within a couple minutes, in most IDEs (Keil / IAR / CoIDE or even LPCxpresso).

There actually are minimum differences between the various IDEs, as long as you understand how a typical project is set up, how to link in source / header / library files and how to set up the various switches. After that, you can easily replicate whatever you do on one IDE to another.
================================
https://dannyelectronics.wordpress.com/
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #12 on: June 23, 2014, 08:39:32 am »

Way too complicated, in my view.

Depending on where I start, I can do the blinky and/or the FPU examples there within 15 minutes for sure, and likely within a couple minutes, in most IDEs (Keil / IAR / CoIDE or even LPCxpresso).

There actually are minimum differences between the various IDEs, as long as you understand how a typical project is set up, how to link in source / header / library files and how to set up the various switches. After that, you can easily replicate whatever you do on one IDE to another.


Yeah, I am not arguing with that. If  you are an experienced engineer, have the means to get these tools and want to be productive quickly, buy the toolchain and IDE and off you go. It is certainly faster than compiling/setting up own toolchain, IDE, what not. That's what these things are for, finally.

However, for a newbie learning the platform, these "magic" IDEs won't do you any favours. If you want to go beyond the "Arduino-like magic button pushing" stage, one has to have the understanding how the code is actually compiled and what is going on behind the GUI. I have been teaching basic C/C++ programming to university students for several years and giving these folks something like Eclipse, Visual Studio or XCode was a sure-fire way to get them lost with the distractions of the IDE right there. If the code compilation, linking and deployment is reduced to a single click of the "Build" button, then good luck trying to explain the difference between a syntax and linking error, for example - everything becomes "it doesn't compile!" error ...

I am a fairly experienced software developer myself, but when I started with ARM, it helped me a lot to actually see what is going on with the startup code, how the linker scripts are set up, how to make gdb talk to my JTAG, etc. Tools like LPCExpresso or Keil that I have tried are hiding these things from you - it somehow does the right thing, but good luck figuring out what is going on there if you don't even know what to look for yet!

To conclude - you need to distinguish whether the objective is to bang out code quickly (then go for an IDE) or learning and pedagogy.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #13 on: June 23, 2014, 09:29:24 am »
Quote
but when I started with ARM, it helped me a lot to actually see what is going on with the startup code, how the linker scripts are set up, how to make gdb talk to my JTAG, etc. Tools like LPCExpresso or Keil that I have tried are hiding these things from you

If they are hiding it from you, they are hiding it in plain sight: they are right there, in your project directory or linked directory, depending on how you set up the tools. If anything, any IDE makes it far easier for you to trace through the various files and see how they work together.
================================
https://dannyelectronics.wordpress.com/
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #14 on: June 23, 2014, 03:40:44 pm »
Quote
but when I started with ARM, it helped me a lot to actually see what is going on with the startup code, how the linker scripts are set up, how to make gdb talk to my JTAG, etc. Tools like LPCExpresso or Keil that I have tried are hiding these things from you

If they are hiding it from you, they are hiding it in plain sight: they are right there, in your project directory or linked directory, depending on how you set up the tools. If anything, any IDE makes it far easier for you to trace through the various files and see how they work together.

Dannyf, you have managed to completely miss my point. The "plain sight" is much less plain when a) you aren't aware that you need some sort of "startup file" to begin with, b) that the application will not work unless you use the correct linker script (and there could be different ones even for the same chip!), c) any of the power or RCC/NVIC/pin mapping idiosyncrasies isn't handled right, etc.

That is the main value of doing the "bare bones" tutorials - to learn how things actually fit together, then you will know what to look for in the IDE. Remember, we are talking a complete newb here, perhaps someone who did some Arduino or PC programming, where all these things are taken care of by the default compiler setup and much simpler hardware.

Then the person switches to an ARM IDE, where this is set up for you "in plain sight" using vendor libraries and tools and wonders why the project suddenly doesn't work at all, even though they just wanted to put some LED on another port - e.g. because power or clock to that port that isn't used in the vendor's example wasn't enabled. Good luck tracking that down if you don't know what you are looking for!

I am certainly not advocating doing bare bones programming for production nor bashing IDEs as such. I am only speaking from experience of having to teach this stuff to complete neophytes for four years at a university.





 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #15 on: June 23, 2014, 09:35:42 pm »
-when a) you aren't aware that you need some sort of "startup file" to begin with, -

startup files are not unique to arm chips or ide. Every mcu has them.

-b) that the application will not work unless you use the correct linker script (and there could be different ones even for the same chip!), -

that is actually a non issue for ide - I have yet run into an IDE where the default linker doesn't work.

-c) any of the power or RCC/NVIC/pin mapping idiosyncrasies isn't handled right, etc.-

again that's not unique to ide.

I don't think any of the examples above represents extra difficulties brought on by the use of an IDE.

================================
https://dannyelectronics.wordpress.com/
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #16 on: June 24, 2014, 01:47:36 pm »
-when a) you aren't aware that you need some sort of "startup file" to begin with, -

startup files are not unique to arm chips or ide. Every mcu has them.


Show me one for an ATMega or PIC then. You won't find anything comparable to the typical ARM startup file (power and clock tree setup) on these. Some PICs have PLL, but that's about it.


-b) that the application will not work unless you use the correct linker script (and there could be different ones even for the same chip!), -

that is actually a non issue for ide - I have yet run into an IDE where the default linker doesn't work.

The issue is not that it won't work but that you may have to modify it - e.g. to put some data in flash. Again not something that is common on the smaller micros like the ATMega (there you use compiler directives for doing the same). Not specifically an "IDE problem", but it is a lot easier to be aware of it when you do things "bare bones" first.

Anyway, I think we will have to agree to disagree here. You are obviously seeing it from the view point of an engineer doing this professionally every day, I am speaking from the position of someone who had to teach the programming basics to newbies. You would likely change your mind quickly if you had to teach this to someone who thinks that setting up a webpage is "programming" (that was the level of the students we had coming into the courses ...). IDE becomes a real distraction really quick in that case. Teach the simple/basic stuff first, move on to more complex topics/tools later!

Cheers,
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #17 on: June 24, 2014, 03:35:19 pm »
Quote
Show me one for an ATMega or PIC then.

Fairly easy:

1) the best place to look for them is in the .lss/.lst files: you will see a vector table (avr), a initialization section, and a call to main() - that's identical to what you see on those ARM chips (and pretty much anything else).
2) MPLAB I think also create a stylized strat-up.c in the project folder. gcc-avr utilizes a set of crt*.* files for start-up - you can google them as well.

Quote
(power and clock tree setup) on these.

Gating of clocks is not available on most pic / avr so you obviously wouldn't find them there.

Quote
IDE becomes a real distraction really quick in that case. Teach the simple/basic stuff first, move on to more complex topics/tools later!

I actually find it the exact opposite. Maybe your perception, which I am sure is 100% legit, is a result of your way of doing things.
================================
https://dannyelectronics.wordpress.com/
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #18 on: June 24, 2014, 04:09:52 pm »
-when a) you aren't aware that you need some sort of "startup file" to begin with, -

startup files are not unique to arm chips or ide. Every mcu has them.

Show me one for an ATMega or PIC then. You won't find anything comparable to the typical ARM startup file (power and clock tree setup) on these. Some PICs have PLL, but that's about it.
PICs and other controllers generally need a startup file written in assembly to setup the stack, clear the memory and initialise variables. The beauty of Cortex Mx devices is that they don't need all that because they can start a C binary directly and call C functions directly from an interrupt. This means you can write all the software in 100% pure C.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online Bassman59

  • Super Contributor
  • ***
  • Posts: 1451
  • Country: us
  • Yes, I do this for a living
Re: Cortex M3 hand holding tutorial
« Reply #19 on: June 24, 2014, 04:30:16 pm »
Anyway, I think we will have to agree to disagree here. You are obviously seeing it from the view point of an engineer doing this professionally every day, I am speaking from the position of someone who had to teach the programming basics to newbies.

I agree ... someone coming from the world of host application programming doesn't have the first clue that a startup file is necessary.
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #20 on: June 24, 2014, 08:43:22 pm »
PICs and other controllers generally need a startup file written in assembly to setup the stack, clear the memory and initialise variables. The beauty of Cortex Mx devices is that they don't need all that because they can start a C binary directly and call C functions directly from an interrupt. This means you can write all the software in 100% pure C.

I beg your pardon? How do you start a "C binary" directly?  (btw, what is a "C binary"? Is it any different from an "assembler binary"?) The variable init, stack setup etc. you have on the Cortex-es too - and more. Mainly clock and power setup, which the PICs/AVRs and similar typically don't have, because of simpler hardware.

 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #21 on: June 24, 2014, 08:53:05 pm »
Quote
The beauty of Cortex Mx devices is that they don't need all that because they can start a C binary directly and call C functions directly from an interrupt.

That's probably one of those "perfect understanding" of yours that is less than proper.

The start-up files I have seen are mostly assembly source files, and C source file in one case.

Quote
How do you start a "C binary" directly?

My reaction exactly, :)
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #22 on: June 24, 2014, 08:59:40 pm »
On PIC start-up file:

here is one generated by XC8 under MPLAB for a PIC12F675 project that I worked on.

Code: [Select]

; Microchip MPLAB XC8 C Compiler V1.12
; Copyright (C) 1984-2012 HI-TECH Software

; Auto-generated runtime startup code for final link stage.

;
; Compiler options:
;
; -o12f675 rmw.cof -m12f675 rmw.map --summary=default --output=default \
; main.p1 gpio.p1 --chip=12F675 -P --runtime=default --opt=default -N-1 \
; -D__DEBUG=1 -g --asmlist --errformat=Error   [%n] %f; %l.%c %s \
; --msgformat=Advisory[%n] %s --warnformat=Warning [%n] %f; %l.%c %s
;


processor 12F675

global _main,start,reset_vec
fnroot _main
psect config,class=CONFIG,delta=2
psect idloc,class=IDLOC,delta=2
psect code,class=CODE,delta=2
psect powerup,class=CODE,delta=2
psect reset_vec,class=CODE,delta=2
psect maintext,class=CODE,delta=2
C set 0
Z set 2
PCL set 2
INDF set 0

OSCCAL equ 0x90
psect osccal,class=CODE,delta=2
global ___osccal_val
___osccal_val:
;oscillator constant would be pre-programmed here
STATUS equ 3
PCLATH equ 0Ah

psect eeprom_data,class=EEDATA,delta=2,space=2
psect intentry,class=CODE,delta=2
psect functab,class=CODE,delta=2
global intlevel0,intlevel1,intlevel2, intlevel3, intlevel4, intlevel5
intlevel0:
intlevel1:
intlevel2:
intlevel3:
intlevel4:
intlevel5:
psect init,class=CODE,delta=2
psect cinit,class=CODE,delta=2
psect text,class=CODE,delta=2
psect end_init,class=CODE,delta=2
psect clrtext,class=CODE,delta=2
FSR set 4
psect strings,class=CODE,delta=2,reloc=256

psect reset_vec
reset_vec:
; No powerup routine
; No interrupt routine


psect init
start
psect end_init
bsf STATUS,5 ;select bank 1
fcall ___osccal_val
movwf 0x90 ^ 0x80
bcf STATUS,5 ;select bank 0
global start_initialization
ljmp start_initialization ;jump to C runtime clear & initialization

; Config register CONFIG @ 0x2007
; Brown-out Detect Enable bit
; BOREN = OFF, BOD disabled
; Data Code Protection bit
; CPD = OFF, Data memory code protection is disabled
; Oscillator Selection bits
; FOSC = INTRCIO, INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN
; GP3/MCLR pin function select
; MCLRE = OFF, GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD
; Watchdog Timer Enable bit
; WDTE = OFF, WDT disabled
; Code Protection bit
; CP = OFF, Program Memory code protection is disabled
; Power-Up Timer Enable bit
; PWRTE = OFF, PWRT disabled

psect config
org 0x0
dw 0x3194


psect bank0,class=BANK0,space=1
psect bank1,class=BANK1,space=1
psect ram,class=RAM,space=1
psect abs1,class=ABS1,space=1
psect common,class=COMMON,space=1
psect sfr0,class=SFR0,space=1
psect sfr1,class=SFR1,space=1


end start
[/quote]
================================
https://dannyelectronics.wordpress.com/
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #23 on: June 24, 2014, 09:08:42 pm »
PICs and other controllers generally need a startup file written in assembly to setup the stack, clear the memory and initialise variables. The beauty of Cortex Mx devices is that they don't need all that because they can start a C binary directly and call C functions directly from an interrupt. This means you can write all the software in 100% pure C.

I beg your pardon? How do you start a "C binary" directly? 
Simple. First you need an interrupt vector table.
Code: [Select]
typedef struct TCortexIrq
{
uint32_t __initial_sp;              // 0x00 Top of Stack
uint32_t Reset_Handler;             // 0x04 Reset Handler
uint32_t NMI_Handler;               // 0x08 NMI Handler
uint32_t HardFault_Handler;         // 0x0c Hard Fault Handler
uint32_t dummy1;                    // 0x10 reserved
uint32_t dummy2;                    // 0x14 Reserved

-snip-

uint32_t WDT_IRQHandler;            // 16+25: Watchdog Timer
uint32_t BOD_IRQHandler;           // 16+26: Brown Out Detect
uint32_t dummy13;                         // 16+27: Reserved
uint32_t PIOINT3_IRQHandler3;        // 16+28: PIO INT3
uint32_t PIOINT2_IRQHandler2;        // 16+29: PIO INT2
uint32_t PIOINT1_IRQHandler1;        // 16+30: PIO INT1
uint32_t PIOINT0_IRQHandler0;        // 16+31: PIO INT0
} TCortexIrq;
Then that needs to be initialized and put in a section which is at the start of the memory:
Code: [Select]
extern void _stack_end();

//Interrupt table. The first entry is the stack pointer the second entry points to main
const TCortexIrq CortexIrq  __attribute__((section("vectors"))) ={
.__initial_sp=(uint32_t) _stack_end, //SP at the end of the memory
.Reset_Handler=(uint32_t) main,
.HardFault_Handler=(uint32_t) hardfault_handler,
.TIMER32_0_IRQHandler=(uint32_t) timer_handler,
.UART_IRQHandler=(uint32_t) UART0_IRQHandler,
};
Now the controller will call main and initialise the stack pointer with the value from _stack_end after a reset. The 'symbol' _stack_end is defined in the linker description file. Next we need some initialisation:
Code: [Select]
extern void __bss_start__();
extern void _bss_end();
extern void _data();
extern void _edata();
extern void _stack_end();
extern void _datastart();

int  main()
{
memset(_data, 0, _stack_end - __bss_start__-32); //clear memory including most of the stack
memcpy(_data, _datastart , _edata-_data); //copy initialiased variables

SystemInit();
__enable_irq();

- run the firmware -
}
SystemInit() is located in a file from the CMSIS part and initialises the PLL and clock. __enable_irq() is a macro from core_cm0.h.
The linker descriptor file looks like this:
Code: [Select]
/* ****************************************************************************************************** */
/*   lpc1113.ld LINKER  SCRIPT                                   */
/*                                                                                                        */

/* identify the Entry Point  */
MEMORY
{
flash : ORIGIN = 0,          LENGTH = 24K /* FLASH ROM                            */
ram    : ORIGIN = 0x10000000, LENGTH = 4K /* free RAM area */
}

/* now define the output sections  */
SECTIONS
{
. = 0; /* set location counter to address zero  */

startup : { *(vectors)} >flash /* the startup code goes into FLASH */

.text : /* collect all sections that should go into FLASH after startup  */
{
*(.init)
*(.text) /* all .text sections (code)  */
*(.glue_7)
*(.glue_7t)
_etext = .; /* define a global symbol _etext just after the last code byte */
*(.rodata) /* all .rodata sections (constants, strings, etc.)  */
*(.rodata*) /* all .rodata* sections (constants, strings, etc.)  */
_datastart = .;
*(.data)
} >flash /* put all the above into FLASH */

.data : /* collect all initialized .data sections that go into RAM  */
{
_data = .; /* create a global symbol marking the start of the .data section  */
*(.data) /* all .data sections  */
_edata = .; /* define a global symbol marking the end of the .data section  */
} >ram AT >flash /* put all the above into RAM (but load the LMA copy into FLASH) */

.bss : /* collect all uninitialized .bss sections that go into RAM  */
{
__bss_start__ = .; /* define a global symbol marking the start of the .bss section */
*(.bss) /* all .bss sections  */
*(COMMON)
__bss_end__ = .; /* define a global symbol marking the start of the .bss section */

. +=  ( LENGTH(ram) - . ) - 32 ;
_stack_end = .;

} >ram /* put all the above in RAM (it will be cleared in the startup code */

. = ALIGN(4); /* advance location counter to the next 32-bit boundary */
_bss_end = . ; /* define a global symbol marking the end of the .bss section */
}

_end = .; /* define a global symbol marking the end of application RAM */
See? Not a single line of assembly language required and nothing hidden under the hood.
« Last Edit: June 24, 2014, 09:13:13 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #24 on: June 24, 2014, 09:44:04 pm »
Quote
Simple.

That's a C start-up file. We are still waiting for your "C binary".

:)
================================
https://dannyelectronics.wordpress.com/
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #25 on: June 24, 2014, 09:46:31 pm »
 :palm: Never heard of a compiler?
« Last Edit: June 24, 2014, 09:48:14 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #26 on: June 24, 2014, 09:49:11 pm »
I think regulator people would call that "binary".

Maybe people with "perfect understanding" would call that "C binary", :)
================================
https://dannyelectronics.wordpress.com/
 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
Re: Cortex M3 hand holding tutorial
« Reply #27 on: June 24, 2014, 10:37:12 pm »
It seems to come down to the fact that people are often comfortable with one of two styles:

1) Know nothing, and poke at it until works.  If it quits working, poke at it until it works again.  Fill in gaps as necessary along the way.  I think in psychology, this is called the procedural learning style.  Step-by-step.  If it breaks, learn a new procedure.

2) Understand how all the essential cogs turn, so an educated guess can be made at how to start from scratch, and how to anticipate, or at least fix errors that come up.  This is the intuitive learning style.  If it breaks, find out why, and consider how to apply this in the future.

I'm in the second camp.  Using an IDE is terrifying for me, because so much stuff "just happens", which means I don't know exactly what actually ended up on the chip, or really how it got there.  I know I wrote some code, and it seems to be doing more or less the right thing, but I can't be confident that I did everything correctly.  In which case, there's a good chance a different IC or a particular interrupt or a change in clock frequency could bring the whole house of cards down.  Not great for confidence.

In my line of work, I've noticed most people seem to be Type 1s.  They just go about their job and do what they've been told (or learned) to do.  There isn't much thought about whether what they've been told is always, only sometimes, or not at all correct.  If they do what they're told but a process fails, well...  *shrug*  I followed the procedure I was given, didn't I?

Now, once you know what happens under the hood, an IDE can automate all of that tedious stuff and make your life easier.  Great!  But I agree wholeheartedly that, while you're learning, it's a distraction and makes it 10x harder to understand where and why something failed.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #28 on: June 24, 2014, 10:59:13 pm »
Now, once you know what happens under the hood, an IDE can automate all of that tedious stuff and make your life easier.  Great!  But I agree wholeheartedly that, while you're learning, it's a distraction and makes it 10x harder to understand where and why something failed.
IMHO it depends on what kind of IDE you are referring to. Some have extensive code generator wizards which can come up with all kinds of initialisation routines. Others 'only' automate building by hiding the process of creating makefiles and help to organize your source code.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Cortex M3 hand holding tutorial
« Reply #29 on: June 24, 2014, 11:32:04 pm »
The start-up files I have seen are mostly assembly source files, and C source file in one case.
And what should the rest of us derive from *your* experience with looking at startup files? You spend your time working with outdated processors and apparently rarely leave the safety of your IDE. You talk like an expert, but I'm not so sure...

Have you ever written code to start up a Cortex M3 from the reset vector?
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3197
  • Country: us
Re: Cortex M3 hand holding tutorial
« Reply #30 on: June 24, 2014, 11:52:01 pm »
Quote
The start-up files I have seen are mostly assembly source files, and C source file in one case.
The Keil ARM compiler used for Tiva Launchpad seems to be in assembler.  The version used in the recent UTX "embedded programming" class was modified to be "barer" than normal.  Pretty understandable, even without a detailed knowledge of ARM ASM.  I guess.  (Full of linker/debugging magic commands like:
Code: [Select]
MemManage_Handler\
                PROC
                EXPORT  MemManage_Handler         [WEAK]
                B       .
                ENDP

It seems to be a trend in modern microcontroller IDEs to copy all the startup files (and similar) into the user's "project" space in source for, instead of leaving it as binary off in some random hidden system location.  I can't argue too much with that, but it is something that desktop programmers are probably not used to.

Quote
The beauty of Cortex Mx devices is that they don't need all that because they can start a C binary directly and call C functions directly from an interrupt.
That's a lot of praise for what amounts to "the initial SP is loaded from a known memory location, and the context saved by the ISR hardware is the same a defined to caller-saved by the C ABI."  You still need assembler to do things like "turn on interrupts."
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #31 on: June 25, 2014, 12:14:47 am »
On an LPC1113 (Cortex M0) the interrupts are enabled by default so no need for assembler there.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #32 on: June 25, 2014, 12:19:17 am »
Quote
Show me one for an ATMega or PIC then.

In case you are still interested, this is the avr start-up file in 1.8.0  - it hasn't changed for a long time.

Code: [Select]
/* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl>
   Copyright (c) 2007, 2008 Eric B. Weddington
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.

   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.

   * Neither the name of the copyright holders nor the names of
     contributors may be used to endorse or promote products derived
     from this software without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */

/* $Id: gcrt1.S 2114 2010-03-31 05:12:22Z arcanum $ */

#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
#error "GCC version >= 3.3 required"
#endif

#include "macros.inc"

.macro vector name
.if (. - __vectors < _VECTORS_SIZE)
.weak \name
.set \name, __bad_interrupt
XJMP \name
.endif
.endm

.section .vectors,"ax",@progbits
.global __vectors
.func __vectors
__vectors:
XJMP __init
vector __vector_1
vector __vector_2
vector __vector_3
vector __vector_4
vector __vector_5
vector __vector_6
vector __vector_7
vector __vector_8
vector __vector_9
vector __vector_10
vector __vector_11
vector __vector_12
vector __vector_13
vector __vector_14
vector __vector_15
vector __vector_16
vector __vector_17
vector __vector_18
vector __vector_19
vector __vector_20
vector __vector_21
vector __vector_22
vector __vector_23
vector __vector_24
vector __vector_25
vector __vector_26
vector __vector_27
vector __vector_28
vector __vector_29
vector __vector_30
vector __vector_31
vector __vector_32
vector __vector_33
vector __vector_34
vector __vector_35
vector __vector_36
vector __vector_37
vector __vector_38
vector __vector_39
vector __vector_40
vector __vector_41
vector __vector_42
vector __vector_43
vector __vector_44
vector __vector_45
vector __vector_46
vector __vector_47
vector __vector_48
vector __vector_49
vector __vector_50
vector __vector_51
vector __vector_52
vector __vector_53
vector __vector_54
vector __vector_55
vector __vector_56
vector __vector_57
vector __vector_58
vector __vector_59
vector __vector_60
vector __vector_61
vector __vector_62
vector __vector_63
vector __vector_64
vector __vector_65
vector __vector_66
vector __vector_67
vector __vector_68
vector __vector_69
vector __vector_70
vector __vector_71
vector __vector_72
vector __vector_73
vector __vector_74
vector __vector_75
vector __vector_76
vector __vector_77
vector __vector_78
vector __vector_79
vector __vector_80
vector __vector_81
vector __vector_82
vector __vector_83
vector __vector_84
vector __vector_85
vector __vector_86
vector __vector_87
vector __vector_88
vector __vector_89
vector __vector_90
vector __vector_91
vector __vector_92
vector __vector_93
vector __vector_94
vector __vector_95
vector __vector_96
vector __vector_97
vector __vector_98
vector __vector_99
vector __vector_100
vector __vector_101
vector __vector_102
vector __vector_103
vector __vector_104
vector __vector_105
vector __vector_106
vector __vector_107
vector __vector_108
vector __vector_109
vector __vector_110
vector __vector_111
vector __vector_112
vector __vector_113
vector __vector_114
vector __vector_115
vector __vector_116
vector __vector_117
vector __vector_118
vector __vector_119
vector __vector_120
vector __vector_121
vector __vector_122
vector __vector_123
vector __vector_124
vector __vector_125
vector __vector_126
vector __vector_127
.endfunc

/* Handle unexpected interrupts (enabled and no handler), which
   usually indicate a bug.  Jump to the __vector_default function
   if defined by the user, otherwise jump to the reset address.

   This must be in a different section, otherwise the assembler
   will resolve "rjmp" offsets and there will be no relocs.  */

.text
.global __bad_interrupt
.func __bad_interrupt
__bad_interrupt:
.weak __vector_default
.set __vector_default, __vectors
XJMP __vector_default
.endfunc

.section .init0,"ax",@progbits
.weak __init
; .func __init
__init:

#ifndef __AVR_ASM_ONLY__
.weak __stack

/* By default, malloc() uses the current value of the stack pointer
   minus __malloc_margin as the highest available address.

   In some applications with external SRAM, the stack can be below
   the data section (in the internal SRAM - faster), and __heap_end
   should be set to the highest address available for malloc().  */
.weak __heap_end
.set __heap_end, 0

.section .init2,"ax",@progbits
clr __zero_reg__
out AVR_STATUS_ADDR, __zero_reg__
ldi r28,lo8(__stack)
#ifdef _HAVE_AVR_STACK_POINTER_HI
ldi r29,hi8(__stack)
out AVR_STACK_POINTER_HI_ADDR, r29
#endif /* _HAVE_AVR_STACK_POINTER_HI */
out AVR_STACK_POINTER_LO_ADDR, r28

#ifdef __AVR_3_BYTE_PC__
ldi r16, hh8(pm(__vectors))
out _SFR_IO_ADDR(EIND), r16
#endif /* __AVR_3_BYTE_PC__ */

#ifdef __AVR_HAVE_RAMPD__
out AVR_RAMPD_ADDR, __zero_reg__
out AVR_RAMPX_ADDR, __zero_reg__
out AVR_RAMPY_ADDR, __zero_reg__
out AVR_RAMPZ_ADDR, __zero_reg__
#endif

#if defined(__GNUC__) && ((__GNUC__ <= 3) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 3))
#if BIG_CODE
/* Only for >64K devices with RAMPZ, replaces the default code
   provided by libgcc.S which is only linked in if necessary.  */

.section .init4,"ax",@progbits
.global __do_copy_data
__do_copy_data:
ldi r17, hi8(__data_end)
ldi r26, lo8(__data_start)
ldi r27, hi8(__data_start)
ldi r30, lo8(__data_load_start)
ldi r31, hi8(__data_load_start)

/* On the enhanced core, "elpm" with post-increment updates RAMPZ
   automatically.  Otherwise we have to handle it ourselves.  */

#ifdef __AVR_ENHANCED__
ldi r16, hh8(__data_load_start)
#else
ldi r16, hh8(__data_load_start - 0x10000)
.L__do_copy_data_carry:
inc r16
#endif
out AVR_RAMPZ_ADDR, r16
rjmp .L__do_copy_data_start
.L__do_copy_data_loop:
#ifdef __AVR_ENHANCED__
elpm r0, Z+
#else
elpm
#endif
st X+, r0
#ifndef __AVR_ENHANCED__
adiw r30, 1
brcs .L__do_copy_data_carry
#endif
.L__do_copy_data_start:
cpi r26, lo8(__data_end)
cpc r27, r17
brne .L__do_copy_data_loop
#ifdef __AVR_HAVE_RAMPD__
out AVR_RAMPZ_ADDR, __zero_reg__
#endif /* __AVR_HAVE_RAMPD__*/

#endif /* BIG_CODE */
#endif /* defined(__GNUC__) && ((__GNUC__ <= 3) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 3)) */

.set __stack, RAMEND
#endif /* !__AVR_ASM_ONLY__ */

.section .init9,"ax",@progbits
#ifdef __AVR_ASM_ONLY__
XJMP main
#else /* !__AVR_ASM_ONLY__ */
XCALL main
XJMP exit
#endif /* __AVR_ASM_ONLY__ */
; .endfunc


As you can see, the pattern is identical: load up the interrupt vector table, some house keeping items and then call main().
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: Cortex M3 hand holding tutorial
« Reply #33 on: June 25, 2014, 12:19:57 am »
Quote
no need for assembler there.

Is that done in your "C binary" file too?
================================
https://dannyelectronics.wordpress.com/
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Cortex M3 hand holding tutorial
« Reply #34 on: June 25, 2014, 12:37:58 am »
That's a lot of praise for what amounts to "the initial SP is loaded from a known memory location, and the context saved by the ISR hardware is the same a defined to caller-saved by the C ABI."  You still need assembler to do things like "turn on interrupts."
Maybe not a huge issue in the grand scheme of things, but it's nice that the Cortex designers did what they could to make it possible to write system code directly in standard C. Memory mapped peripherals also help. Interrupt stuff and access to other registers is generally available through intrinsic functions. It's debatable whether intrinsics should count as C (especially when you get down to inline assembly), but IMO it's preferable to do as much as possible in a high level language and only dip down to the lower level when absolutely necessary.

One of my pet peeves is the code you see from OEMs and IDE vendors that's needlessly dependent on startup code written in assembly. For example, it's not unusual to see the .bss section of RAM being initialized by a loop in assembly code. Sure, it's fast, but the same loop in C would take only a few cycles more and be much more understandable.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Cortex M3 hand holding tutorial
« Reply #35 on: June 25, 2014, 12:42:31 am »
Quote
no need for assembler there.

Is that done in your "C binary" file too?
Maybe one of those "assembly binary" files?  :-//
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #36 on: June 25, 2014, 09:04:24 pm »
As you can see, the pattern is identical: load up the interrupt vector table, some house keeping items and then call main().

Danny, you are nitpicking over details and missing the forest for the trees, IMO. I am not sure what is your goal here. Are you trying to debunk my entire argument by picking a random (not very relevant) detail and showing that I am wrong on it?

Moreover, the file you are showing is a red herring. It is actually part of the avr-libc runtime. You pretty much never deal with that part yourself, neither on ARM, nor AVR or any other architecture. It is a part of the compiler toolchain for the platform and different toolchains will have different runtime code like that.

That AVR chip will work just fine if you don't do anything in that file, it is needed only to run a binary compiled with GCC, so that the expected symbols (like the interrupt vectors) are defined for the linker, the heap/stack are in the expected locations in memory, etc. If you program in assembler, you can pretty much ignore everything in that file and things will work just fine. Nothing in that file is doing any hardware initialization whatsoever.

What I was talking about as a "start file" is the part of user's code where stuff like clock is being set up, Flash is initialized or peripherals powered up. That could be called from these runtime files, but could be also invoked by the user's code from main(). AVRs don't have anything like that - mainly because the architecture is much simpler compared to ARM.

Which leads exactly to the point of why a newbie coming from e.g. an Arduino/AVR environment to ARM via a "black box" IDE could be screwed - they aren't used to needing to do this stuff (or to include the right vendor-provided files in their project). Most often this code is hidden somewhere in some vendor library code (e.g. inside CMSIS) - for example, for the LPCExpresso IDE the basic blink-a-LED example includes a fairly sizeable cr_startup_lpc176x.c that invokes SystemInit() from CMSIS towards the end - which does all the "magic" around clock and PLL setup. You have to dig for it to find it (it is not inside your project, CMSIS is an external dependency!). That assumes that you know what you are looking for, of course - this is code executed before user's main() is run, so it is not obvious that it is there for a newbie! And unlikely the library/runtime setup code, things like the PLL multipliers or the various clock prescalers are something that needs to be changed quite often by the developer to adapt the code to their hw.

« Last Edit: June 25, 2014, 09:37:49 pm by janoc »
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #37 on: June 25, 2014, 09:56:43 pm »
Why would you need to change the clock or prescalers? I set them up once and re-use the same settings for every project. The easiest thing to do is have everything run at full speed. Only when you are working on very low power it may be necessary to switch to lower clocks. But then again ultra low power is not the strong suit of most ARM controllers anyway.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Dago

  • Frequent Contributor
  • **
  • Posts: 657
  • Country: fi
    • Electronics blog about whatever I happen to build!
Re: Cortex M3 hand holding tutorial
« Reply #38 on: June 26, 2014, 06:30:16 am »
But then again ultra low power is not the strong suit of most ARM controllers anyway.

I guess your point is the word "most" but I still need to point out that in relation to computing power the most lowest power MCUs are ARMs. Even in absolute stand-by/idle power use low-power ARMs tend to have one of the lowest power usages. In absolute terms MSP430s or some PICs might have lower power use but the µA/MHz is about the same or higher as ARMs.
Come and check my projects at http://www.dgkelectronics.com ! I also tweet as https://twitter.com/DGKelectronics
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #39 on: June 26, 2014, 07:07:20 pm »
Why would you need to change the clock or prescalers? I set them up once and re-use the same settings for every project. The easiest thing to do is have everything run at full speed. Only when you are working on very low power it may be necessary to switch to lower clocks. But then again ultra low power is not the strong suit of most ARM controllers anyway.

For example when you are taking a project and want to move it to another, different board. Or change the clock frequency/crystal. That alone will force you change the various prescalers to keep the PLL input within the allowed limits and to adapt the output to what the various peripherals need - e.g. USB often rigidly requires 48MHz clock. Or you want to switch from external clock to the internal RC oscillator. Or you don't need full speed and want to run slower to reduce current consumption/heat. It is a fairly common thing to do. I am quite surprised that you don't know this.

And re low power - I am not sure where are you getting such info, STM32F103 takes about 5-50mA in run mode, depending on what you have enabled. In low power modes it is much less - e.g. in standby, running on the low speed clock, it takes around 1uA (!). And that is not really a chip optimized for such use. The Energy Micro EMF32 series is known for its low power capabilities - those things work down to tenth of nA! E.g. look here: http://www.silabs.com/products/mcu/lowpower/pages/efm32wg-wonder-gecko.aspx  Dave did even a video on Gecko demo board.

« Last Edit: June 26, 2014, 07:09:13 pm by janoc »
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #40 on: June 26, 2014, 08:00:04 pm »
Why would you need to change the clock or prescalers? I set them up once and re-use the same settings for every project. The easiest thing to do is have everything run at full speed. Only when you are working on very low power it may be necessary to switch to lower clocks. But then again ultra low power is not the strong suit of most ARM controllers anyway.

For example when you are taking a project and want to move it to another, different board. Or change the clock frequency/crystal. That alone will force you change the various prescalers to keep the PLL input within the allowed limits and to adapt the output to what the various peripherals need - e.g. USB often rigidly requires 48MHz clock. Or you want to switch from external clock to the internal RC oscillator. Or you don't need full speed and want to run slower to reduce current consumption/heat. It is a fairly common thing to do.
Not really in my world. If I use an USB enabled controller I have always have a 12MHz crystal next to it. Once setup I never have to touch it again. Same goes for controllers with an internal RC oscillators. I already mentioned the exception when it comes to power reduction. Anyway a newbie shouldn't need to worry much about having to change the PLL setup for every design.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
Re: Cortex M3 hand holding tutorial
« Reply #41 on: June 27, 2014, 09:21:12 pm »
Aw man, that's not at all true.  A newbie should indeed know how and where the clocks are configured.  You may be able to "fudge it" with whatever your template / demo code used, but blindly accepting clock setup as a given, or worse, not knowing it's there at all..?  Who would seriously consider that OK?

If you're using USB, you need a multiple of 12MHz.  If you're going for high-speed calculation, you'll want to run as close as possible to it's highest speed.  For an NXP LPC4k, that's upwards of 200MHz.  Most other Cortex Ms can't run that fast, so there's one time where you really have to pay attention.  If speed is not at all a concern and battery life and/or external components are, you need to optimize that way.  Once you get past the very first stage of "I got helloworld.c to compile!" then it is very relevant.
 

Online janoc

  • Super Contributor
  • ***
  • Posts: 3109
  • Country: fr
Re: Cortex M3 hand holding tutorial
« Reply #42 on: June 29, 2014, 11:30:48 pm »
Not really in my world. If I use an USB enabled controller I have always have a 12MHz crystal next to it. Once setup I never have to touch it again. Same goes for controllers with an internal RC oscillators. I already mentioned the exception when it comes to power reduction. Anyway a newbie shouldn't need to worry much about having to change the PLL setup for every design.

It is not about having to but about knowing where and how to change it! Also, without knowing the various prescaler values, good luck trying to figure out what your system clock actually is and what frequency the various peripherals are running at, as these could be different even with the same crystal and PLL settings! How would you configure e.g. timers or PWM in such situation?

nctnico, your statement is really baffling.

 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 19741
  • Country: nl
    • NCT Developments
Re: Cortex M3 hand holding tutorial
« Reply #43 on: June 29, 2014, 11:58:47 pm »
I never said you would never need to touch it or not know it. However as a fresh starter with a microcontroller you start with an example. A good example has a remark which says which clock frequency is being used. That is how you know the clock frequency without knowing about how the PLL and clocks work. In order to move forward quickly you must skip the parts which are not interesting at that moment.

In some designs I use SoCs with manuals having over 4000 pages. I'm not going to read all of them to figure out how to configure the I/O pins. I just skip to the section which describes the I/O pins. I just assume the bootloader and Linux 'know' how the clocks need to be setup.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf