EduardH
Posts: 35
Joined: Fri Sep 04, 2015 8:10 am

what is wrong with this bare metal code.

Tue Feb 20, 2018 2:07 pm

Good afternoon,

I made a blinking led; OK02 from "baking pi". I modified the program for blinking GPIO0. In the code there is something like str r1,[r0, #0x28]. It works fine. Then I replaced this line by two others:
ldr r3,[r0, #0x28]
str r1, [r3]
The second code snippet did not work.

in both snippets ro is loaded with the GPIO_BASE 2020 0000 (for rpi zero)
r1 is loaded with 1 to blink the GPIO0

Please can You tell me what I did wrong.

The reason why I want to change the code is looking why my program (without) the delay loops runs so slowly. (circa 2.5 MHz)
The second code snippet is taken from the assy listing of a C program that toggles much faster ( > 20 MHz)

Have a nice day,

Eduard

LdB
Posts: 907
Joined: Wed Dec 07, 2016 2:29 pm

Re: what is wrong with this bare metal code.

Tue Feb 20, 2018 4:12 pm

Offset 0x28 is GPCLR0 so I suggest you read the datasheet again carefully .... lets highlight the important part
The output set registers are used to set a GPIO pin. The CLR{n} field defines the respective GPIO pin to set, writing a “0” to the field has no effect.
Your first code snippet does the right thing it writes a value to the register AKA it is a store instruction (str)
str r1,[r0, #0x28]

Your second piece of code is a load (ldr) .... look at it really careful
ldr r3,[r0, #0x28]

What do you really think you are going to load from the GPCLR0 register (read the quote again)???????

Then to top it off you write a register (r1) value to the address of the value you just read from the GPCLR0 register
str r1, [r3]

It doesn't work because the code is nonsensical rubbish :-)

At a guess the reason your code probably runs slower is likely because you haven't turned the branch and data cache on and the ARM is probably not set to full speed .. AKA your bootstub is really minimal.

EduardH
Posts: 35
Joined: Fri Sep 04, 2015 8:10 am

Re: what is wrong with this bare metal code.

Tue Feb 20, 2018 6:00 pm

Hello LdB,

Thanks for Your help. I posed a question and got answers to 3 questions. Indeed writing to CLR would not set the GPIO bit. That doesn't change much because a few lines later there is a write to SET in the loop. (not shown here) ldr r3,[r0, #0x28] loads the contents of location 2020 0028 into the r3 register. That is rubbish. r3 has to be loaded with the number 2020 0028. I see why the code doesn't work.
I was trying to search why the output speed. For sure You gave me the explanation.

Sincerely,

Eduard

I have got more than one answer to my question. This thread may be closed.

LdB
Posts: 907
Joined: Wed Dec 07, 2016 2:29 pm

Re: what is wrong with this bare metal code.

Tue Feb 20, 2018 7:33 pm

Just so you know
r3 has to be loaded with the number 2020 0028.
Your code does not do that

So lets do this with values so lets say memory location 20200028 has value of 0xDEADFEED
r0 will be 0x20200000

ldr r3,[r0, #0x28] .. loads the value from 0x20200028 into r3 .. that is not the address but what is at the location that is what the [ ] brackets mean

So R3 now equals 0xDEADFEED .. IT DOES NOT EQUAL 0x20200028

feel free to check .. its called immediate offset
https://www.heyrick.co.uk/armwiki/LDR
The C equivalent on integer arrays
Immediate offset:
LDR R0, [R1, #4]
r0 = r1[1];
str r1,[r3] will then write the contents or r1 to the memory location 0xDEADFEED being carried in r3

So the only explaination I can see is you put up wrong code.

The alternative is your code is randomly writing to memory locations and your code somehow toggles the port elsewhere which is why it is at the wrong speed.

For the record if you want a fast loop code to toggle a port as fast as possible

Code: Select all

  
  mov r2, #????    // Place your bit value for the GPIO port here
  ldr r3, .L4            // Loads the GPIO port address base 0x3F200000
.L2:
  str r2, [r3, #40]  // Store bit value  to clear register
  str r2, [r3, #28]  // Store bit value to set register
  b .L2                  // Loop
.L4:
  .word 1059061760

EduardH
Posts: 35
Joined: Fri Sep 04, 2015 8:10 am

Re: what is wrong with this bare metal code.

Sat Feb 24, 2018 6:26 pm

Many thanks for Your help.

Indeed, I understand what I did wrong.

I want to find out why my program (on Rpi0, rpi2 and rpi3) worked much slower then I expected and what can be done to give it a speed boost. It must be something like the cache or the prediction OFF. I just went from the "baking pi" lessons to "valvers". The valvers part1 blinking led (without the delay loops) is not faster than the Cambridge OK02. I ran very fast through the valvers lessons. I guess the answer is in the fifth lesson. After repeating the lessons slowly I'll tell the gpio output speed. This is a free time project. There is no hurry. Just looking how things work and hoping they can be useful in the radio hobby.

Sincerely,

Eduard

Return to “Bare metal, Assembly language”