Low level embedded example programs for the pic32 (UBW32 and CUI32 boards)
Fetching latest commit…
Cannot retrieve the latest commit at this time
You may see that I have a lot of other ARM based projects at github, I do have a lot of low level ARM experience, as well as a fair amount with other platforms but never got into MIPS. Have wanted to but needed a starting place. So this year I bought a couple of boards from Sparkfun. The UBW32 http://www.sparkfun.com/products/8971 I bought is now retired and replaced with a newer one. I dont know if that is good or bad as I found PIC32MX4 tools after buying this CUI32 board http://www.sparkfun.com/products/9645 Specifically this tool: http://members.dslextreme.com/users/paintyourdragon/uc/ubw32/ubw32.tar.bz2 Linked to from this page: http://www.paintyourdragon.com/uc/ubw32/index.html Not without problems of course. libhid-dev is apparently not supported by Ubuntu, or at least 10.10. 10.04 does have it and I was able to get the sources from debian/ubuntu for 10.04 and build and install it on 10.10. Have not tried the newer Ubuntu versions.... Building the Microchip pic32 compiler from sources was a bust, more work than I was interested in when the current llvm and stock gcc are so easy to come by. I am not interested in canned libraries, and $900 is way out of the hobby budget for such tools. I did find that the Microchip c32 compiler is available in pre-built 32 and 64 bit Linux versions. You have to pay to get -O2 to work. Codesourcery is now completely Mentor Graphics, so we will see what happens with that . Hopefully they wont make the typical mistakes that cause the product line and purchase of the company to be a bust for the existing user base. So I still have a lot to learn about MIPS and the instruction set, I was able to get enough assembler going to boot and run some sample programs. These are NOT StickOS nor UBW32 programs. These are C and/or assembly programs that replace StickOS or UBW32. You can always put that firmware back on the board, so long as you dont mess up the lower area of flash. The xD000000 - xD005000 range of flash at a minimum is preserved for the bootloader, between xD005000 and xD006000 is for exception vectors or something like that and the user programs can/should start at 0xxD006000. Mess up the flash below 0xxD005000 and maybe you brick the board, maybe not, you have been warned. I assume it may be crt0.o from the Mirochip tools, who knows but the UB32 firmware .hex file used the physical addresses in the 0x1D006000+ range, but the first few instructions switched to a 0x9D006000+ range (thus the 0xxD006000 nomenclature above), so I made my linker script cause the same to occur, executes as if it was 0x9Dxxxxxx but build a .hex file for 0x1Dxxxxxx. Using 0x80000000 for ram goes along with the 0x9Dxxx flash and it appears to work just fine so far. Microchip is using little endian so -EL is used on all the gnu command lines. This is critical if you leave that off and get big endian .hex files, well it wont work... The ubw32 flash loader program did not like a type 05 entries in the .hex file, probably a simple change in that program, which is not mine, so I wrote a quick program that takes the binutils created .hex file and creates another .hex file with the offending line removed. The ihex tool takes something.hex in and creates something.hex.hex. The .hex.hex file is the one you want to feed the ubw32 loader. Codesourcery which I think is completely switched over to Mentor Graphics now, is currently THE place for ARM based gcc tools, so I went there to get MIPS based tools. And that is what was used for gcc and binutils with these examples. I normally build the current llvm release (2.9 at the moment) as well as a copy of the cutting edge trunk from the svn repo. They take a while to build, if you have a multi core processor using make -j num makes a huge difference. Their make file system is not perfect so unfortunately you have to make clean if there have been changes. LLVM is great as a cross compiler, you get all the targets in one tool, unlike others where you have to compile a new toolchain for each target. Other than 32 vs 64 bit ints you can do most of your work target independent and then the last step go from bitcode to target specific assembler. I use binutils assembler and linker to merge it with startup code and other hand written assembler and take it to a final binary. I had some relocation problems both with gcc and llvm using -G0 on the gnu side and -relocation-model=static or -relocation-model=dynamic-no-pic with LLVM (llc). As of this writing for the blinker02 example both static and dynamic-no-pic produced the exact same output. Examine the makefile for more on how to use llvm for cross compiling, at least one way to do it. I find it best to build all the C code, then use llvm-link to link into a single bitcode file. Then optimize at that point where the optimizer has the most amount of meat to crunch on. Then turn it into a single .s file to feed binutils. As of this writing there are only a couple of examples, an assembly only example using a counter based delay, blinker01. Blinker02 is a baseline C based example. Future examples will use more peripherals and get progressively more complicated. No desire to clone the Microchip libraries or anything like that, take the programmers reference, schematics and figure things out. In case you want to roll your own tools that you can compile these examples with here are some notes. Binutils is used by both gcc and llvm in these examples, gives you an assembler and linker which is all you need if assembly language is what you are after. If you run linux/Ubuntu you probably already have a number of the development tools as you are probably already a programmer/developer. Things like build-essential, automake, etc. you will need bison and flex which you may not already have, and for the more recent gcc versions libgmp3-dev, libmpfr-dev and libmpc-dev (apt-get install all of these items BTW). So binutils, at the time of this writing the most current is: wget http://ftp.gnu.org/gnu/binutils/binutils-2.21.1a.tar.bz2 Note 2.22 fails to build for mips > tar xjvf binutils-2.21.1a.tar.bz2 > cd binutils-2.21.1 > mkdir build > cd build > ../configure --target=mips-none-elf --prefix=/opt/mips-none-elf this takes a bit, not long > make this takes longer depending on your machine, if you have multiple cores then put the number of cores: > make -j 4 this still takes a while but much faster in parallel. you may figure out on the way that you need to install something else and have to try a few times. using a directory (like build, it doesnt have to be a subdir of the binutils sources) to configure/build in you can easily just delete that directory instead of the whole binutils tree to start over fresh. when you get a clean build then > make install that might need a sudo on it... Add this to your path so gas and ld are available for the gcc build. > PATH=/opt/mips-none-elf/bin:$PATH Now for gcc if you are interested >wget http://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-core-4.6.1.tar.gz >tar xzvf gcc-core-4.6.1.tar.gz > cd gcc-4.6.1 > mkdir build > cd build >../configure --target=mips-none-elf --prefix=/opt/mips-none-elf \ >--disable-nls --enable-languages=c --disable-libssp --disable-libmudflap \ >--disable-libquadmath --without-headers --with-newlib takes a while, not long >make takes a really long time, multi core or fast computer makes a huge difference, put the number of cores in there >make -j 4 same deal, if you didnt get libmpfr or libmpc for example you will have to keep trying. not long ago a single apt-get install libmpfr-dev would give you the things you needed for building gcc, then it was that you had to do both libmpfr and libgmp3, now you have to manually do all three libmpfr-dev, libgmp3-dev and libmpc-dev. to get a gcc 4.6 built. of course I am running an older Ubuntu 10.04 LTS. and 10.10 on some machines. when gcc finishes building successfully >make install I dont know if that needs a sudo or not, it might. Now anytime you want to use it PATH=/opt/mips-none-elf/bin:$PATH tools are mips-none-elf-gcc, mips-none-elf-as, etc. When using with my Makefiles either: > make MIPSGNU=mips-none-elf Or change the line in the makefile to use the alternate prefix. It is possible the tools will build for you with the same prefix as Codesourcery used. mips-sde-elf. Building the llvm 29 release >svn co http://llvm.org/svn/llvm-project/llvm/branches/release_29/ llvm29 >cd llvm29 >cd tools >svn co http://llvm.org/svn/llvm-project/cfe/branches/release_29/ clang >cd .. >./configure --enable-optimized --disable-doxygen --prefix=/llvm29 >make takes forever, -j num helps greatly. can change it from go get lunch amount of time to go get a coke from the coke machine amount of time. >make install Building the trunk is as simple: >svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm >cd llvm >cd tools >svn co http://llvm.org/svn/llvm-project/cfe/trunk clang >cd .. >./configure --enable-optimized --disable-doxygen --prefix=/llvm >make >make install For both from your toplevel llvm or llvm29 source directory > make update will pull in svn updates for both llvm trunk and clang trunk. The cutting edge development will have daily activity and there are definitely times where some checkins do not work, sometimes you are doing a update while pushes are going in, so I normally do two or three make updates in a row to wait for no activity. Definitely, unfortunately do a make clean to clean out intermediate files, unfortunately the make system doesnt catch everything, the make, make install again. If it fails to build, try some more make updates or wait for a while for whomever to find the build bug and fix it and check in a patch. A/The reason for having the trunk is that when you find and want to file a bug you may find that a number of them have been found and fixed and by running the prior release, it is stable but does not have all bugfixes backported, if any. The above (gcc) does not necessarily give you a C library, or even gcc library for that matter, I have no use for those in an embedded environment so it doesnt bother me. It might bother you, so more work may be required. Likewise I dont use C++ so I use the core gcc tarball not the full gcc tarball. With gcc in general you are likely to have floating point problems, with this chip not having an fpu (well I dont see it mentioned in the docs) a soft fpu with gcc is that much more painful. Here again I have no use for floating point in embedded work so these tools usually work great for me. Apple has put a lot of resources into llvm development putting the results back into the open source world. The last couple bugs I filed were handled by @apple.com email addresses during weekday work hours. I think llvm is used for iphone app development so the core compile and at least arm backend is maturing nicely.