Вы находитесь на странице: 1из 17

FAE Training October 2010

Introduction
This lab will familiarize you with the IAR Embedded Workbench for ARM and will utilize the Fujitsu KSK-MB9BF506 evaluation board. EWARM has the ability to simulate a generic Cortex M3 core, but for the purposes of this lab, we will utilize the F506 evaluation board and an IAR J-Link. Upon completion of this lab, you will have a better understanding of how EWARM functions so that you can create your own projects as well as be confident when you are conversing with customers who also use the IAR toolchain. The lab is written for EWARM v5.50 but older versions of the tool will resemble the pictures contained therein. Since the overall footprint of the application that we will develop is around 3kB, it can be built with any version of EWARM (full, evaluation or KickStart). While the easiest way to get started on a project is to modify an existing one, this lab will assume that we are building one more-or-less from scratch.

Part 1 Connecting hardware and creating a workspace


1.) Lets begin by connecting the hardware to the J-Link and to the computer. Please connect your hardware as follows (the USB cable to the J-Link should be connected to your computer):

FAE Training Lab

2.) Start the Embedded Workbench for ARM. Once EWARM is loaded, you will notice that the Information Center is visible. From the Information Center, you can view the sample workspaces for your board. For this lab, however, we will be building our own application from scratch. 3.) You should have a copy of Fujitsu.zip, a zip file which contains the source code as well as the Linker Configuration File, setup macros, and flashloaders that will be necessary for our project. We will be adding these to our project. In practice outside of this lab, you can create new source code and header files that can be included in the project. This zip file should be unzipped in the ..\My Documents\IAR Embedded Workbench\ directory. 4.) Click File-New-Workspace. You should now have a blank slate that looks like this:

FAE Training Lab


5.) We now need to add a project to our Workspace. The project will contain the source code for our application. Click Project-Create New Project. Choose Empty project from the following dialog box and click OK:

6.) We will be asked where we would like to store our project; by default, workspaces and projects are stored in the ..\My Documents\IAR Embedded Workbench\ directory. Well choose the Fujitsu FAE Training Lab directory that we unzipped earlier. Name the project F506 blinky and click Save. We now have a project with no files:

FAE Training Lab

7.) Next, we will add code to our project. Our blinky example uses code from a couple of different directories, so we will add code for each of these separately to make it easier on ourselves. You will notice that the code in Fujitsu FAE Training Lab directory is contained in three spots: main.c in the root directory, board support files in the modules directory and the startup file in the startup directory. In order to keep our code organized, we will preserve that directory structure within the IAR workspace through the use of groups. Lets begin by adding the code from the modules directory. Click Project-Add Files. In the window that pops up, double-click the modules directory. Select the two C files drv_hd44780.c and drv_hd44780_l.c and click OK.

8.) To keep our code organized, we will put these files in a group. Click Project-Add Group. Name the group modules and click OK. You will see a modules folder in your Workspace window. Drag and drop each one of the three source files we just added into the CMSIS folder. Note that adding groups to your project and putting code in those groups does not impact EWARM at all it is to help the engineers keep their code organized.

FAE Training Lab


9.) Repeat steps 7 and 8 for the startup folder, selecting cstartup_M.s to add to the project. Create a group called startup and add that file to the drivers group. Note that adding startup code to your project overrides the default behavior of EWARM which is to grab generic startup code from the toolkit installation directory. This allows you to customize your startup code! 10.) Finally, add main.c to the project. We will leave main.c in the top-level project directory. 11.) Double-click main.c to open it in the source window. Notice in the lower left-hand corner of the source window is a small button labeled f( ) click this button and you will see a list of all the functions in main.c. Double-click main( ) to go to the main( ) function.

