## Using GCC in Keil : Best of Both worlds

Saturday, April 19, 2014

We were evaluating different IDE's for development with our newly acquired STM32 board that we posted about earlier and a new Stellaris Launchpad . The initial example that we covered was completed in Keil environment. Next we wanted to extend beyond the 32KByte limit imposed by Keil so we need to look for alternatives. Although we were quite happy with coocox IDE, we needed some thing with lot more debugging options. Even though the CCS IDE from TI is good but for older PC's like ours its difficult. This lead us to work with Keil, but under the hood GCC would do the heavy lifting.

We would explain the process of compiling for thee different ARM Cortex-M3 architectures and all that you would need to get started on that.

UPDATE 19,Apr 2014: There has been some changes to the STM32 Standard Libs location

[1] IDE & Compiler:
First we need to get the compiler and the IDE ready. For this we need to download the following:
Now we have both of them. Installation of Keil is pretty straight forward, so we would omit that detail. Its important that you install the GCC Arm Embedded package in the top most folder like
"E:\ARMGNU\4.6 2012q2\"    or    "C:\ARMGNU"
This would make the compiler path to be simple. Also when the installation ask for path configuration at the end of the installation check on 'Add to Path ....' .This would help to locate the compiler easily and also reduce the mess of relative paths.

[2] Support Libraries for Microcontrollers:
An essential thing with GCC is the availability of the linker files and from the chip perspective the peripheral libraries. To achieve this we need to download three separate packages for the three chips that we have selected:
• EFM32 : http://www.energymicro.com/simplicity
Basically you need to download the Simplicity studio and update all the "emlib" & "CMSIS" components. We actually downloaded the whole suit so that we have all the things including the data sheets and the demo packages.
• STM32New Standard Libs Location
This gives the complete STM32 peripheral libraries as well as the start up code needed for the compile. OLD: STM32F10x standard peripheral library (Inactive)
• Stellaris M4 - Launch Pad : Stellaris Ware SW-EK-LM4F120XL (v9453)
This again includes the ROM firmware Mapping as well as the linker files needed to compile the code. The best part is that the driver libraries have been compiled already for GCC so its easier to integrate. The only issue is that the download requires you to signup at TI website and then agree on Export agreement to get the download. The "SW-EK-LM4F120XL" gives the very specifics of what we need for launchpad so we would suggest going for that. Also the "pinMux" utility can be helpful for generating peripheral initialization code.

[3] Prepare the Development Environment:
Now we need to get the directory prepared so that we can make our first project in all of these microcontrollers. We have created the following directory Structure:
F:\WS
|
+-- \wsSTM32         <--- For STM32 microcontroller
|
+-- \wsEFM32         <--- For EFM32 microcontroller
|
+-- \wsTIM4          <--- For Stellaris M4 microcontroller

This would allow us to make the build environment simultaneously for all the three microcontrollers.
Now for the instructions to copy the required folders for the development environment to work:
• EFM32
Here is a list of the folders found in the installation directory "energymicro" of the Simplicity Tool. (You can navigate to the required installation folder 'energymicro' using "File" menu=>"Browse Installed Files".)
• Copy "CMSIS\Include" => "wsEFM32\CMSIS\Include"
• Copy "Device" => "wsEFM32\Device"
• Copy "emlib" => "wsEFM32\emlib"
• Additionally you can also copy "CMSIS\Lib\GCC" to have the Math functions if desired.
• No need for library generation as the peripheral library would be integrated into the code at compile time.
• STM32
Here you need to extract the zip file stm32f10x_stdperiph_lib.zip into the directory "STM32F10x_StdPeriph_Lib_V3.5.0" from which we would be copying the following directories:
• Copy "Libraries\CMSIS\CM3\CoreSupport" => "wsSTM32\CMSIS"
• Copy "Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x" => "wsSTM32\STM32F10x"
• Copy "Libraries\STM32F10x_StdPeriph_Driver" => "wsSTM32\STM32F10x_StdPeriph_Driver"
• Copy "Project\STM32F10x_StdPeriph_Template" => "wsSTM32\STM32F10x_StdPeriph_Driver"
• We would not go for library generation as we would integrate the required peripherals at the compile time.
Here we need to install the Stellaris Ware package and it installs everything into a directory "StellarisWare". We need to get the following directories:
• Copy "driverlib\gcc-cm4f" => "wsTIM4\lib"
• Copy "usblib\gcc-cm4f" => "wsTIM4\lib"
• Copy "utils" => "wsTIM4\utils"
• Copy "inc" => "wsTIM4\inc"
• Copy "boards\ek-lm4f120xl\hello\hello.ld" => "wsTIM4"
• Copy "boards\ek-lm4f120xl\hello\startup_gcc.c" => "wsTIM4" - This file needs to be individually copied and modified for every project as the Interrupt vectors and the stack needs to be defined.
Finally your directory structure should look like:
This means we are ready to make our first step into the project development.

