Uncategorized

Rpi Assembly Language Notes

Asked 
Viewed 65 times
1

I have been struggling to light an LED using my raspberry pi 4 model b but have not been able to find a solution.

My assembly code :

.section .init
.globl _start
_start:

mov r0, #0xF0000000
orr r0, #0x0E000000
orr r0, #0x00200000
orr r0, #0x00000004
mov r1, #1
lsl r1, #18
str r1, [r0]

mov r0, #0xF0000000
orr r0, #0x0E000000
orr r0, #0x00200000
orr r0, #0x0000001C
mov r1, #1
lsl r1, #16
str r1, [r0]

loop$:
b loop$

I am trying to light up the LED through GPIO 16. A post on the raspberry pi forums suggests that the peripheral memory base has changed to 0xFE000000 instead of 0x20000000 + the GPIO offset; neither of those memory addresses worked to light the LED.

I also installed NOOBS on a different SD card and wrote a python script to light the LED and that worked.

To learn about the bare metals of raspberry pi, I have been reading the Baking Pi tutorial by the University of Cambridge.

Any help would be great.

 New contributor
  • I skimmed Baking Pi’s first two lessons and found this tutorial very good for newbies. I would rate it top 1% of the 100+ online tutorials I have read all these years. Lesson 1 actually shows every step to turn on GPIO 16 LED. Is there a step you could not follow or got stuck? – tlfong01 2 days ago   
  • I skimmed the Troubleshooint section and read the following: Troubleshooting: cl.cam.ac.uk/projects/raspberrypi/tutorials/os/… “This course has not yet been updated to work with the Raspberry Pi models B+ and A+. Some elements may not work, in particular the first few lessons about the LED. It has also not been updated for Raspberry Pi v2” … In other words, the tutorials is perhaps 5 years out of date! – tlfong01 2 days ago    
  • So you know how to use python to turn on a LED. But why now diving deep down to ARM assembly/machine language? – tlfong01 2 days ago   
  • Question – I used apt-get to install the toolchain, but got errors “unable to find some archives, …” Did you get the same error? – tlfong01 2 days ago   
  • Hi @Rahul Wadhwani, I am catching up. I just finished reading Lesson1 and so can more or less understand your turn-on-LED program. I will try to copy a similar demo code from Lesson 1 and hopefully assembled it and run it. – tlfong01 2 days ago   
  • I hope you are able to run it. Do you also have a raspberry pi 4 model b? – Rahul Wadhwani 2 days ago
  • Hi @ Rahul Wadhwani, Yes I am using Rpi4B 2GB. I have very little experience in “Make”. So I need to google/wiki quite a bit. Now I got stuck when running the makefile, with the error “… missing separator, Stop” as described at the top of my updated answer. Do you happen to know how what could be wrong? – tlfong01 yesterday    
  • PS – The complete listing of the makefile is in Appendix C of my answer. – tlfong01 yesterday   
  • I found an update of Baking Pi for Rpi2/3. I need to see what is the difference bdetween 1 and 2/3, and if there is any hope for 4. github.com/mauri870/baking-pi/blob/master/README.md – tlfong01 yesterday   
  • @goldilocks: Thank you for your advice. My apologies for any trouble caused. I have never heard of the StackEdit markdown editor. I will try to see if it helps to make my answers more friendly to visitors. “… please don’t use posted answers as scratchpads. You can continue to edit .., SE use a markdown editor and post them once they are ready.. StackEdit was pretty much made for that purpose, you may need a dropbox or google cloud account” – tlfong01 just now   Edit   

-3

Question

Baking Pi Lesson 1 Problem

/ to continue, …


Answer

Answer not yet ready, because I am still learning! 🙂

/ to continue, …


Learning Notes

Progress Notes 2019sep30hkt1708

I google and found what is the meaning of a make file separator.

makefile separator

/ to continue, …


Progress Notes 2019sep29hkt1708

When I tried to make using the makefile given by the tutorial. I got the error message

*** Makefile:41 Missing Separator. Stop

The lines around 41 are the following. I guess there is some sort of syntax error. Nee to read manual.

# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(LINKER)
    $(ARMGNU)-ld --no-undefined $(OBJECTS) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)

# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s $(BUILD)
    $(ARMGNU)-as -I $(SOURCE) $< -o $@

Progress Notes 2019sep29hkt1252

I studied Lesson 1’s demo program and made a summary (Appendix E). Next step it to do the following:

(1) Assemble the program,

(2) Load the assembled output file to a micro SD card,

(3) Insert SD card in Rpi4B and boot to run it.


Progress Notes 2019sep28hkt2129

I read the Make Wikipedia and have refreshed my memory. Now I can go to read the ARM RISC datasheet to get a rough idea of the registers structure, because writing my very first ARM assembly language program to turn on a LED connected to GIP pin 16.


