Friday, January 14, 2011

Code Sourcery g++ Lite and Programmer's Notepad for LPC1768 development

Eclipse is a fantastic IDE but some may prefer the light weight Programmer's Notepad. This post will show you how easy development for LPC1768 on a Windows box using CodeSourcery g++ Lite and Programmers notepad is.

1. Install CodeSourcery g++ Lite for ARM. Dowload the latest EABI target from CodeSourcery website.

2. Install Programmers Notepad. You can get the latest version here.

3. Open Programmers Notepad.

4. Goto Tools -> Options. Select tools in the left pane.


6. Now, click on Add. First, we'll add the Build Tool. Enter "Build" in the name field. Search where you have installed CodeSourcery and look for "cs-make.exe" as the command. Typically, cs-make is found in a place like this "C:\Program Files\CodeSourcery\Sourcery G++ Lite\bin\cs-make.exe" . In the folder field, enter "%d" and select a shortcut familiar to you. In the Save field, select "Save all files". Click on OK.


7. Repeat the procedure for Clean. Click on Add again. Enter "Clean" as the name. Select cs-make as the command again. Enter "clean" as the parameter. The other fields are entered as in the previous step. After entering everything, it should look like this.


Hit OK and OK the Options window too.

8. Now, you should have two tools, Build and Clean listed as shown below.

9. Start a new project. File -> New Project. Enter a suitable name and choose the folder where you want your work stored.


Hit OK.

10. Download the latest Quick Start Code from Cortex - m3 tutorials on google code. Extract it to your project location. As of date, this is the latest version. If you are using the USB secondary bootloader presented earlier in this blog, then use this one. The two Quick Start code bases are identical save for the fact that the one meant for the bootloader has a different flash start location. 8 KB of flash in the beginning is left aside for the bootloader and then the application code follows. The slight modification is the linker file LPC17xx.ld

11. Right Click on the project name in Programmers notepad and add the files you just extracted.



12. Hit F5 (or whatever short cut you use or Click on Tools -> Build) to compile and generate the .bin and Hex file.


You should get a message in the output window which shows successful compilation. The output message should be similar to this :
> "C:\Program Files\CodeSourcery\Sourcery G++ Lite\bin\cs-make.exe"
arm-none-eabi-gcc -W -Wall -fno-common -O2 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -g3 -c core_cm3.c -o core_cm3.o
arm-none-eabi-gcc -W -Wall -fno-common -O2 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -g3 -c startup_LPC17xx.c -o startup_LPC17xx.o
arm-none-eabi-gcc -W -Wall -fno-common -O2 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -g3 -c system_LPC17xx.c -o system_LPC17xx.o
arm-none-eabi-g++ -W -Wall -fno-common -mcpu=cortex-m3 -mthumb -O2 -c main.cpp -o main.o
arm-none-eabi-ld -Map=main.map -TLPC17xx.ld --gc-sections -nodefaultlibs -nostartfiles  core_cm3.o startup_LPC17xx.o system_LPC17xx.o  main.o -o main.elf
arm-none-eabi-size main.elf
   text       data        bss        dec        hex    filename
    808          0          0        808        328    main.elf
arm-none-eabi-objcopy -R .stack -O ihex main.elf main.hex
arm-none-eabi-objcopy -O binary -j .text -j .data main.elf main.bin

> Process Exit Code: 0
> Time Taken: 00:01


If you see the size of compiled file being declared, you know the build is successful. Otherwise, you'll see an error message indicating which file(s) has an error.

Voila ! Getting started with Cortex M3 is so very easy.

A few questions that might come up.

1. I want to start a new project. Should I write my own start up files, makefile etc.. ?

- No. The Quick Start Code Base is just for that. Each time you start a new project, add the files from the Quick Start Code Base and use that as a starting point.

2. My project has more source files like "uart.h" and "uart.c". Should I modify the makefile ?

- No. The makefile included in the Quick Start Code Base compiles every Source file the project directory. So, there is no need to touch the makefile at all for simple projects ! Just import the code base and you're off. Every assmbler source (*.S ), C Source (*.c ) and CPP source (*.cpp) in the project directory is assumed to be needed, compiled and presented to the linker. While this may not be the best method, this makes things easy to get started with. When the project gets too big, then it might be a good time to visit the makefile and organise the project properly.

UPDATE : The LPC17xx code base has been improved since the writing of this post. The newer code base links against libc, supports C++ and offers a minimal implementation of syscalls. Download the latest version here.

