Author Topic: Help me understand this code  (Read 11243 times)

0 Members and 1 Guest are viewing this topic.

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Help me understand this code
« on: November 16, 2020, 10:59:20 pm »


I dont seem to understand this guy's code @ 4:20

So I understand that according to Cortex-M standards, 0xE0000000 is the starting address of the "ITM stuff".

https://developer.arm.com/documentation/ddi0337/h/instrumentation-trace-macrocell-unit/itm-programmers-model

#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))

Can anybody explain to me moe specifically whats the parenthese mean and maybe give some broader insight? It hurts my eyes...

Thanks.
 

Offline RenThraysk

  • Regular Contributor
  • *
  • Posts: 107
  • Country: gb
Re: Help me understand this code
« Reply #1 on: November 16, 2020, 11:20:41 pm »
There is a continuous section of memory forming an array of unsigned longs starting at 0xE0000000.

The sub expression, ((volatile unsigned long *)(0xE0000000+4*n)), is taking the index and computing the address of a particular unsigned long.

The complete expression, *((volatile unsigned long *)(0xE0000000+4*n)), is reading the unsigned long value stored at that address.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 14135
Re: Help me understand this code
« Reply #2 on: November 16, 2020, 11:38:05 pm »
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:
Code: [Select]
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*(n))))
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #3 on: November 16, 2020, 11:50:15 pm »
Or if you use stop that handmade approach and just use standard CMSIS headers, this will turn into:
Code: [Select]
ITM->PORT[n].u32
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #4 on: November 16, 2020, 11:56:16 pm »
So lets say, I wanted to listen in on 2 different variables..

one would be sending to stimulus port 31 and the other stimulus port 0

ITM_Port32(31)=1

ITM_Port32(0)=9

How would that code look like? I want somthing like this, I think I would have to let my debugger know what to expect like this.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #5 on: November 17, 2020, 12:13:15 am »
Your code is correct assuming that both ports are enabled. I have no idea about that specific debugger and its configuration.

But usually you just use one port and define a protocol to differentiate your data.
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #6 on: November 17, 2020, 12:15:38 am »
So why do the other 30 buffers or 31  :scared:

Exist at all?

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #7 on: November 17, 2020, 12:17:57 am »
Because ITM is a very generic peripheral. And the sources don't have to be all from the software. It can be anything that system designer decided to configure inside the device.

And also, specific implementations do not have to support all of them. You are supposed to read the ID register to find out how many are implemented on your hardware.

So most people just use it as a fast debug UART with port 0 only. This is the most compatible use.
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #8 on: November 17, 2020, 12:21:55 am »
So let me get this straight, if I go by CMSIS and #include "core_cm7.h" in my main.c file... This is a header that contains ITM stuff in the CMSIS section.

I can use your CMIS technique instead of his ugly ((( ))) thing.

As long as I understand that, using the following define, to get the same address I offset by 1?

#define ITM_Port32(n)  (*((volatile unsigned long *)(0xE0000000+4*n)))

ITM_Port32(31) is same as ITM->PORT[n].u32 ??
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #9 on: November 17, 2020, 12:25:57 am »
I can use your CMIS technique instead of his ugly ((( ))) thing.
It is CMSIS and if you plan on doing embedded development you need to read those ugly things. This is a standard way to refer to memory mapped locations from C.

As long as I understand that, using the following define, to get the same address I offset by 1?

#define ITM_Port32(n)  (*((volatile unsigned long *)(0xE0000000+4*n)))

ITM_Port32(31) is same as ITM->PORT[n].u32 ??

I don't understand this. Your definition of ITM_Port32(n) is equivalent to ITM->PORT[n].u32. Where 'n' is the index of the port. u32 here is the size of the data to send. It can be u8, u16 or u32. In your macro you used "unsigned long", which is the same as u32.

So ITM_Port32(31) is ITM->PORT[31].u32.
« Last Edit: November 17, 2020, 12:30:58 am by ataradov »
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #10 on: November 17, 2020, 12:29:53 am »
oh,

Yeah, something like that, I guess.

Monkey see , monkey do.
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #11 on: November 17, 2020, 01:55:12 am »
Ok Help me out  :scared:, Heres me code ... It reacts strangely yet predictably, I think I outdone myself this time.  :clap:

/* Includes ------------------------------------------------------------------*/
#include "main.h"
.....



/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "core_cm7.h"
/* USER CODE END Includes */
....

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint16_t data31 =0;
uint16_t data0  =0;
/* USER CODE END 0 */