Progress Notes 2019sep28hkt1129

I am reading Lessons 0, 1. I tried to install the toolchain using the following command but got error message, …

sudo apt-get install gcc-arm-none-eabi

error message: “Unable to fetch some archives.

I am not sure if my broken toolchan can compile any ARM code. Anyway, I download the “OS Template”, which I untared (using Win10 9Zip) to a seemingly make file, as listed in Appendix C. I have been writing python code this couple of years and forgot the “make” thing and need to wiki to refresh my memory! 🙂


Introduction

I studied digital computer fundamentals a century ago. I remember I learned things like voltage and current, Ohm’s Law, transistor, register, ALU, CPU etc. Most of the things I learned then are out of date. For example, I learned Motorola 6800 and Intel 8086 CISC assembly language, but now everybody go RISC. So I need to unlearn old stuff, and learn new tools. In other words, the old dog needs to learn new tricks. 😦

Learning Plan

I think I will start with Cambridge U’s Baking Pi tutorial Lessons 0, 1, to learn how to turn on a LED, …

/ to continue, …


Learning Notes

/ to continue, …


References

(1) Baking Pi – Operating Systems Development – Computer Science and Technology Dept, Cambridge U

(2) Lesson 0 Introduction

(3) Lesson 1 How to turn on OK/ACT LED 01

(4) ARM Intructions Reference

(5) Troubleshooting

This course has not yet been updated to work with the Raspberry Pi models B+ and A+. Some elements may not work, in particular the first few lessons about the LED. It has also not been updated for Raspberry Pi v2.

(6) Baking Pi GitHub – Chadderz121/bakingpi-www (Last update: 2014)

(7) Download GNU Toolchain, OS Template, and Model Answers

Some Linux distributions including Ubunutu offer the ARM GNU Toolchain via apt-get. Run the following command:

$ sudo apt-get install gcc-arm-none-eabi

(8) Download OS Template

(9) Make – Wikipedia

(10) Introducing ARM assembly language by Carl Burch, Hendrix College, October 2011

(11) Baking Pi: Operating Systems Development by Alex Chadwick – Chadderz121/bakingpi-www

(12) ARM Cortex-A72 (ARMv8-A architecture) Technical Manual – ARM

(13) Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile

(14) ARM PrimeCell General Purpose Input/Output (PL061) Technical Reference Manual

(15) Linux Make manual page

(16) Baking Pi for Rpi2/3

(17) Baking Pi Forum Discussion 1

(18) Baking Pi Forum Discussion 2

/ to continue, …


Appendices

Appendix A – ARM Instructions list used in Lessons

The following is a list of all the instruction boxes in the courses in order.

ldr reg,=val puts the number val into the register named reg.

mov reg,#val puts the number val into the register named reg.

lsl reg,#val shifts the binary representation of the number in reg by val places to the left.