12.) Notice that there is a function called HD44780_IO_Init( ) near the top of main( ). Rightclick that function name and choose Go to definition. The source window will open drv_hd44780_l.c and take you to the declaration of that function. To go back to main( ), click the Navigate Backward button on the toolbar near the top of the IDE. 13.) Click View-Source Browser. You will see a Visual C++-like source browser that shows you the functions, structures and defines that are in your code. Double clicking any one of these will take you to their definition in the code. A few things should be noted at this point. First, a project has by default two build configurations, Debug and Release. The difference between them is that Debug has Low optimization set and Release has Medium optimization. We will learn how to change that in part 2, Also, files are saved every time you do a build. You can quickly thumb between the open files in your source window by clicking the file name tab at the top of the source window.

End of Part 1

FAE Training Lab


Part 2 Configuring project options for the workspace
One of the more important parts of making your project work correctly is selecting the correct options from EWARMs options dialog box. From this box, you can configure almost everything your project will need to behave the way you want it to act. 1.) In the Workspace window, right-click the F506 blinky project and choose Options. Alternatively, you can click the F506 blinky project and click Project-Options.

Notice that the default is for an ARM7TDMI core, but we are using the F506 CM3. Under Processor Variant, choose Device and select Fujitsu and then the MB9BF506.

FAE Training Lab


2.) Click the Output tab and make sure that Executable is selected since we will be ultimately downloading this to the evaluation board instead of creating a library to be used in another application. 3.) On the Library Configuration tab, make sure that your runtime library is set to Normal. If you need to save code space, you can set the RTL to none or Custom; if you set it to custom, you should add another project to your workspace and this time choose DLIB. This DLIB project will allow you to remove parts of the RTL that you dont need in order to save code space or make special modifications to the RTL to suit your needs. 4.) On this same tab, make sure that the low-level interface is set for Semihosted so that printf( ) statements can output data to the Terminal I/O Window. 5.) Next, click the C Compiler Category. Under the Language tab, select C. From this tab, you can also choose whether or not to require function prototypes in your code. The default behavior is to not require these prototypes. 6.) Under the Optimizations tab, notice that the default behavior for the Debug release configuration is to have Low optimization. You can change this to whatever you like, but notice that when you choose Medium or High optimization, you can choose which transformations are applied to the code. Details of each transformation can be found in the EWARM Developers Guide. 7.) Under the Output tab, make sure that Generate debug information is selected. If you are attempting to debug code and the C-Spy debugger complains that there is no definition for main( ), it is probably because this box has been unchecked. We need this to be checked so that the debugger can reference the source code to the disassembly. 8.) Under the List tab, select Output list file and Assembler mnemonics. This will show us what source statements generate what assembler code in our list files so that they can be studied without having to run a debug session. 9.) Select the Linker category. Under the Config tab, you will notice that generic_cortex.icf is selected as our linker configuration file. We have a couple of files in our projects config directory that we can use, MB9BF500_Flash.icf and MB9BF500_Ram.icf. We will choose the former to put our code into flash so that we can run our code without the debugger attached. Check the box for Override default and then click the box with the ellipsis next to the file name to open a file browser window. Navigate to your project directory and select MB9BF500_Flash.icf and click OK. Notice that this will put the full path in the box you can edit this to be $PROJ_DIR$\config\MB9BF500_Flash.icf to make the project more portable.

FAE Training Lab


10.) Under the Output tab, make sure that Include debug information in output is checked so that C-Spy will be able to link our source code to the disassembly. 11.) Under the List tab, check the box for Generate linker map file. This file will show us where our code modules are going in the final application as well as their sizes. 12.) Click OK to save all the changes we have made to the Project Options. There are still more things that we will configure, but we will do this when we get to the section on debugging our code on the target.

End of Part 2 Part 3 Compiling and linking our project