....

  while (1)
  {

                ITM->PORT[31].u32 =data31;
                data31++;
      HAL_Delay(500);
      ITM->PORT[0].u32 = data0;
      data0++;
      HAL_Delay(500);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
« Last Edit: November 17, 2020, 01:57:18 am by LootMaster »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #12 on: November 17, 2020, 01:58:21 am »
What did you expect? It outputs raw binary numbers. If you want nice looking numbers you have to format them like that in the device into a string and print that string.

Also, you are supposed to wait for the ready bit. And use u8 instead of u32 if you are just printing strings.

The same core_cm7.h contains a function ITM_SendChar () that you can just use directly. It checks that things are enabled and port is ready.


« Last Edit: November 17, 2020, 02:00:25 am by ataradov »
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #13 on: November 17, 2020, 02:04:16 am »
Cant this SWO thing send in 4 byte chunks?

I have a 16 bit int here, how to send as fast as possible?

Please change my code bro, I dont wanna use Send_char anymore I wanna use your method, this is way more slick.

edit: sorry, this thing is actually 2mhz pretty slow...it goes out as it comes.
« Last Edit: November 17, 2020, 02:09:06 am by LootMaster »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #14 on: November 17, 2020, 02:10:44 am »
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:
Code: [Select]
//-----------------------------------------------------------------------------
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');
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #15 on: November 17, 2020, 02:16:21 am »
  Nope  :scared: :scared: :scared:

while (1)
  {

      ITM->PORT[31].u8 =data31;
      data31++;
      HAL_Delay(500);
      ITM->PORT[0].u8 = data0;
      data0++;
      HAL_Delay(500);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

Does not work, nothing is shown in ITM console

Wow I am discovering symbols I never thought were possible...Cool
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #16 on: November 17, 2020, 02:19:27 am »
Your code is incorrect. It does not wait for the readiness of the port to accept the data. And "500" may not be enough of a delay. Is it 500 ms or 500 us?. The expected end result would be the same with this code.

Or may be that debugger you are using can only receive words, which would be stupid.
« Last Edit: November 17, 2020, 02:22:24 am by ataradov »
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #17 on: November 17, 2020, 02:31:06 am »
Those are in milliseconds. It should leave it enough time... when I replace 32 by 8 I get absolutely nothing.

But you are right, I should check the readyness of the port.

if (what flag?) ? .. How do you know by instinct the CMSIS command??

 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #18 on: November 17, 2020, 02:33:50 am »
΅Ά·ΈΉΊ΋Ό΍ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ΢ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџѠѡѢѣѤѥѦѧѨѩѪѫѬѭѮѯѰѱѲѳѴѵѶѷѸѹѺѻѼѽѾѿҀҁ҂҃҄҅҆҇҈҉ҊҋҌҍҎҏҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽҾҿӀӁӂӃӄӅӆӇӈӉӊӋ
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #19 on: November 17, 2020, 02:33:58 am »
Stop resisting, open core_cm7.h, and look at the source of ITM_SendChar(). Why are you making your life harder for no reason?

The flag is the same register. If ITM->PORT[0].u32 reads as 0, the port is not ready.

But 500 ms should be enough. Something else is wrong.
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #20 on: November 17, 2020, 02:36:16 am »
I should be able to change this on either

1: the debugger
2: the java interpretation

ST-LINK-V3...
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #21 on: November 17, 2020, 02:37:00 am »
I should be able to change this on either

1: the debugger
2: the java interpretation

ST-LINK-V3...
Change what? I don't understand what you mean.
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #22 on: November 17, 2020, 02:39:16 am »
obviously this is just an offsetted number of a wrong binary type.

Send Char has more instructions that this.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 12498
  • Country: us
    • Personal site
Re: Help me understand this code
« Reply #23 on: November 17, 2020, 02:42:48 am »
It may be interpreting it as UTF-8-encoded string or something like this. I don't know.

But in any case there is no way your code would just print numbers. That's not how it works and that's the last time I will repeat that. If you don't want t o listen, it is fine with me.
Alex
 

Offline LootMasterTopic starter

  • Regular Contributor
  • *
  • !
  • Posts: 192
  • Country: ca
Re: Help me understand this code
« Reply #24 on: November 17, 2020, 02:45:00 am »
Ok I will stop resisting and check out that function.
you win you win
It doesnt work like I think it does not matter If want it to be that way... :rant:
« Last Edit: November 17, 2020, 02:46:42 am by LootMaster »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

- - -
-->