str reg,[dest,#val] stores the number in reg at the address given by dest + val.

name: labels the next line name.

b label causes the next line to be executed to be label.

sub reg,#val subtracts the number val from the value in reg.

cmp reg,#val compares the value in reg with the number val.

Suffix ne causes the command to be executed only if the last comparison determined that the numbers were not equal.

.globl lbl makes the label lbl accessible from other files.

mov reg1,reg2 copies the value in reg2 into reg1.

Suffix ls causes the command to be executed only if the last comparison determined that the first number was less than or the same as the second. Unsigned.

Suffix hi causes the command to be executed only if the last comparison determined that the first number was higher than the second. Unsigned.

push {reg1,reg2,...} copies the registers in the list reg1,reg2,... onto the top of the stack. Only general purpose registers and lr can be pushed.

bl lbl sets lr to the address of the next instruction and then branches to the label lbl.

add reg,#val adds the number val to the contents of the register reg.

Argument shift reg,lsl #val shifts the binary representation of the number in reg left by val before using it in the operation before.

lsl reg,amt shifts the binary representation of the number in reg left by the number in amt.

str reg,[dst] is the same as str reg,[dst,#0].

pop {reg1,reg2,...} copies the values from the top of the stack into the register list reg1,reg2,.... Only general purpose registers and pc can be popped.

alias .req reg sets alias to mean the register reg.

.unreq alias removes the alias alias.

lsr dst,src,#val shifts the binary representation of the number in src right by val, but stores the result in dst.

and reg,#val computes the Boolean and function of the number in reg with val.

teq reg,#val checks if the number in reg is equal to val.

ldrd regLow,regHigh,[src,#val] loads 8 bytes from the address given by the number in src plus val into regLow and regHigh.

.align num ensures the address of the next line is a multiple of 2num.

.int val outputs the number val.

tst reg,#val computes and reg,#val and compares the result with 0.

mla dst,reg1,reg2,reg3 multiplies the values from reg1 and reg2, adds the value from reg3 and places the least significant 32 bits of the result in dst.

strh reg,[dest] stores the low half word number in reg at the address given by dest.

Appendix B – Lessons Description

Introduction

  1. Introduction – This introductory lesson does not contain a practical element, but exists to explain the basic concepts of what is an operating system, what is assembly code, and other important basics. If you just want to get straight into practicals, it should be safe to skip this lesson.

OK LED Series (Beginner)

  1. How to turn on OK/ACT LED 01 – The OK01 lesson contains an explanation about how to get started and teaches how to enable the ‘OK’ or ‘ACT’ LED on the Raspberry Pi board near the RCA and USB ports.
  2. How to turn on OK/ACT LED 02 – The OK02 lesson builds on OK01, by causing the ‘OK’ or ‘ACT’ LED to turn on and off repeatedly.
  3. How to turn on OK/ACT LED 03 – The OK03 lesson builds on OK02 by teaching how to use functions in assembly to make more reusable and rereadable code.
  4. How to turn on OK/ACT LED 04 – The OK04 lesson builds on OK03 by teaching how to use the timer to flash the ‘OK’ or ‘ACT’ LED at precise intervals.
  5. How to turn on OK/ACT LED 05 – The OK05 lesson builds on OK04 using it to flash the SOS morse code pattern (…—…).

Screen Series (Advanced)

  1. Screen01 – The Screen01 lesson teaches some basic theory about graphics, and then applies it to display a gradient pattern to the screen or TV.
  2. Screen02 – The Screen02 lesson builds on Screen01, by teaching how to draw lines and also a small feature on generating pseudo random numbers.
  3. Screen03 – The Screen03 lesson builds on Screen02 by teaching how to draw text to the screen, and introduces the concept of the kernel command line.
  4. Screen04 – The Screen04 lesson builds on Screen03 by teaching how to manipulate text to display computed values on the screen.

Input Series (Advanced)

  1. Input01 – The Input01 lesson teaches some theory about drivers, and linking programs, as well as keyboards. It is then applied to print out input characters to the screen.
  2. Input02 – The Input02 lesson builds on Input01 by teaching how to make a command line interface for an Operating System.

Appendix C – OS Template (Makefile for “making” ARM assembly code)

ARM Makefile – 2019sep2801

###############################################################################
#   makefile
#    by Alex Chadwick
#
#   A makefile script for generation of raspberry pi kernel images.
###############################################################################

# The toolchain to use. arm-none-eabi works, but there does exist 
# arm-bcm2708-linux-gnueabi.
ARMGNU ?= arm-none-eabi

# The intermediate directory for compiled object files.
BUILD = build/

# The directory in which source files are stored.
SOURCE = source/

# The name of the output file to generate.
TARGET = kernel.img

# The name of the assembler listing file to generate.
LIST = kernel.list

# The name of the map file to generate.
MAP = kernel.map

# The name of the linker script to use.
LINKER = kernel.ld

# The names of all object files that must be generated. Deduced from the 
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))

# Rule to make everything.
all: $(TARGET) $(LIST)

# Rule to remake everything. Does not include clean.
rebuild: all

# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
    $(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)

# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
    $(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET) 

# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(LINKER)
    $(ARMGNU)-ld --no-undefined $(OBJECTS) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)

# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s $(BUILD)
    $(ARMGNU)-as -I $(SOURCE) $< -o $@

$(BUILD):
    mkdir $@

# Rule to clean files.
clean : 
    -rm -rf $(BUILD)
    -rm -f $(TARGET)
    -rm -f $(LIST)
    -rm -f $(MAP)

.END

/ to continue, …

Appendix D – Make reading notes

Make – Wikipedia

In software development, Make is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program.

Stuart Feldman Bell Lab 1976, 2003 ACM Software System Award, declarative programming (using rules), not IDE, also for project management, GNU Make (short gmake) is the standard implementation of Make for Linux and OS X, GNU Make 4.2 consists of about 42,500 lines of C code,

Make is invoked with a list of target file names to build as command-line arguments: make [TARGET …]

Make searches the current directory for the makefile to use, e.g. GNU Make searches files in order for a file named one of GNUmakefile, makefile, Makefile and then runs the specified (or default) target(s) from (only) that file.

Rules – A makefile consists of rules. Each rule begins with a textual dependency line which defines a target followed by a colon (:) and optionally an enumeration of components (files or other targets) on which the target depends. The dependency line is arranged so that the target (left hand of the colon) depends on components (right hand of the colon). It is common to refer to components as prerequisites of the target.

Macros – A makefile can contain definitions of macros. Macros are usually referred to as variables when they hold simple string definitions, like “CC=clang”. Macros in makefiles may be overridden in the command-line arguments passed to the Make utility. Environment variables are also available as macros.

Appendix E – Turn On LED programming Study notes V0.2 2019sep29hkt1257