In this section, we will build our application and look at where the linker has decided to place our code. We will also explore different ways to look at the size of our code so that we can see what optimizations will do to our project. Finally, we will explore moving code sections to predefined addresses so that we can create some space between code modules a common practice in updatable fault-tolerant systems. 1.) Build our project by either clicking Project-Make, by pressing F7 or by pressing the Make button ( ) from the toolbar. When you do this, EWARM will save all source code and will pop up a window to ask you what name you want to give to the overall workspace. In this window, choose to call the overall workspace blinky and save it in our workspace directory. 2.) You will notice that we get a warning that there is a statement in main.c that is unreachable. By double-clicking this warning, we are taken to the offending statement in main.c it is the return statement. Sometimes engineers will place failsafe code in faulttolerant systems as a catch-all that should never be reached (at least not through any path of execution of which they could conceive). We can choose to suppress this warning so that we dont see it again. Click Project-Options-CCompiler-Diagnostics and type in the IAR number of this warning (Pe111) and click OK. Choose Project-RebuildAll and notice the warning is gone!

FAE Training Lab


3.) In the Workspace window, click the plus sign next to the Output folder to see its contents. You will see that it has the application as well as the map file.

4.) Double-click the map file in the Workspace window so that we can see what the sizes of our modules are as well as where they are placed. Near the end of this file, we see that the main( ) function is located at address 0x30F and is of size 0xB4 bytes (the location and size may vary depending on the settings you chose).

FAE Training Lab


5.) If we want to see the sizes of the individual files as well as the size of the overall application, we can set the Build Messages Window to provide us with this information. Click Tools-Options and under the Messages category, set Show build messages to All.

6.) Click Project-RebuildAll so that we can see the sizes of the modules. Scroll through the Build Messages Window to see that main.cs size is 990 bytes of code, 172 bytes of constants in flash and 8 bytes of RAM while the overall application is 2,960 bytes of code and 2,064 bytes of RAM with an additional 276 bytes of constants in flash. Also note that the Build Messages Window shows you the command line invocation of the tools on individual files in the project, so had we chosen to log the build messages in step 5, we would almost have a complete makefile. 7.) Lets move the main( ) function to address location 0x1000. We can do this by adding a pragma directive just before the main( ) function. On the line before int main( ), add this line: #pragma location="MyMainFunction Next, open the ICF file we chose with a text editor. Find the line: place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; Once you have located this line, place the following line just after it: place at address mem:0x1000 {section MyMainFunction}; Now, return to the project and do a RebuildAll. You will notice that in the map file, the location for the main function has changed. Note that instead of giving us the address of 0x1000, the address is 0x1001. In Cortex M3 architectures, data is even-byte aligned but code is odd-byte aligned.

End of Part 3

FAE Training Lab


Part 4 Downloading and debugging our project
In this section of the lab, we will download our project into the target and run it as well as explore some of the different options we have for debugging code. However, we first need to setup just a few more details in the Project Options before we can do this. 1.) The first option to change is Project-Options-Debugger-Setup. We need to change the Driver from Simulator to J-Link/J-Trace so that the code will go to the hardware target instead of IARs Cortex M3 core simulator. 2.) Next, we need to run some pre-defined setup macros. These setup macros are executed immediately after code is downloaded into the device and put the MCU in a pre-set state. In general, engineers who have problems running their code off the debugger (it works great when the debugger is attached, but it doesnt run when I take it off the debugger) are probably not executing startup macros. What they need to do is copy the functionality of the setup macro into their startup code so that the processor is in the same state as it is when the debugger is attached. We have a macro file defined for us in our workspace directory. Check the box for Use macro file then click the box with the ellipsis to open a file explorer box. Select the Flash.mac file in the config directory. 3.) Notice on this tab that the Device Descriptor File (*.ddf) was already selected for us when we chose the F506 chip in General Options. The DDF provides the addresses and names of the Special Function Registers (SFRs) on the chip. 4.) Also notice the Run to main option. By default, this option is checked. When checked, the behavior for debugging will be to have the MCU run through all the startup code and then halt on the first statement of main. If unchecked, the debugging session will breakpoint at the first instruction of cstartup, just like the board has gone through the reset vector. 5.) Click the Download tab. Check the box that says Use flash loaders. A flashloader is a file that is downloaded into the RAM of the board and does an In-System-Programming of the board, i.e. it takes code that is downloaded from the USB of your computer and through the JLink and burns it into the internal flash of the MCU. For our target, a flashloader has already been created and will be used when you check this box. If a customer is downloading to an external flash on their production board, it might be necessary for them to make their own flashloader. Sample flashloader projects are in the toolkit directory to help them get started.