15 comments:

  1. Hi,

    For me, this doesn't quite work out, although I followed the instructions to the letter. Everything is OK up to the point where I press F5. There it gives me this error:

    > "C:\Program Files (x86)\CodeSourcery\Sourcery G++ Lite\bin\cs-make.exe"
    arm-none-eabi-gcc -W -Wall -fno-common -O2 --std=gnu99 -fgnu89-inline -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -g3 -c core_cm3.c -o core_cm3.o
    arm-none-eabi-gcc: CreateProcess: No such file or directory
    cs-make: *** [core_cm3.o] Error 1

    > Process Exit Code: 2
    > Time Taken: 00:00

    Whether this is Win 7 UAC fogging up PATH usage or plain old compatibility issues (running Win 7 Pro x64), it halts for no reason. Tried all kindsa things like rebooting for the additions to the ENV vars to sink in etc. But no joy.

    I say no reason, because when I open up a command window (cmd.exe) and just run cs-make.exe after navigating to the project directory, it compiles fine. And by the way, the clean command actually DOES work straight from PN (?!). Weird.

    So, thanx for the example anyways, this kind of stuff might just keep me from buying a license for Rowley Crossworks for ARM or something similar...

    Great work you're doing. I'll check in later...!

    ReplyDelete
  2. Quite strange.

    At first guess, I'd say there is a conflict between GCC versions. Perhaps you have 2 versions installed and the new GCC is attempting to find the compiler/preprocessor of the old gcc and failing.

    Check if GCC_EXEC_PREFIX environment variable is defined. If yes, try removing/renaming it and then building with programmers notepad.

    If that doesn't work, restart after renaming the GCC_EXEC_PREFIX variable to something else and then try building with PN.

    I'll look further in case you still cant get it to work.

    Glad you like my posts. More to follow.

    ReplyDelete
  3. Of course! Let me explain: Before I got myself this Blueboard-LPC1768-H, I also got me an STM32-P103 from Olimex. The horror. Took me countless hours getting that to flash an LED with OpenOCD / Eclipse via the ARM-USB-OCD JTAG. Eventually found out that the JTAG is half-broken, so I can't rely on it. STM's USART0 flash util doesn't work on Win 7, so I actually built your Wiggler and used H-JTAG to get it going. This also would not work under Win 7, but only on some legacy car-pc mini-itx thing with a parallel port that I had lying around. When I finally had that working, I decided that things should be easier, so I ordered the Blueboard. Luckily, I can just flash this new board from my development laptop via USB, so I'm in a better place now...

    The charred remains of my first bout with GCC in the form of said OpenOCD / Eclipse / Yagarto installation still lurked somewhere on my disk. So I uninstalled everything GCC related and then got a clean installation of the latest CodeSourcery running again.

    Although on my system GCC_EXEC_PREFIX still remains undefined, cs-make.exe now builds from PN. It just gives this warning, but I guess that's just GCC: "startup_LPC17xx.c:123:9: warning: taking address of expression of type 'void'", which refers to '&_stack', the initial stack pointer.

    On a different note, 'cs-make.exe clean' promptly stopped functioning because of all this. When I looked at the error closely, I saw that in the makefile, it tries to run the remove command like this:

    REMOVE = rm -f

    And running 'rm' in a command window netted me the 'command not recognized' error. So when uninstalling the original GCC installation, I also uninstalled some instance of rm.exe, I guess. In the new installation of CodeSourcery, I found it is called cs-rm.exe. Minor change to the makefile...

    REMOVE = cs-rm -f

    ...and all is now working as it should. Thanx again for getting me on the right track. I see how this is not a problem for linux users, since rm is a command native to the system.

    I'll conclude by asking if you know of any libraries that I can add to the GCC / CodeSourcery installation, that will help me get started with LPC1768 peripherals like SPI, I2C, PWM, USART, Ethernet, ADC, DAC, CAN, USB, Timers, (G)LCD's, etc. I have my own SPI routines for PIC, which I could port, and I think I can manage USART, PWM, Timers, etc. but things like Ethernet and USB are big undertakings to get right. And somebody has probably written something already...

    ReplyDelete
  4. Glad to see you've got things working.

    You'll find a number of useful application notes in the NXP website. http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768

    And for peripheral libraries, NXP dishes out a CMSIS compliant lib. http://ics.nxp.com/support/documents/microcontrollers/zip/lpc17xx.cmsis.driver.library.zip

    ReplyDelete
  5. Hello!
    So, the code is compiled but how you upload it to LPC1768? Are you using a development board? Maybe LPCXpresso?

    Thanks for the great article!

    ReplyDelete
  6. This is the board I use.

    http://shop.ngxtechnologies.com/product_info.php?cPath=21&products_id=65

    I prefer minimalistic boards with many exposed pins as my projects are rather unconventional.

    The compiled code can of course be used on any development board or even bare chip with power supply. You may use either the JTAG or UART bootloader ( with flash magic ) or secondary USB bootloader to load code to the flash memory.

    The USB bootloader is by far the easiest to use and requires the least components once the bootloader has been installed.
    Check this out.
    http://gvworks.blogspot.com/2010/10/usb-bootloader-for-blueboard.html

    LPCXpresso probably comes with a special debugging chip which can talk to LPCXpresso IDE via USB.

    ReplyDelete
  7. Hi Sagar This Is John Harris
    I made the change rm to cs-rm then 'clean' ran OK

    I got
    startup_LPC17xx.c:123:9: warning: taking address of expression of type 'void'

    but it did build a hex file

    ReplyDelete
  8. I've changed rm to cs-rm in the makefile. Strangely, both rm and cs-rm work for me.

    In the newer code base, a typedef has been used to take care of that warning.

    http://cortex-m3-tutorials.googlecode.com/files/LPC17xx_cpp_2.rar

    You can find the latest one here:

    http://code.google.com/p/cortex-m3-tutorials/downloads/list

    ReplyDelete
  9. Couple of things.
    I set up a workspace folder C:\ProgNote Work with a sub folder inside that for the demo project. In Programmer's Notepad I then did a file>>Save workspace as ProgNote Work in C:\ProgNote Work.

    Is this the right way to set up work-spaces?

    I downloaded lpc17xx_cusbSerial_example1.rar unpacked it. then used aUSB to UART bridge module from Saelig to load the supplied main.hex file to my Blueboard via the serial port. I plugged the USB cable into the Blueboard USB socket and did a reset. Windows found new hardware and I was able to point it to usbser.inf and then usbser.sys. Got a 'Your new hardware is working', and opened Tera Term found the port and set the baud rate. Then I hit a key, and LO! I had VCP comms working with my Blueboard's own USB port.

    So far so good. I copied all the non-output files into a new project folder in the Programmer's Notebook work-space, opened a new project, and did a build to get a new main.hex, that I loaded to the Blueboard via the serial port.

    I did get the same warning relating to pointers twice, but I did not note the file names

    Now Windows did not see the Blueboard USB connections. Re started my PC same problem. Went to do a Clean and Build of the project, but Clean returned an error
    process_begin: CreateProcess(NULL, rm -f core_cm3.o intenable.o serial_fifo.o startup_LPC17xx.o syscalls.o system_LPC17xx.o usbSerial.o usbcontrol.o usbhw_lpc.o usbinit.o usbstdreq.o main.o mini_cpp.o, ...) failed.
    make (e=2): The system cannot find the file specified.

    Build said nothing to do, so I faked it by adding a character to the printf test in main then did a Build. This time no warnings, and when I loaded main.hex to the Blueboard, Windows recognized the hardware and Tera Term could talk over the VCP link.

    So how do I fix Clean?

    ReplyDelete
  10. The warnings are probably about unused parameters in some functions. If that is the case, its nothing to worry about.

    Does clean work in other projects ?
    Oh and did you change rm to cs-rm in the makefile ? I've not made that change in the older projects.

    ReplyDelete
  11. Regarding work spaces, what you did seems OK. But I cant to be too sure because I use eclipse most of the times. The code complete feature is too good.

    ReplyDelete
  12. It worked on the demo program used to test Programmer's Notes. Tried lots of things then wit your prompting looked at the make file for lpc17xx_cusbSerial_example1, and yes I needed to make the cs-rm mod.

    When I did a Build after Clean I got the two warnings again and they were:

    usbstdreq.c: In function 'USBGetDescriptor':
    usbstdreq.c:116:2: warning: cast discards qualifiers from pointer target type
    usbstdreq.c: In function 'USBSetConfiguration':
    usbstdreq.c:174:3: warning: cast discards qualifiers from pointer target type

    Are they anything important?

    Thanks for your blog and for answering my questions

    ReplyDelete
  13. With explicit type casts, the warning shouldn't have popped up at all. Must have something to do with a compiler flag. Its nothing to worry about. Its meant to be that way.

    If you have a USB->UART chip ( like the FTDI chip ) to load flash, then I would recommend using that over VCOM. With VCOM, you'll have to quit and re-open teraTerm each time you load a new program and UART consumes far less resources than USB and is thus less likely to interfere with your actual project. For instance, USB uses interrupts which could screw up time critical code but UART works without interrupts.

    ReplyDelete
  14. Keep on writing, great job!
    My page: it hosting

    ReplyDelete