# Program: led02.s
# Function: Turn on OK/ACT/status green LED connected to GPIO pin #16
# Rpi4B ARM Cortex A72
# Ref: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html
# Ref: http://infocenter.arm.com/help/topic/com.arm.doc.100095_0001_02_en/cortex_a72_mpcore_trm_100095_0001_02_en.pdf
# build/source/ main.s kernel.ld LICENSE Makefile
# /home/pi/assembly_language/build/source/turn_on_led_01.s

.section .init
.globl _start
_start:

# **********************************************************************************
# Assembler instructions telling the ARM assembler to execute
#.section .init # tells assembler to place assembled  target code of this code section    
# (called .init) to start position to execute to end of this section, or end of file              
#.globl _start  # these two line to stop warning message and are not important
#_start:            #
# ***********************************************************************************

ldr r0, = 0x20200000

# **********************************************************************************
# Assembly language instructions for the ARM chip/processor to execute
# These instructions set GPIO pin 16 to Low level, so to turn on connected LED
# ldr r0, = 0x20200000 # Load into register R0 the numercial value of 0x2020 0000
#   r0 is the name of the first of 13 GPIO registers (r0, r1, r2, ... to r12)
#   This value 0x2020 0000 is the address of the GPIO controller
#   This GPIO Controller has 24 bytes of instruction to set 54 GPIO pins
#   00 - 24 Function Select
#   28 - 36 Turn On Pin
#   48 - 48 Turn Off Pin
#   52 - 60 Set pin to input mode (default if output mode)
# ***********************************************************************************

mov r1, #1
lsl r1, #18
str r1,[r0, #4]

# ***********************************************************************************
# Assembly language instructions for the ARM chip/processor to execute
# These instructions set GPIO pin 16 to Low level, so to turn on connected LED
# mov r1, #1 - move the number #1 into register r0
# lsl r1, #18 - shift left the binary representation of the number in r1 by 18 places.
# str reg, [dest,#val]  -  stores the number in r1 at the address of number in r0 + 4.

# ***********************************************************************************

mov r1,  #1
lsl r1, #16
str r1, [r0, #40]

# ***********************************************************************************
Put 1 to r1, left shift r1 16 places, store r1's contents to address r0 content = 16
which is GPIO16's address
# ***********************************************************************************

loop$:
b loop$

# ***********************************************************************************
loop$: - names next line to be "loop$
b loop$ - Causes the next line to be executed to be label.
# ***********************************************************************************

Appendix F – Makefile06 tlfong01 2019sep29hkt2130

# makefile06 tlfong01  2019sep29hkt2124
# mauri870 Fix lesson typo c158d66 on Dec 22, 2017
# https://github.com/mauri870/baking-pi/blob/master/Makefile

###############################################################################
#   makefile #   by Alex Chadwick
#   A makefile script for generation of raspberry pi kernel images.
###############################################################################

# The toolchain to use. arm-none-eabi works, but there does exist 
# arm-bcm2708-linux-gnueabi.
ARMGNU ?= arm-none-eabi

# The intermediate directory for compiled object files.
BUILD = build/

# The lesson kernel to compile
LESSON ?= ok01

# The directory in which source files are stored.
SOURCE = src/$(LESSON)/

# The name of the output file to generate.
TARGET = kernel8-32.img

# The name of the assembler listing file to generate.
LIST = kernel.list

# The name of the map file to generate.
MAP = kernel.map

# The name of the linker script to use.
LINKER = kernel.ld

# The names of libraries to use.
LIBRARIES := csud

# The names of all object files that must be generated. Deduced from the 
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))

# Rule to make everything.
all: $(TARGET) $(LIST)

# Rule to remake everything. Does not include clean.
rebuild: all

# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
    $(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)

# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
    $(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET) 

# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(LINKER)
    $(ARMGNU)-ld --no-undefined $(OBJECTS) -L. $(patsubst %,-l %,$(LIBRARIES)) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)

# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s
    $(ARMGNU)-as -I $(SOURCE) $< -o $@

$(BUILD):
    @mkdir $@

# Rule to clean files.
clean : 
    @rm -f $(BUILD)/*.o $(BUILD)/*.elf
    @rm -f $(TARGET)
    @rm -f $(LIST)
    @rm -f $(MAP)

# *** End ***

.END

shareeditundeleteflag
deleted by goldilocks 9 hours ago

Why was your post deleted? See the help center.
  • I appreciate the effort you are making, but please don’t use posted answers as scratchpads. You can continue to edit a deleted question and then undelete it later, or better yet, since SE uses (a superset of?) markdown, use a markdown editor and post them once they are ready. StackEdit was pretty much made for that purpose (hence the name), you may need a dropbox or google cloud account — in any case there’s plenty of such things around. google.com/search?q=”markdown+editor – goldilocks 9 hours ago

Categories: Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: