Most of the parentheses are just parentheses, used to group an expression so its evaluated before the outer operator gets it. The outer pair are so that adjacent operators when/where the #defined name is used don't affect evaluation within it. The (n) after the name makes the name a function-like macro, with parameter n. The pair immediately round volatile unsigned long * are a cast operator, in this case casting an integer to that pointer type.
There's no particular 'magic', this is just 'vanilla' C, constructing a pointer to a port (using an architecture and processor dependent integer base address) and dereferencing it for access.
Arguably, the parameter n should have parentheses round where its used, as if an expression not wrapped in parentheses containing any operator with lower precedence than multiplication is used for n, the result will be incorrect and probably cause a misaligned pointer error. Here's the fixed version:
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*(n))))
It can and it does, but this debugger interprets them as ASCII characters. Probably because that's how majority of people use it. There is nothing you can do here, you will have to convert your number internally into ASCII and print it byte by byte. Or get a different debugger that is more flexible in how it reads the data.
ITM_SendChar() is my method, but used correctly. It internally writes ITM->PORT[0].u8.
The quickest and hackiest way would be something like this:
//-----------------------------------------------------------------------------
void puthex(uint32_t v, int size)
{
char hex[] = "0123456789abcdef";
for (int i = 0; i < size; i++)
{
int offs = ((size - 1) - i) * 4;
ITM_SendChar(hex[(v >> offs) & 0xf]);
}
}
And in the loop:
puthex(data31++, 8);
ITM_SendChar('\r'); // Line ending so numbers go on a new line
ITM_SendChar('\n');
Most of the parentheses are just parentheses, used to group an expression so its evaluated before the outer operator gets it. The outer pair are so that adjacent operators when/where the #defined name is used don't affect evaluation within it. The (n) after the name makes the name a function-like macro, with parameter n. The pair immediately round volatile unsigned long * are a cast operator, in this case casting an integer to that pointer type.
There's no particular 'magic', this is just 'vanilla' C, constructing a pointer to a port (using an architecture and processor dependent integer base address) and dereferencing it for access.
Arguably, the parameter n should have parentheses round where its used, as if an expression not wrapped in parentheses containing any operator with lower precedence than multiplication is used for n, the result will be incorrect and probably cause a misaligned pointer error. Here's the fixed version:
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*(n))))
ITM_Port32(31)=1;
So essentially, he made an expression to to find a memory location that he can write too?
A "pointer" to an offsetted array by 0xE0000000 and distanced by 4 bytes according to n.
What bothers me is that there is no limit to that number that is set for n, isnt that dangerous to not declare a limit as you #define it? At least the compiler might warn you..
so when he puts ITM_Port32(31)=1;
the processor goes to a memory location pointer ITM_port... wich applies a formula go(0xE0000000+4*(31)) and write 1.
Am I correct? What is the correct terminology for this sort of mind tricks, honestly these boklets I read never contained such hardcore parentheses examples.
I was just confused as o why he would want to do that....ITM_Port32(31)=1
If all the action happens with ITM_Port32(0)=1 or w/e...Since this is a queued slow process anyways... Whats the benefit writing to those "ghost town" stimulus ports? If there was better data organization and faster with the eclipse interpretation I could understand.
Just poor clarity on the matter.. nd the guy just lost me with his goofy attitude...I want SERIOUS videos made by pros.