This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Question : The Definitive Guide to the ARM Cortex-M3

Note: This was originally posted on 11th December 2007 at http://forums.arm.com

Dear, all.

I am new in this forum.
Recently I studying Cortex-M3 core, so I bought book "The Definitive Guide to the ARM Cortex-M3" by Joseph Yiu.
This book is very good book and this explains most of unaswered questions by TRM or AALRM.

As I found some mistake in this book, I would like to feedback, but I could not find publisher's homepage. Then I found Josephe's name in this forum, I would like to ask here.

In page 42, there is fig 3.11 and 3.12 but this contents is same as fig 3.8 and 3.9.
Fig 3.8 and 3.9 should be some program list.

Can I get correct figure? Or where I should contact?
Please advise.

Kenichi
  • Note: This was originally posted on 21st January 2010 at http://forums.arm.com

    Thanks Josepth. I was concerned that buying the new edition would be a simple cover change with errata updates. However, it sounds like enough new material to warrent the purchase. So, off to Amazon...  :mellow:

    Dave
  • Note: This was originally posted on 21st January 2010 at http://forums.arm.com

    Thanks Josepth. I was concerned that buying the new edition would be a simple cover change with errata updates. However, it sounds like enough new material to warrent the purchase. So, off to Amazon...  :mellow:

    Dave


    Thanks Dave. Hope you find the book useful. :-)
    Joseph
  • Note: This was originally posted on 23rd January 2010 at http://forums.arm.com

    Joseph,

    your book is really very useful !!

    There is something though that I can't understand or it is not quite precise. On p.135 you mention a "problem with context switching at IRQ".

    If an interrupt request takes place before the SYSTICK exception, the SYSTICK exception
    will preempt the IRQ handler. In this case, the OS should not carry out the context switching.


    this is correct The OS cannot change the context because the IRQ handler may have changed some of the top registers.

    Otherwise the IRQ handler process will be delayed, and for the Cortex-M3, a usage fault
    could be generated if the OS tries to switch to Thread mode when an interrupt is active.


    I have seen several RTOS implementations and it is also quite logical to use only the PSP for the taks. This means that there is no reason to change the LR when you do a context switch.

    And if you do not touch the LR (in SYSTICK) there will be no usage fault.

    And there is no way to delay the IRQs... The core will first try to tail chain all the IRQs that have higher priority than any stacked, and then the execution will return to the stacked ones if any. No user task can get control before all the IRQs are serviced out.

    So I think that there will be no IRQ delays or usage faults. The real problem is the preemption that can destroy the task contexts and the use of PendSvc is the correct solution. Another solution is to lower enough the SYSTICK priority.
    There is one more thing about the priorities. Sometimes you need to call protected system function (SVCs) not only from user tasks but also from ISRs. This means that the SVC exception must have a mid-priority and all kernel-aware IRQs must have lower priority otherwise they will end up with usage fault if they use the SVC instruction.  Then we will have
    - "fast" IRQs
    - SVC
    - kernel aware IRQs
    - SYSTICK
    - PendSV
    - user tasks

    Miro
  • Note: This was originally posted on 23rd January 2010 at http://forums.arm.com

    Hi Miro,

    Good questions!

    In the case of having an IRQ running, and if the IRQ is lower priority than SysTick, then proceeding on context switching usually means the PSP is changed to point to the stack frame of a a different task.
    As a result, when you execute exception return, the PC value of another task will be used and you will end up executing the other tasks with privilege level of the IRQ, which can be bad (user task running at privileged level, and all other IRQs at the same or lower priority level will be blocked).  Therefore context switching code could modify LR to ensure it is switching to unprivileged level, but then it lead to usage fault due to trying to run in Thread mode with an active IRQ.

    In practice I believe Cortex-M3 will flag a usage fault even if LR is not modified because it has various system integrity checkings. When switching to the other task with IPSR equal 0 (which is unstacked from the other task's stack frame) and having an active IRQ should trigger a fault (need double check).

    Lower the SysTick priority is one solution, but if an IRQ handler is not function properly (e.g. accidental software deadloop) the SysTick will not be able to preempt and the system will be frozen.

    Yes, it if possible to have a mid-priority level SVC so that an OS aware IRQ handler can use the SVC function.  But instead of using SVC, you might able to call the SVC function directly rather than using SVC exception.  This is better if you need to port the software to Cortex-M0, which has 4 levels of priority levels.

    Hope this answered your questions and feel free to let me know if you need further explanations.
    regards,
    Joseph
  • Note: This was originally posted on 23rd January 2010 at http://forums.arm.com

    Thanks Joseph,

    I think it is pointless to discuss the case when we have a stacked IRQ before the SYSTICK. The IRQ may have pushed some top registers so the task context cannot be saved easily.

    The only option is to implement the context switching from some exception that has the lowest priority.

    Yes, it if possible to have a mid-priority level SVC so that an OS aware IRQ handler can use the SVC function. But instead of using SVC, you might able to call the SVC function directly rather than using SVC exception.


    I am afraid that is not a good idea. We use SVC for system functions that are not reentrant. So if you have more than one IRQ level using kernel functions then you can't call them directly. Otherwise imagine that IRQ1 has called a system function and it is interrupted from IRQ2 that can also call the same or similar function.

    Hm... actually... you are right ;-) You can use direct calls, but you need to rise the priority first (or disable the IRQs). But then the question is why you would use two different approaches? One for tasks and one for ISRs... Here we need to compare the SVC handler code and the priority veneer code. But if the SVC is the faster then we should use for both tasks and ISRs. Otherwise we should use the "direct" approach.

    btw. I don't like the new SVC very much ;-) For ARM7 I had a SWI handler of only 5 instructions and that was the only overhead. No stack usage at all. Even most of my system functions were stackless so everything was fast & simple. Now with the SWI the handler is going to be about twice as big and slower. So I may consider the direct call as well ;-)
  • Note: This was originally posted on 23rd January 2010 at http://forums.arm.com

    Hi Miro,

    Direct call is faster, but if your user tasks are running at non-privileged level, then you will need SVC to access some of the system functions (e.g. NVIC accesses). Alternatively a user task might be compiled separately from the rest of the application.  In this way using SVC is easier because it doesn't need to know the address of the system function.

    SVC need 12 clock cycles (or more) due to interrupt latency, and will consume more stack space. So I would rather use direct call if possible. (But then I am a hardware guy moving to software, so are lots of software issues I might not aware of  :mellow:  ).

    Yes, if a system function cannot be reentrant, then SVC is an easy way to ensure that only one task/ISR can use it at one time. Another solution is to use the PRIMASK or BASEPRI register which can change the current priority level. So when an IRQ handler is going to use an OS function that another IRQ might use and the function cannot be reentrant, you can use PRIMASK or BASEPRI to block the other IRQ.
    In this way you can directly call the function, would that be okay for your application?
  • Note: This was originally posted on 25th January 2010 at http://forums.arm.com

    Thank you Joseph,

    That is a good point for the privileged mode ;-)

    Yes, I can use both SVC calls and direct calls (+ basepri...) and probably I will test both ways before taking the final decision.

    Once again thank you. Your book is really good guide for everybody switching to the Cortex family. Usually I don't need to read a book to start with a new micro, moreover I think I have deep knowledge about ARM7, but the Cortex core is so complex and without a guide like yours it will take ages to learn it..

    In my opinion there is a lack of good documentation, examples projects and tools for ARM in general. I am surrounded with people and companies which are using more expensive and weaker MCUs simply because they cannot afford to spend so much time and money for the switch. And that is pity... Maybe my sadness is due to my country because as a student my practice was on VAX/PDP11 and that was 20 years ago and now I see in the same university they teach 8/16 bit Microchip ... I don't think this "progress" is in the right direction but such is life ;-)
  • Note: This was originally posted on 25th January 2010 at http://forums.arm.com

    Thanks Miro. 

    Last year we had developed a Cortex-M3 User Guide which is available via microcontroller vendors
    (include as part of their documentation).  For example,
    [url="http://www.st.com/stonline/products/literature/pm/15491.pdf"]STM version[/url] ,
    Other MCU vendors might also have this document available.

    The Cortex-M0 generic user guide is also available on the ARM web site now.

    Maybe you should tell your university about this webminar:
    [url="https://www2.gotomeeting.com/register/741720467"]Migrating Microchip PIC18 or PIC24 projects to ARM® Cortex™-M MCUs [/url]
    - Are you using a Microchip PIC18 or PIC24 microcontroller? Find out how easy it is to migrate your applications to the next generation of microcontroller technology, based on the ARM Cortex-M processors.

    regards,
    Joseph
  • Note: This was originally posted on 11th March 2010 at http://forums.arm.com

    Thanks for the info. :)
  • Note: This was originally posted on 10th April 2010 at http://forums.arm.com

    Joseph - do you know why there is not a Kindle version of the new edition of your book?

    I thought Newnes was a little more "on the ball" (or maybe it's an Amazon issue?)

    Thanks!
  • Note: This was originally posted on 10th April 2010 at http://forums.arm.com

    Joseph - do you know why there is not a Kindle version of the new edition of your book?

    I thought Newnes was a little more "on the ball" (or maybe it's an Amazon issue?)

    Thanks!
  • Note: This was originally posted on 10th April 2010 at http://forums.arm.com

    Joseph -

    Question about the new IF-THEN construct.  Basically, I don't understand the advantage of it over the previous "conditional execution" model that I was so fond of.

    It seems that the 2nd edition of the book gives it a little more treatment, which is good, but I'm still not sold on it.

    I have 2 problems with it.  To illustrate, I'll use the example from the 2nd ed. of the book, table 4.33


    OLD ARM CODE WITH CONDITIONAL EXECUTION:
    [font="Courier New"]
    CMP   R1, #2
    ADDEQ R0, R1, #1
    [/font]

    NEW CODE WITH IF-THEN:
    [font="Courier New"]CMP   R1, #2
    IT    EQ
    ADDEQ R0, R1, #1[/font]


    Forgive me for being cynical, but what I see is:

    (1) More code (3 instructions vs. 2).  This is not good for 2 reasons:
       - longer execution time (* maybe it's not, I'm not up to speed)
       - more code to maintain (3 source lines vs. 2)

    (2) Potential for inconsistency.  Isn't the EQ suffix on the ADD redundant?  The way I read "IT EQ" is "If EQ evaluates to TRUE, THEN execute the next 1 instruction, otherwise don't."  So WHY do we need the EQ suffix on ADD?!?!?  Put another way, what would happen with the following code, would the assembler just spit out an error?

    [font="Courier New"]CMP R1, #2
    IT  EQ
    ADDNE R0, R1, #1[/font]

    So in other words, the conditional suffix doesn't match up with the ITEQ.  This situation cannot happen with the old syntax.

    I will admit I haven't spent lots of time understanding the construct, but IF-THEN seems like a step backwards in code maintainability, and at best a wash when it comes to performance.  Actually it seems like the performance would be worse.  The engineers I've worked with ARM are smart, so clearly I'm missing something (I'm being serious).  Sorry if these issues are addressed in the book, I don't have it handy & I wanted to send this off before I forget.

    Please help sell me on the IF-THEN construct!

    Thanks.
  • Note: This was originally posted on 11th April 2010 at http://forums.arm.com

    Hi Wave,

    I don't know why the second edition of the book is not available for Kindle.
    (In fact, I didn't even notice the first edition is available on Kindle until you mention it.
    Certainly it is not available in the UK web site)
    I will try to arrange a meeting with the publisher in a few weeks time.
    I will take the chance to ask them.

    Yes, the ARM syntax is indeel more straight forward in term of using conditional execution.
    However, the issue is that we cannot use the same instruction encoding solution for Thumb-2.
    With Thumb-2, a large portion of the the instruction space (in terms of binary encoding)
    is already taken by the existing Thumb instructions. We cannot take 4 bits away from
    the 16-bit instructions to make them conditional - it will means the instructions set will not
    be compatible. Alternatively we could make conditional execution available only on
    the 32-bit Thumb instructions, but then it might results in larger code size because
    16-bit version of the instructions cannot be used if they have to be conditionally executed.

    By using a separate 16-bit instruction for conditional execution control, we get the best results:
    - code size is small (see example below)
    - Both 16-bit and 32-bit Thumb instructions can be conditional executed
    - No need to change existin 16-bit instruction encoding

    When comparing the code size:
    OLD ARM CODE WITH CONDITIONAL EXECUTION:

    CMP R1, #2  (32 bits)
    ADDEQ R0, R1, #1 (32 bits)
    (total = 64 bits)

    NEW CODE WITH IF-THEN:
    CMP R1, #2 (16 bits)
    IT EQ (16 bits)
    ADDEQ R0, R1, #1 (16 bits)
    (total = 48 bits)

    Now you can see the code size is actually smaller than the ARM instruction set, although it has one extra instruction.
    Another feature about the IT instruction is called IT folding. (see instruction timing table in
    [url="http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337g/BABBCJII.html"]http://infocenter.arm.com/help/topic/com.a...g/BABBCJII.html[/url] )
    In the some cases, the IT instruction does not take any extra clock cycle.
    (actually, look like there is a doc erratum there, NOP instruction should always take 1 cycle, ouch!)
    So it is possible to get to the same performance as ARM instruction, with a smaller code size.

    If the condition in the IT instruction does not match the condition of the next instruction in the assembly code,
    the assembler will report an error.  However, if you are using ARM RealView Compiler or Keil MDK-ARM, you don't have to add the IT instruction, as the assembler can insert that for you automatically.  However, this feature might not be available in other tool chains. So in general I would recommend to put the IT instruction in the code for clarity and software porting.

    Hope this answered your enquiry.
    regards,
    Joseph
  • Note: This was originally posted on 11th April 2010 at http://forums.arm.com

    Joseph,

    Thanks for your detailed & thoughtful reply.  I'm still more of a "paper book" kind of guy (my first ed. of your book is marked up w/ highlighter and notes!) but the Kindle versions are a lot more portable.  Plus, the ability to search for a specific word is very appealing...  As an aside, you'd probably be happy to hear that most of the clients I work with who are using the CM3 have multiple copies of your book distributed around the cubes & labs, etc...

    Thanks very much for the explanation about the IF-THEN instruction, it makes a lot more sense to me now.  I'm always harping on people to write the most concise, least-error-prone code, and the instruction seemed to be a step backwards in both areas, but now I understand.

    Anyway, thanks again for your contributions and well-worded explanations!
  • Note: This was originally posted on 11th April 2010 at http://forums.arm.com

    Thanks for your kind words. Glad to know that readers find my book useful  :-)