[4] Target Hardware Installation:
We need to get our targets for hardware installed first. This is a mandate since we would need debugging capability as well. Listed below are the Targets for each of the platform that we are going to use:
• EFM32 : EFM32GG-STK3700
This kit has an on-board J-link and a host of peripherals that help to demonstrate the capabilities of EFM32. You need to do driver installation from "energymicro\installers"; the J-link driver. Upon connecting the kit you can check the status if every thing is working using the "EnergyAware Commander" tool from "Simplicity". Just click on the "Connect" button on the "EnergyAware Commander" then it would get connected to the board. Now you would be able to see the board connected says "EFM32 Giant Gecko Starter Kit" shown in the "Board:" section and the "Debug Mode:" is "MCU". In case you wish to use the J-Link to debug some thing out side just change "Debug Mode:" to "OUT" that makes it a SWD J-Link Debugger for any EFM32 chip.This way you can even program your own boards.
• STM32 : Our newly acquired STM32 board
This is not a standard board and hence there is no need to install the drivers. We would use the J-Link provided by one of our friends to debug this board.
• Stellaris M4 Launchpad : EK-LM4F120XL
For this board the ICDI drivers you would need to download them from:
http://www.ti.com/tool/stellaris_icdi_drivers
It would ask for driver installation 3 times and you can point to the location of the extracted zip file for the ICDI driver. This would install a Virtual COM port device and two Debugging devices.

This completes our installations needed for the hardware target.

[5] Creating the first Project
For the ease of implementation we would like to choose a simple project of "Blinky" for all the microcontrollers. This would demonstrate how to create the project , assign the compiler as well as add the dependencies properly. Now we need to create the project directories first. We prefer to create a separate project folder, lst folder for listing files and obj folder for object files and outputs. Here is how your directory structure would look like after creating the projects in each of the microcontroller workspaces.
We now have the project created for all the microcontroller with the correct directory arrangements. Lets start with creating the project and writing the code for the individual microcontrollers.

1. First we need to open the Keil uVision4 IDE:
2. Click for the New uVision Project
3. Now set the correct path to the Blinky Project workspace directory ("wsEFM\00_blinky\proj") and save the project file as blinky.uvproj by clicking on the "Save" button.
4. Next you would need to select the correct microcontroller for the EFM32GG-STK3700 we need to select the EFM32GG990F1024 microcontroller.
5. Keil would ask you to include the default "startup_efm32gg.s" click on "No" to continue.
6. Now to add the required files, open the "Target 1" on the Left hand side of the screen and right click on the "Source Group 1" and select the "Add Files to Group 'Source Group 1' ... " option.
You need to traverse to the Workspace directory of EFM32 ("ws\wsEFM32") and select the following files and keep clicking on the add button till all the required files have been added.
For Assembly file Change the search filter to "Asm Source file (*.s .."
ws\wsEFM32\emlib\src\em_cmu.c
ws\wsEFM32\emlib\src\em_emu.c
ws\wsEFM32\emlib\src\em_assert.c
ws\wsEFM32\emlib\src\em_gpio.c
ws\wsEFM32\emlib\src\em_system.c
ws\wsEFM32\Device\EnergyMicro\EFM32GG\Source\system_efm32gg.c
ws\wsEFM32\Device\EnergyMicro\EFM32GG\Source\GCC\startup_efm32gg.s