FAE Training Lab


6.) Next, click the Plugins tab. In this tab, you will find plugins that make the C-Spy debugger RTOS aware as well as providing handy debugging and testing tools such as Code Coverage, Profiling, Stack and Symbols. Make sure that these last four are selected near the bottom of the menu. The RTOS plugins are created by the RTOS vendors, but in general any OSEK ORTIcompliant RTOS can be used to have kernel-aware debugging in EWARM. Other RTOSs (like Embedded Linux) can be used, but you will not have kernel-awareness by the debugger. Also note that the Stack plugin is not currently RTOS-aware, so if you are using an RTOS, you should disable this plugin otherwise you will constantly receive messages in the debugger window that your stack is out of range. 7.) We need to configure our J-Link interface. Click Project-Options-JLink. In the first tab, notice that the speed has been set to Auto at 32kHz. This is fine for our application, but if you are debugging an application with large structs or arrays, you might want to experiment with adjusting this speed to minimize the loading time from the target to C-Spy for those large data sets. The maximum speed is 12MHz, but running at this speed can cause timing issues downloading code. 8.) Next, view the Connection tab. For the interface, choose Serial Wire Debug instead of JTAG. SWD replaces the 5-pin JTAG port with a clock + single bi-directional data pin, providing all the normal JTAG debug and test functionality plus real-time access to system memory without halting the processor or requiring any target resident code. SWD uses an ARM standard bi-directional wire protocol, defined in the ARM Debug Interface v5, to pass data to and from the debugger and the target system in a highly efficient and standard way. Only 2 pins required - vital for very low connectivity devices or packages Provides debug and test communication to JTAG TAP controllers Enables the debugger to become another AMBA bus master for access to system memory and peripheral or debug registers High performance data rates - 4 Mbytes/sec @ 50 MHz Low power - no extra power or ground pins required Small silicon area - 2.5k additional gates Low tools costs, $100 build costs - may be built in to evaluation boards Reliable - built in error detection Safe - protection from glitches on pins when tools not connected SWD provides an easy and risk free migration from JTAG as the two signals SWDIO and SWCLK are overlaid on the TMS and TCK pins, allowing for bi-modal devices that provide the other JTAG signals. These extra JTAG pins can be switched to other uses when in SWD mode.

FAE Training Lab


9.) We are now ready to download and debug our application. Click OK to close the Project Options window and then press the Download/Debug button on the toolbar. 10.) You will see a few windows pop up that indicate that the code is downloading to the device and then the device will execute the startup code and stop at the first instruction of main( ). Lets explore some of the breakpoint functionality of EWARM. In the main( ) function, locate the line of code which says: cntr--; You can set a breakpoint on this line by right-clicking the line and choosing Toggle Breakpoint (Code). Alternatively, you can put the cursor on that line and press F9. Now click ViewBreakpoints to see a list of all breakpoints currently active.

From this window, you can modify any breakpoint. However, let us execute the code up to that breakpoint you can do so by pressing F5 or pressing the Go button ( ) to execute the code. Notice that the breakpoint window now has a green arrow next to the breakpoint to indicate that is where you currently are halted. If we want to change the behavior of this breakpoint to stop, say, every hundredth time it hits the breakpoint, we can do so by turning this breakpoint into a conditional breakpoint. Right-click the breakpoint in the Breakpoint Window and choose Edit. In the Skip count section, put 100 and click OK.

FAE Training Lab


