MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

First time assembler user has a problem!

Thu Nov 27, 2014 9:29 pm

I just received my Pi in the mail and its great! Its so cool to have a Linux machine the size of a credit card.

However, I am attempting to do the Cambridge Baking Pi course and can't even get the first lesson to work and I have no idea why!

My code is this:

Code: Select all

.section .init
.globl _start
_start:

/*
* This command loads the physical address of the GPIO region into r0.
*/
ldr r0,=0x20200000

/*
* Our register use is as follows:
* r0=0x20200000 the address of the GPIO region.
* r1=0x00040000 a number with bits 18-20 set to 001 to put into the GPIO
*                               function select to enable output to GPIO 16.
* then
* r1=0x00010000 a number with bit 16 high, so we can communicate with GPIO 16.
*/
mov r1,#1
lsl r1,#18

/*
* Set the GPIO function select.
*/
str r1,[r0,#4]

/*
* Set the 16th bit of r1.
*/
mov r1,#1
lsl r1,#16

/*
* Set GPIO 16 to low, causing the LED to turn on.
*/
str r1,[r0,#40]

/*
* Loop over this forevermore
*/
loop$:
b loop$
This is exactly the same as the code from lesson one. This should make the LED flash, but it doesn't and I have no idea why!

I have double checked the Pi works and it does (I tried Arch Linux and Raspbian) And i am following the instructions by the letter (Just compiling my kernel.img and dragging it onto the Fat32 boot partition of the SD card)

The compiler spits out no errors

Code: Select all

arm-none-eabi-as -I source/ source/main.s -o build/main.o
arm-none-eabi-ld --no-undefined build/main.o -Map kernel.map -o build/output.elf -T kernel.ld
arm-none-eabi-objcopy build/output.elf -O binary kernel.img 
arm-none-eabi-objdump -d build/output.elf > kernel.list
I've also tried the flashing LED lesson too and that doesn't work either...

My Pi is a b+ v1.2, does this make a difference? If not, what on earth am I doing wrong?
I've had a good hunt around the internet and am now even more confused than I was before...

User avatar
joan
Posts: 14469
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: First time assember has a problem!

Thu Nov 27, 2014 9:41 pm

The activity LED moved from gpio 16 on earlier models to gpio 47 on the B+.

So if you are using 16 you'll need to change.

User avatar
rpdom
Posts: 15567
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 7:58 am

Unfortunately it is not as simple as changing 16 to 47, due to the way the GPIO controls work, and the behaviour of the pin has been inverted so the LED does the opposite of what the original code did.

Code: Select all

.section .init
.globl _start
_start:

/*
* This command loads the physical address of the GPIO region into r0.
*/
ldr r0,=0x20200000

/*
* Our register use is as follows:
* r0=0x20200000 the address of the GPIO region.
* r1=0x00200000 a number with bits 21-23 set to 001 to put into the GPIO
*                               function select to enable output to GPIO 47.
* then
* r1=0x00008000 a number with bit 15 high, so we can communicate with GPIO 47 (32+15=47).
*/
mov r1,#1
lsl r1,#21

/*
* Set the GPIO function select.
*/
str r1,[r0,#16]

/*
* Set the 15th bit of r1.
*/
mov r1,#1
lsl r1,#15

/*
* Set GPIO 47 to high, causing the LED to turn on.
*/
str r1,[r0,#32]

/*
* Loop over this forevermore
*/
loop$:
b loop$
I think that will work. I haven't tested it as that would mean turning my B+ off and it is busy flashing the TARDIS light at the moment :)

MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 2:08 pm

Does this mean that the rest of the code in the lessons on the Cambridge website are incorrect?

Also, how do you identify which pins to use? Its something I'm really struggling with

User avatar
joan
Posts: 14469
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: First time assember has a problem!

Fri Nov 28, 2014 2:23 pm

MHarrop678 wrote:Does this mean that the rest of the code in the lessons on the Cambridge website are incorrect?

Also, how do you identify which pins to use? Its something I'm really struggling with
A few gpios have changed but not by enough to invalidate the lessons as a learning process.

See http://elinux.org/RPi_Low-level_periphe ... .28GPIO.29 for the gpio to pin assignments on R1 and R2. R2 also applies to the B+.

The activity LED gpio moving from 16 to 47 should be the only other change (guessing here, I haven't actually looked at those lessons).

User avatar
rpdom
Posts: 15567
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 4:40 pm

I argree with joan. The ACT LED is the only GPIO change that should affect those lessons.

MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 4:51 pm

Really? Because I tried the last solution and was unable to get that to work. It compiled ok, but I was given just a blank screen when it came to running it.

Also, thank you so much rpdom! Your solution worked. I now have an LED that lights up! Now if I only understood why...

User avatar
joan
Posts: 14469
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: First time assember has a problem!

Fri Nov 28, 2014 5:08 pm

Have a look at http://www.raspberrypi.org/documentatio ... herals.pdf page 89 onwards.

The change from gpio 16 to 47 has several implications.

GPIO Alternate function select register 4 needs to be updated for the mode (rather than GPIO Alternate function select register 1). Also gpio 47 is in a different bit position within that word.

GPIO Output Set Register 1 has to be used to set the gpio to 1 (rather than GPIO Output Set Register 0). Also gpio 47 is in a different bit position within that word.

GPIO Output Clear Register 1 has to be used to clear the gpio to 0 (rather than GPIO Output Clear Register 0). Also gpio 47 is in a different bit position within that word.

Also gpio 47 is active high rather than active low for gpio 16.

That might give you some idea why higher level programming languages were developed.

User avatar
Burngate
Posts: 6089
Joined: Thu Sep 29, 2011 4:34 pm
Location: Berkshire UK Tralfamadore
Contact: Website

Re: First time assember has a problem!

Fri Nov 28, 2014 5:18 pm

why higher level programming languages were developed
So that the low-level programmer can feel superior to the high-level programmer - he knows why strange things happen.
The high level programmer hasn't a clue what's going on, but he gets a lot more done
So everyone's happy.

User avatar
joan
Posts: 14469
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: First time assember has a problem!

Fri Nov 28, 2014 5:26 pm

Burngate wrote:
why higher level programming languages were developed
So that the low-level programmer can feel superior to the high-level programmer - he knows why strange things happen.
The high level programmer hasn't a clue what's going on, but he gets a lot more done
So everyone's happy.
I wonder if I was wrong anyhow, it might have been more correct to say that's why libraries were developed. Low level programmers always re-use libraries. :D

User avatar
rpdom
Posts: 15567
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 5:36 pm

I like assembler. I like to be able to know that if I poke that bit (literally), this happens :)

MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

Re: First time assember has a problem!

Fri Nov 28, 2014 5:39 pm

Thank you both for your help, but its more that I'm struggling to read that table and wrap my head around it all.
All this sort of stuff is very new to me, I write in Lua and dabble in the occasional C/C++/CSharp Program. I never get anywhere near Binary, Hex or registers.

I'm using it to attempt to learn assembler and machine code, but now i've jumped into it, its all a little beyond me. I mean this with absolutely no offense intended (You guys have been a great help :) ) but i really need the explanation of it all in really easy childish terms. You wouldn't be able to point me anywhere would you? Maybe a youtube series or something?

dwelch67
Posts: 959
Joined: Sat May 26, 2012 5:32 pm

Re: First time assember has a problem!

Tue Dec 02, 2014 4:09 am

I tried to reply to this, wrote about reading the broadcom manual and understanding these bits that control the gpio, etc in ideally understandable terms in reference to C and other basic programming concepts. but perhaps I took too long, submitted and it asked if I was a human, captha code whatever and my work lost. went back and only some of it was retained by the browser, frustrated at the loss so I gave up.

re-reading, nobody else answered, so which part is it that you want explained. the gpio stuff or assembly or machine code or all of the above?

Pick one we can start from there...are there online resources? maybe yes maybe no depends on which thing or things you want to explore...

David

User avatar
rpdom
Posts: 15567
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: First time assember has a problem!

Tue Dec 02, 2014 8:52 am

The tables are lists of memory addresses that are linked to control locations (registers) inside the GPU. Each address contains 32 bits (1 word) and relates to a particular function of a bit of hardware.

The big table is a summary. The smaller tables give details of what each address is used for.

For example, the first address is 0x7E200000 (just to confuse matters that address is mapped into CPU memory at 0x20200000, so your code uses that address as a start instead). It is called GPFSEL0. It's function is "GPIO Function Select 0" and you can read or write it.
The smaller table 6-1 shows what this and the next five addresses do.
Each lot of 32 bits is broken up into 10 groups of 3 bits (plus 2 unused bits). Each group of 3 bits sets the mode of a particular GPIO pin. Standard modes are 0b000=Input, and 0b001=Output. There are various alternative modes available for each pin too.

There are 54 GPIOs in total, so there are 6 addresses, each one controlling 10 GPIOs (except the last which only has 4).

So, to set GPIO 47 to Output mode, you have to write 0b001 to the 8th group of three bits in the 5th address (everything counts from 0).

Here's part of the code again with a few more comments.

Code: Select all

/*
* This command loads the physical address of the GPIO region into r0.
*/
ldr r0,=0x20200000

/*
* Set GPIO 47 to Output mode by writing 0b001 to bits 21-23 (7 * 3)
* to GPFSEL4, which controls GPIOs 40 to 49.
* That is in the 4th word of the table at 0x20200010 or r0 + 0x10 (16 decimal)
*/
mov r1,#1
lsl r1,#21
str r1,[r0,#16]

/*
* Normally we would read the current contents of the location first, so we don't change GPIOs 40-46 and 48,49
* when we write to it. But this is only a quick example program. That bit comes later
*/

/*
* Turn GPIO 47 on by writing 1 to bit 15 of GPSET1. Each GPSETn location controls the output of up to 32 GPIOs.
* Writing a 1 to a GPSETn location sets that GPIO output (if it is in output mode) to a high state.
* Writing a 0 to a GPSETn location does nothing. To set a GPIO to output low you have to write a 1 to a GPCLRn.
*/
mov r1,#1
lsl r1,#15
str r1,[r0,#32]
Please do ask if you would like clarification of anything :)

MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

Re: First time assember has a problem!

Wed Dec 03, 2014 5:21 pm

Wow, this is great! Thanks so much for all your help!

My Dad and I worked through it in the morning and he helped explain it all to me (He used to play with a ZX Spectrum when he was my age) He also suggested i draw a diagram of all the Pins, their bytes/bits and their functions.

I'm going to try (as the lessons suggest) to turn the pin off now. Wish me luck!

MHarrop678
Posts: 51
Joined: Thu Nov 27, 2014 8:36 pm
Location: Ipswich, UK

Re: First time assember has a problem!

Thu Dec 04, 2014 6:57 pm

I just wanted to tell you all that I've progressed passed lesson 2 now and am well on my way to coding in Assembly properly. I wouldn't have been able to complete/get to this stage without all of your help! Thank you so very much! Learning a new way to code is so exciting :D

jonndavis1993
Posts: 1
Joined: Mon Mar 07, 2016 3:48 pm

Re: First time assember has a problem!

Mon Mar 07, 2016 4:04 pm

rpdom wrote:...

Code: Select all

/*
* Turn GPIO 47 on by writing 1 to bit 15 of GPSET1. Each GPSETn location controls the output of up to 32 GPIOs.
* Writing a 1 to a GPSETn location sets that GPIO output (if it is in output mode) to a high state.
* Writing a 0 to a GPSETn location does nothing. To set a GPIO to output low you have to write a 1 to a GPCLRn.
*/
mov r1,#1
lsl r1,#15
str r1,[r0,#32]
In your example you moved the value '1' into register 'r1', then you performed a logical shift left 15 bits. Why do you need to left shift 15 bits specifically? Is there any documentation that examples why a bit on in the 15th location is significant? If so, could you provide a link to it?

AlfredJingle
Posts: 69
Joined: Thu Mar 03, 2016 10:43 pm

Re: First time assembler user has a problem!

Tue Mar 08, 2016 12:43 pm

To the op: I started assembly programming 6 months ago and I made most progress using the info on the Github site of dwelch (see above for one of his comments). His Github name is dwelch67 and he has a very good/nice/interesting piece on programming and several excellent boot loaders and how to connect two Pis together. Only after I found his pages was I able to really move forward with assembly. Well worth the invested time.
Be prepared to read a lot though if you really want to learn assembly. The armv7 architecture manual has over 2700 pages.
going from a 6502 on an Oric-1 to an ARMv8 is quite a big step...

Return to “Bare metal, Assembly language”