This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
In line with implementing a workaround for PMM32 errata, I wanted to know
how much current my MSP430FR4133 draws in AM at 16 MHz when spinning in an
endless loop w/o any interrupts or other "disturbances".
So I removed the "eint" which normally comes after the initialisation part and
before the main loop and checked the current. It was 1.15 mA which seems to be
OK for an FR4133 at 16 MHz in AM running entirely from the cache. Then I
changed some minor stuff in my initialisation code which does not have any
influence on the current consumption. But suddenly the supply current jumped
to 1.35 mA.
After a bit of searching it turned out that the current drawn depends on where
the main loop is running (it actually got moved around a bit while adding or
removing code in the initialisation part). The main loop is simply
forever: jmp forever
If it is located 2 bytes before a modulo 8 address (0x???6 oder 0x???E) it
consumes 1.35 mA. On every other address we'll have 1.15 mA. That means, if
we assume the following (gas) code
.balignw 8, 0x4303 nop nop nop forever: jmp forever
it will draw 1.35 mA. When removing any number of nops, we get 1.15 mA.
First thing that jumps into mind is that the jmp sits on the last word of a
cache line and the prefetcher fetches the next 4 words from FRAM. But as we
have a 2-way set-associative cache with 4 lines of 64 bits each, it should be
possible to cache two consecutive, 8-byte-aligned memory blocks with 8 bytes
of size each.
To make things more funny: The code
.balignw 8, 0x4303 nop nop nop forever: jmp forever .word 0x0000
consumes 1.36 mA. But this one
.balignw 8, 0x4303 nop nop nop forever: jmp forever .word 0xFFFF
only 1.28. And last but not least:
.balignw 8, 0x4303 nop nop nop forever: jmp forever1 forever1: jmp forever
uses 1.24 mA (irrespective of what comes after).
Any explanations?
That's what I thought as well. But this does not explain the higher current for
my last example. forever1 should definitely make it into the next cache line.
So in this case the code again should run entirely cached (even with the
next word being cached) and just switching between two cache lines can't
be that expensive...
Yes, I know the principles.
> Do you have a specific concern, in the sense not achieving the optimum current, or do you suspect a malfunction of the device?
I did not observe any malfunction. I just wondered about this behaviour and would like to understand it. The whole caching and esp. the "intelligent logic" (which selects the cache lines) is not very well documented so I am curious. At least we have an almost 20% increase of power consumption only because of the location of a piece of code which should entirely fit within the cache...
No, I just want to understand what's gonig on. And, apart from that, I have my doubts that any compiler will consider the word follwing the "jmp" in order to optimise power consumption ;-).
And, as I wrote: Initially, I just wanted to see how much the power rises when switching SMCLK from 8 to 16 MHz to work around PMM32. Of course, nobody who is concerned about power will have the CPU run in AM doing nothing. But in case one has a small loop that does something useful, it depends on where it sits within the cache line and what data is following.
After some investigation done by TI (thanks!) it turns out, that:
1. The word after the jmp gets (pre-)fetched and even cached (but on a different cache line if it sits on a modulo-8 address!)
2. If it sits on a modulo-8 address (and therefore in a different cache line) even though it is cached, the current consumption depends on the bits switching. This is due to the prefetch which crosses the cache line border. So even if all bits are in the cache, switching cache lines may be more expensive than staying in a single one.
**Attention** This is a public forum