11.) Begin executing your code again. Notice that the breakpoint is being skipped, but in the Breakpoint Window, you can see a count of how many times the breakpoint has left in the skip count, i.e. how many times it must be hit again before execution halts. Depending on the speed of your computer and SWD connection, this count may go really quickly or somewhat slowly. When setting a conditional breakpoint, you can also use an expression statement; this statement can be any syntactically valid C statement, e.g. cntr <= -100 Note that this can slow down your debugging session because the SWD has to pull the value specified in the condition every time the breakpoint is hit to see if the condition is true. 12.) Now, lets explore what a data breakpoint can do. Execute code until you hit your breakpoint at cntr;. If your Disassembly Window isnt already open, open it by clicking View-Disassembly. Now click in the Disassembly Window so that we can single-step at the disassembly level rather than the source level.

Remember that the green arrow indicates if we are debugging at the source- or disassemblylevel (by clicking back in the source window, we can return to source-level debugging). Now lets see where the PSW1 button is located in memory. We can single-step to the source line of if(~(BUT_PDIR&PSW1)), we can see that the address of the button will be loaded into R0. Press F10 or the Step Over button to load the address of the variable into R0 by looking at the Register Window (View-Register if it isnt already visible), we see that the address is 0x40033314. Also note that windows in the IDE can be docked, i.e. they can be dragged-anddropped on top of one another. This can help clean up your IDE view so you can see what is currently important to you!

FAE Training Lab


13.) Now, lets add a data breakpoint at that address. In the Breakpoint Window, right-click in an unused area and select NewBreakpoint-Data. In the window that pops up, click Edit and choose an Absolute address. Set the address to be 0x40033314 (assuming that your address is the same as mine, which will depend on your compile options) and click OK.

Now we can choose options of breaking when the data is read, written or both. Additionally, we can choose to break only when the data matches a certain pattern. Lets set it for breaking only when the data is written. In our Breakpoint Window, delete our old code breakpoint by either selecting it and pressing Delete or right-clicking the breakpoint and clicking Delete. Now run the code and you will see that you quickly hit the data breakpoint! Breakpoints can be turned off without deleting them by unchecking their box in the Breakpoints Window. 14.) Open the Watch Window by clicking View-Watch. We can watch the values of variables, arrays and structures within this window. To quickly insert an element in the watch window, double-click the element name in the source window and drag-and-drop it into the Watch Window. Try double-clicking cntr and then drag-and-drop it into the Watch Window.

FAE Training Lab


15.) The Quick Watch Window is a little different than the Watch Window because it allows you to choose when to evaluate the expressions. Moreover, the Quick Watch Window allows you to execute macro functions defined in your macro file. In our SmartFusion.mac file, we have a macro called execUserReset() which resets the processor. By putting that expression in the top of the Quick Watch Window and pressing the Evaluate button ( ), we can reset the processor.

16.) Now, lets try attaching to a running target. This is useful if you have a board that is running code out in the field but has suddenly gone off in the weeds. This technique allows you to see what is happening on the board. To see this at work, deselect all breakpoints from the Breakpoint Window and click Go or press F5. Now press the Stop Debugging button on the toolbar ( ). You should see the LED on the board continue to blink so long as there is still power to the board this simulates a board running in the field. If youd like, you can detach the debugger from the board to see that it is still running (but you will need to externally power your board) and then reattach it to make sure that the board is completely running on its own volition. Now go to Project-Options-Debugger-Download and select Attach to program notice that this will automatically deselect the Use flash loader option.

FAE Training Lab


Click OK and now click Debug without Downloading from the toolbar ( ). This will attach the debugger to the running target. Notice that the debugger toolbar indicates that the target is running. You can halt the target by pressing the Halt button on the debugger toolbar ( ). Notice that the debugger now correlates the targets current Program Counter with the source code in both the Source and Disassembly Windows. You can now debug normally!

Вам также может понравиться