After including these files you need to add the main.c Source code. To do so, go to in "File Menu" and click on "New File" to create this file. Now copy paste the code into the editor window.
#include <stdint.h>
#include <stdbool.h>
#include "efm32.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"

void _exit(int code)///New lib SysCall
{
while(1);
}
int main()
{

uint32_t i;
/* Chip errata */
CHIP_Init();

/* Enable GPIO clock */
CMU_ClockEnable(cmuClock_GPIO,true);

/* Init the LEDs */
GPIO_PinModeSet(gpioPortE,2,gpioModePushPull,0);

while(1)
{
GPIO_PinOutToggle(gpioPortE,2);
for(i=0;i<0xfffff; i++);
}
}


Now the main.c is ready. Save it at the following location:
Then you need to add this file into the project in the same way as demonstrated earlier while adding the system files.

5. Now you need to configure the compiler. For that go to the "Project" Menu select "Manage" and then click on "Components, Environments, Books...".
Go to the "Folders/Extensions" tab and check the "use GCC" check box. It would show a warning and say yes to that. Now fill in the Path of the "ARM GNU Embedded" installation done earlier. For us it was "E:\ARMGNU\4.6 2012q2\" so we have set that, you can set the correct as per your installation. The click on "ok" to continue.

7. Finally we need to make the project settings to make it compile for GCC. To do this Right Click on the "Target 1" and then click on "Options for Target 'Target 1'"
Go to the "Output" Tab click on "Select Folder for Objects..." set the folder to "obj" then click on "Ok" to continue.
Next Go to the "Listing" tab and check the "Assemble Listing.." and "Linker Listing .." Check boxes. Finally to set the  listing folder click on the button "Select Folder for Listings..." and set the folder to "lst", then click on "Ok" to continue.
Next go to the "CC" tab and add the preprocessor definition to "Define" as "EFM32GG990F1024". Remove the checks from "Enable APCS ..." and "Support Calls between ..." check boxes. Add the check to "Compile Thumb Code" option. Set "Include path" to
"..\..\CMSIS\Include";"..\..\emlib\inc";"..\..\Device\EnergyMicro\EFM32GG\Include"

Make sure you get this line properly else the compilation fails.
Next go the "Assembler" tab and set the "Include Path" to
"..\..\CMSIS\Include";"..\..\emlib\inc";"..\..\Device\EnergyMicro\EFM32GG\Include"
And then remove check from "Enable ARM/Thumb Interworking.."
Next go to the "Linker" Tab and remove the checks from "Do not use Standard System ..." and "Use Math Libraries". Now set "Linker Script File" to "..\..\Device\EnergyMicro\EFM32GG\Source\GCC\efm32gg.ld".
Next go to the "Debug" Tab and connect your EFM32GG-STK3700 to the PC.Select the "Use" radio button near to "ULINK.." shown in the combo box. Se this combo box to "J-Link / J-TRACE Cortex" and then check the "Run to Main Option".
Now click on the "Settings" Button next to the JLink selected in the combo box. If everything is ok then it would bring up the proper J-Link detection of the micro on the STK. If not check the "Port" option and make it as "SW", then click "ok" and retry the Settings it should work.
Now go to the "Utilities" tab and change the combo box to "J-Link...". Check the "Update Target before debugging" check box.
Next click on the "Settings" Button and it brings up another window. Check the "Reset and Run" check box. Then click on "ok" to continue.
Finally we are done with all the settings now click on "OK" in the "Options for Target 'Target'" window.

8. Its time to make the program. So click on the "Build" icon or press "F7"

