Recent Question/Assignment

ALX.4: Developing and Testing Assembly Code in Keil uVision
Use the Keil IDE to create and test assembly code for the KL25Z microcontroller. Observe registerlevel operation of assembly and explore the use of software simulations as a means to learn a programming language.
Learning Objectives:
• Create new Keil assembly code projects in Keil uVision
• Experience navigating through Keil uVision and using its tools for code development and debugging.
• Enhance your understanding of assembly memory access commands and how they interact with CPU registers and memory.
Resources and Supplies:
• †ReferencesKeil_Assembly_Guide
• †ReferencesARMv6-M_ASM_QuickRef.pdf
• †ALX.4Project4 (skeleton project folder)
• †ReferencesASM_template //template project folder for KL25Z assembly projects
• KL25Zcpu_ARMv6m_Architecture_Reference_Manual.PDF
† Files (or folders) are on the course shared directory: egrcoursesunixECE331Shared.
ALX Process .................................................................................................................................... 1
ALX Exercises ................................................................................................................................. 2 Exercise 0: Introduction to Keil and Assembly (estimated 45 min) ..................................................... 2 Exercise 1: Keil Assembly Guide (estimated 45 min) ......................................................................... 2 Exercise 2: Exploring Memory Access Instructions (estimated 60 min) .............................................. 3
Exercise 3: Writing and Debugging Assembly Instructions (estimated 30 min) ................................... 7
Submitting ALX Assignments ........................................................................................................... 8
ALX Process
Refer to D2L instructions for this ALX for deliverables and deadlines for submitting them.
Exercise 0: Introduction to Keil and Assembly (estimated 45 min)
This exercise will help you prepare for ALXs 4-9 by installing Keil µVision software on your local Windows personal computer and give you a brief reminder for the Assembly language. Keil µVision is an MDK that we will use to simulate Assembly commands for KL25Z. In later ALXs, we will utilize Keil µVision to write C programs for KL25Z and upload programs to the microcontroller.
Step A: Installing Keil µVision on your Windows PC
Note: you will need a Windows PC to run this software. If you are using a MAC, please install a Windows emulator.
1. In your References folder find Keil_Assembly_Guide and follow the instruction on slides 2-6 to download and setup Keil µVision and get the appropriate packs
2. Once Keil is ready, take a snapshot of your installed packs and attach them to your worksheet.
Step B: Understanding Keil environment
Now that we have installed Keil, this step will help you understand the environment.
3. In your Keil_Assembly_Guide read slides 7-9 and answer the questions posed in your worksheet regarding slides 2-9.
Step 3: A quick reminder of Assembly language
This step will serve as a quick re-introduction of Assembly language that you have learned in your ECE331 lecture by now.
4. Locate your ARMv6-M_ASM_QuickRef document and study the whole document.
5. Answer the questions posed in your worksheet based on your ARMv6-M_ASM_QuickRef.
Exercise 1: Keil Assembly Guide (estimated 45 min)
This exercise will introduce you to creating assembly programs for the KL25Z microcontroller using the Keil uVision IDE. The basic steps in creating a coding project and building and simulating a project will be explored.
For Exercise 1, you should complete all of the steps on slides (10-19) of the Keil_Assembly_Guide. All of the information you need is in the guide document. These steps will direct you to record some information and results on your worksheet. Some additional notes/hints are provided below.
• Keil_Assembly_Guide can be found in T:coursesunixECE331SharedReferences.
• Two other items can be found under SharedReferences that might help with assembly programming:
o ARMv6-M_ASM_QuickRef, a compressed description of all ASM instructions you will use in ECE331.
o ASM_template (folder), a folder containing the main.s template file needed to start any assembly code project. Use a copy of this folder for any code projects you create for Preps or practice. You will need a new folder for each code project, not just a file.
• The Project4 folder contains several sub-folders that you will transform into Keil uVision code “projects”, one folder for each lab exercise. A Keil uVision project is a collection of source code files and a .uvproj file used by Keil to organize your code project. Typically, these files are all contained within a “project folder” to keep source files separated between code projects.
• Step 10 asks you to scroll past a bunch of code to the “student code” area. The code you skip is necessary to setup the compiler and initialize key parameters in the microcontroller. This code is all preset for you and you don’t need to do anything with it. But all assembly projects you create will need this code, and it is included in the provided ASM_template folder.
Exercise 2: Exploring Memory Access Instructions (estimated 60 min)
Two of the most important elements in understanding assembly-level operation of a microcontroller are memory access and flow control. Memory access instructions comprise a range of load, store, and move instructions that use a variety of address mode to define and copy values in CPU registers and memory. This exercise will explore many memory access instructions to help you visualize their operation within a microcontroller. Flow control instructions (branches and subroutines) that define and manipulate the sequence in which instructions are executed will be covered later in ECE331.
Task A: Create a new project using an existing main.s source code file
1. From the Keil Edit Mode window, close your Exercise 1 project using Project Close Project.
2. In Keil, create a New uVision Project by navigating into the Project4ex2 folder and creating a project named memory_access.
If you need assistance, refer to Keil_Assembly_Guide, steps 2-5 on Slides 10&11. Your project should be at path in a directory of your choosing on your local Windows personal computer:
directory ECE331 netID KeilProject4ex2memory_access.uvproj
3. In the Keil Project panel, add the existing main.s file to the source group
• Expand Target 1, right click on Source Group 1, and select “Add Existing Files…..”.
• In the dialog box that opens, (if necessary) change Files of type: to Asm Source file (*.s…).
• Then select the main.s file from the list and click Add. Then Close.
This process is also covered in the Keil_Assembly_Guide, steps 6-8 on Slide 11.
4. Open the main.s file in the Keil Editor by expanding Source Group 1 and double-clicking main.s.
Scroll down to the Main function (line 57) and observe the series of memory access instructions.
Task B: Simulate assembly memory access instructions
5. Without making any changes to main.s, Build this project. Ignore any “No section matches…” warnings. Then configure flash tools to debug using the simulator. Please refer to the Keil_Assembly_Guide (Slide 10) if you have any questions.
6. Start a simulation (Start/Stop Debug Session).
7. In Debug Mode, skip over the initialization code prior to the Main function by right-clicking on the first memory access instruction (line 60) and selecting Run to Cursor line.
8. One line of code at a time, study each instruction, try to predict what will happen when it is executed (see comments after each instruction for hints). Then use Step to execute that line of code. Repeat these actions for each line of code prior to the ending infinite loop (B .).
9. Answer the questions on the Worksheet regarding some of these memory access instructions. You may want to start over and step through them again to re-simulate any instructions that are not clear. To restart a simulation, follow these steps:
• If the simulation is running, press the Stop button (it will not be running if you are stepping through line by line).
• Press the Reset (RST) button to clear CPU registers including the PC. Clearing PC will direct execution back to the top of your code.
• If desired, select Run to Cursor line to advance code to the beginning of your code or the first line you want to run again.
Studying the assembly instructions in this lab is the best way to learn address modes and assembly language. You will soon be tested over this material, and we will not cover assembly instructions much in class. Repeat Steps 8-9 as needed to ensure you understand what each of these instructions will do; this is your BEST opportunity to learn how they work.
10. Two lines of code are “commented-out” (anything following a ‘;’ is a comment and will not be executed). On the Worksheet, explain what you can learn about assembly by reading these invalid instructions. Ask other students or the TA if you need help figuring this out.
As noted in comments with these lines of code, they contain illegal forms. In other words, they have operands that are not allowed within our 16-bit instruction set.
Locate these illegal instructions on the AssemblyQuickReferenceChart in your ARMv6M_ASM_QuickRef and try to see if you can determine how these instructions do not meet operand requirements.
Observing execution of instructions in the simulator is great way to visualize how the instructions are working. However, for many instructions just observing CPU registers does not sufficiently explain what the instruction is doing. In the next Task we’ll add observations of memory addresses that should help clarify.
Task C: Observing memory for Load instructions
Using the Memory panel, Keil will highlight (in Red text) values as they are read (loaded) from ROM and will add values to RAM as they are written (stored). This allows you to step through program execution and clearly observe what is taking place in the hardware. However, after you run through the program once, you can not clear these values and highlights unless you exit the debugger and restart it. The RESET command will only clear CPU registers.
11. Exit the debugger to reset the simulator and clear memory. Then, start a new debug session. Do not run or step your code until instructed to after several steps.
Now let’s setup memory panels to observe ROM and RAM and better undertand what actions are taking place while executing each line of code. Our assembly source code has labels
(which are inherently addresses pointing to memory locations) for program constants at “ROM_Data” and program variables at “RAM_Data”. These are the two areas (addresses) we want to observe.
12. Find the address of “ROM_Data” using the disassembly window. “ROM_Data” is a label defining the address where constants are stored at the end of your code. Remember that constants are stored in ROM following instruction bytes. But how do you find the address of ROM_Data?
• In Debug Mode, scroll the main.s source code file to the Main function.
• Locate the line that loads “ROM_Data” into R1. Select this line and notice that the equivalent line in the Disassembly panel becomes highlighted. Click on a few different lines to ensure the highlight is tracking your selection in the source code.
• With the “ROM_Data” instruction selected, observe the highlighted disassembly line. o The first column is the address of that instruction, 0xD0 in this case.
o The second column is the machine op-code for this instruction, which is what the microcontroller reads to know what to do but will be of very little use to you.
o Next is the instruction mnemonic, LDR in this case. o Then the operands, “r1” and “[pc,#64]”. r1 is CPU register 1, but what is [pc,#64]?
[x] means x is an address, so this instruction will load r1 with the value at the address inside the [ ]. pc is the Program Counter (i.e. R15) which indicates that this instruction uses PC-relative address mode and the value in PC is the reference address. The #64 is the offset address. But how does any of that help you find the actual address of ROM_Data?
Because of the pipeline nature of the ARM core, it is difficult to calculate the absolute address of an instruction using PC-relative address mode. Fortunately, Keil knows this and provides the information we need in the comment at the end of this instruction.
Notice the comment (after ;), “@0x00000114”. This tells us
address data
PC-rel. instr. Program data
Address X Value X
PC-relative operands
Address Y Value Y
ROM
constants

Illustration of how a ROM address is mapped to a PC-relative instruction. Here the PC relative instruction points to Address X, a memory cell reserved after program data to store operands for PC-relative instructions. Address X contains Value X which is, in this case, the address where Value Y can be found, i.e. Address Y. Here, Address Y is what has been assigned to the label “ROM_Data”.
that the value of ROM_Data is stored in ROM (all PC-relative instructions store addresses in ROM) at (@) 0x0000.0114. So if we look in 0x0000.0114 we can find the value of ROM_Data. But how do we look at that address?
There are two ways we can find what data is stored at 0x0000.0114. First, we could look in the Disassembly panel and see what’s at address 0x00000114. However, because disassembly data is shown in 16-bit units, it is very difficult to read 32-bit values. You can look if you want, but it I recommend you save yourself the confusion and not do this!
The second (preferred) method is to set a Memory panel to view that address. Let’s do it!
13. View memory where the value of ROM_Data is stored.
• In the bottom right of the Keil Debug Mode window, select the Memory 1 tab.
• In the Address space, type the address where the value of “ROM_Data” is stored
(0x00000114), with 0x prefix, then press ENTER. (Sometimes the memory panel will update without pressing ENTER but it will not hurt if you do).
• You should see a 32-bit value, stored little endian, in addresses 0x0114 – 0x0117. Without executing the program, record this value on your Worksheet.
• The data at 0x00000114 is the value of the label ROM_Data (which is an address). This does not tell you what values are stored at ROM_Data, only the address where they are stored. To help solidify this point, record on your Worksheet the starting address for program constants stored at label ROM_Data.
Hint: The data stored at 0x…114, the value of label “ROM_Data”, and the address where ROM constants are stored are all the same.
So, for PC-relative instructions, the address in the instruction “points to” the address of the data we want. Think of this like the Guide channel on cable TV; you look at the Guide to see which channel has the show you want, just like you look at the PC-relative address to find the address of the data you want.
14. Now that we know the value of ROM_Data, we are finally ready to look at the values stored at ROM_Data. Let’s do this in a new Memory panel.
• Within the bottom bar of buttons at the top of the Keil Debug Mode screen, near the middle, is a button called Memory Windows with a drop-down list to activate memory panels.
• Click the small triangle right of this button to see a list of memory panels, then select Memory 2. A new panel called Memory 2 should now be open in the bottom right of your screen.
• Select Memory 2 tab and type the value of “ROM_Data” (with 0x prefix) in the Address area then press ENTER.
Now we have Memory 1 tab showing the PC-relative addressing value of ROM_Data and Memory 2 tab showing values at ROM_Data. We also want to observe “RAM_Data” so let’s open a third Memory panel.
15. Use the Memory Windows button to open a Memory 3 panel and set its Address to 0x1FFFF100 (1FFF.F100).
You could follow the same steps above to identify the value of RAM_Data (the disassembly tells us RAM_Data is stored @ 0x110). To save time, we’ll just give you this one.
Note: it is possible that your compiler for some reason assigned a different address to RAM_Data. If you discover that RAM values are not showing properly in the steps below, double-check the address for RAM_Data.
16. In the main.s source file, scroll to the Main function. Notice the first three instructions are PCrelative instructions that will load values from ROM (but not at ROM_Data). Let’s reset the Memory 1 panel to 0x00000110 (0x110 works too) so we can observe all of the PC-relative constants being read (loaded). Starting at 0x00000110, Memory 1 should contain three 32-bit values, stored little endian. Record these 32-bit values on your Worksheet.
Now that the memory panels are all set up, it’s time to Step through the instructions again and observe their effects on memory. Be sure you take your time to learn what each line is doing and are able to explain it, for example on an exam!
If you have Run or otherwise executed any code since last restarting the Debug session, please exit Debug and start again; you need a fresh start to see why we went through all the effort to create memory panels. Keil *should* save your memory panels and open them again when you restart debugger.
17. In main.s, let us once again let’s skip over the initialization code prior to the Main function by right-clicking on the first memory access instruction (line 60) and selecting Run to Cursor line.
18. The first three instructions are PC-relative “loads” that will access memory at 0x00000110. So, click on the Memory 1 tab to display it. With an eye on the Memory 1 panel, click Step (or press F11) to execute the first instruction and observe what happens in Memory 1. If you miss it, exit debug, restart, run to line 60 and try again.
19. Click Step (F11) to execute the next two instructions (only the next two) and observe what happens in Memory 1. Record your observation on the Worksheet.
20. The next nine instructions are loads that will primarily be loading constants from ROM_Data, so activate the Memory 2 panel to display memory starting at ROM_Data.
When you switch to Memory 2 panel you may notice that some of the data here is already highlighted in Red text. This is due to the initialization code that we always skip over so you do not need to worry about it.
21. For each of the 9 remaining load (LDR) instructions, Step through slowly, line by line, and try to see exactly what is happening with each instruction. Pay particular attention to the size of data (word, halfword, byte) being loaded. You may want to double-check your answer to the questions in Step 9.
A great way to study these instructions is to try to predict the result of each instruction before you hit Step and then observe if your predictions were correct or not.
There is no better way to learn this fundamental feature of microcontrollers and assembly than simulating and observing. If you get lost or confused or just want to see something again, exit debug, restart, run to wherever-you-want-to, and then Step while observing. Task D: Observing memory for Store and Move instructions
22. Once you have tested the load instructions, activate Memory 3 panel and Step through the four store instructions, one line at a time. Comment on your observations in the Worksheet. If you need to clear the memory indicators (colored text), exit debug, restart, and run-to line 78. Repeat as necessary to learn how these store instructions work.
Again, we suggest that you try to predict the result of each instruction before you hit Step and then observe if your predictions were correct or not.
23. Finally, Step through the three move instructions one more time. These move instructions do not interact with memory (only CPU registers) so you can ignore the memory panels.
24. Review Exercise 2 and summarize what you have learned about assembly and about using the Keil uVision IDE in your Worksheet.
Exercise 3: Writing and Debugging Assembly Instructions (estimated 30 min)
Now that you have observed many variations of memory access commands, we’ll put your knowledge to the test by writing lines of assembly that will achieve specified goals. To aid in this exercise, you will use a skeleton source file that includes some existing blocks of code to which you will add your code.
Task A: Create a new project using an existing skeleton source file
1. From the Keil Edit Mode window, close your Exercise 2 project using Project Close Project.
Note, you must exit the debugger before you can close a project.
2. Follow the first few steps of Exercise 2 to create a New uVision Project in the Project4ex3 folder with a project name of ex3. Then, add the existing main.s file to the source group.
If you need assistance, refer to the Keil_Assembly_Guide on Slides 10&11. Your new project will be at the path directory ECE331 netID KeilProject4ex3ex3.uvproj
Task B: Load some data
The bottom of the ex3main.s skeleton file includes DCD directives to assign some data values starting at the label ROM_Data. Beneath the “Start Task B:” comment (line 58), several pre-defined instructions are included to load values into R0, R1, and R2. Do not alter any of the pre-defined instructions. Likewise, do not alter any of the instructions past the Task B section.
3. Beneath the three pre-defined Task B assembly load instructions, add assembly instructions to complete the following tasks. Note that some load instructions do not permit constant offsets
and instead you will need to use register offsets (i.e., first load the offset into a register, then use that register as an offset).
• Load value of 0x8 into R3
• Load word from [ROM_Data] into R4
• Load unsigned halfword from [ROM_Data +4] into R5, where ‘4’ is an address offset
• Load signed byte from [ROM_Data +8] into R6, where ‘8’ is an address offset
4. Build your code to check for syntax errors and correct as necessary. If you do correct errors, comment on what you fixed on the Worksheet. Then test your code in the simulator to ensure it is working correctly. You only need to test the 4 lines you added.
Reminder: You must Build code after making changes or the changes will not be simulated. Task C: Store some data
5. Immediately beneath the “Start Task C:” comment, add assembly instructions to complete the following tasks. You may use values in any register including those loaded in Task B, but do not add instructions except those listed here. Also, do not alter any of the instructions outside the Task C section.
• Load value of RAM_Data into R7
• Store byte in R6 to [RAM_Data]
• Store halfword in R5 to [RAM_Data + 4]
• Copy value in R6 to R4
• Store word in R4 to [RAM_Data + 8]
6. Build your code to check for syntax errors and correct as necessary. Then test your code in the simulator to ensure it is working correctly. Note, you will need to execute all of the code prior to Task C section in order for this section to work correctly.
7. Take screenshot of the code you wrote for Tasks B and C and attach them in Worksheet.
Submitting ALX Assignments
Refer to D2L instructions for this ALX for deliverables and deadlines for submitting them.