Well you might get the error:
../../Device/EnergyMicro/EFM32GG/Source/GCC/startup_efm32gg.s(169): error: symbol `.flash_to_ram_loop' is already defined
This can be resolved.
Open the file "startup_efm32gg.s" in the IDE. Make sure its not read-only.
Change line number 169 to .flash_to_ram_loop1:
Change line number 173 to     bgt   .flash_to_ram_loop1
Save the file and retry to build again. It would get build fine no problems. You should get the messages like this.
9. Now to start the debug session go to the "Debug" Menu and then click on "Start/Stop Debug Session"
Now this should load the debug perspective and then press "Run" button to execute the code.
You should get the LED blinking now. Success ....

1. For creating the project Follow the same steps as explain earlier in case of EFM32.
Make sure that the location of the project file for STM32 is:
For our board we needed to select the microcontroller as "STM32F103RB".
Click "No" to the warning message for the default startup file inclusion.

2. Now while adding the files add the following files to the project:
ws\wsSTM32\STM32F10x\system_stm32f10x.c
ws\wsSTM32\STM32F10x\startup\TrueSTUDIO\startup_stm32f10x_md.s

Now there is a catch here while including the .s file make sure its the correct one for the STM32 microcontroller you are using. For Medium density it means STM32F10x with 32-128kb FLASH.
We would detail about these secrets of STM32 in a future post.
Next the main.c needs to be included:

#include <stm32f10x.h>
void _exit(int code)///New lib SysCall
{
while(1);
}

int main()
{
unsigned long i;

//Enable clock for the PORTA
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

//SET the Port as Output with 50MHz for PA0 PA1
GPIOA->CRL = 0x44444433;

//Turn ON PA1 - ON to give the alternating effect
GPIOA->BSRR = 1;

while(1)
{
//XOR to produce the Blinky Effect
GPIOA->ODR ^= (GPIO_ODR_ODR0+GPIO_ODR_ODR1);
//Dummy Loop
for(i=0;i<0x1FFFFF;i++);
}
}

Here we are trying to blink two LEDs on PA0 and PA1 pins.
Make sure you save the "main.c" in the location ws\wsSTM32\00_blinky\main.c

3. Configure the compiler as shown for EFM32.

4. Now to configure the 'Target 1' , open the "Options for Target 'Target 1'" window by right click on the "Target 1". Se the Output and Listing as shown earlier in EFM32 case.
Now in "CC" tab make the preprocessor definition in "Define :" to "STM32F10X_MD" . Now this is the same as the catch about the inclusion of the ".s files" as shown earlier. It depends on the Type of the chip you have. Here just enable the Check "Compile Thumb Code" and add the include path:
..\..\CMSIS;..\..\STM32F10x
Unfortunately we were unable to get the support library to work so we are using direct access in this project. We would post about how to compile the project to get a .a library out of the support libraries.
Now in the "Assembler" tab Just add the Include Path to "..\..\CMSIS;..\..\STM32F10x"
On the "Linker" tab remove the checks on "Do not use Standard .." and "Use Math..." check boxes. Make the Linker Script File as "..\..\STM32F10x_StdPeriph_Driver\TrueSTUDIO\STM3210B-EVAL\stm32_flash.ld". This again need to be selected as per the STM32 microcontroller you are using.

5. Now you need to make the setup for J-link dongle as shown earlier in case of EFM32. The J-Link commander that comes with the kit would be able to update and check the correct debug interface.However you would need to add the flash memory type.

6. Press the build button and this should build flawlessly.
7. Now start the debug session as shown earlier. And click on the Run icon.
Success with that, still we need to make the peripheral library working. We would post abut this in a future post.

The present ld file is not proper for generating the binary output. We are currently looking into this. Once the issue is resolved, we would certainly publish the update on this post.

.... Coming soon .....

Welcome to Boseji's Blog

## Welcome

Creation by Electronics Hobbyists from Bharat(India) to encourage & help people. This blog hosts the numerous innovations, discoveries and projects we provide.
We Support Open Source Hardware Definition v1.0

All works on this blog are licensed under a
Based on a work at forbharat.wordpress.com and m8051.blogspot.com.

Permissions beyond the scope of this license may be available at http://forbharat.wordpress.com/permissions/.
Thank you for all your support.