Little bit of thermal compound…

September 12, 2010 Leave a comment

I finally decided to do something about my overheating Thinkpad T60, about 3 yrs old. Streaming at 360p full screen caused my CPU (fixed at 1 GHz) temperature to shoot up to 93C in just 10min. By using new thermal compound, even after 30min of running the temperature is down to 60C!

The idle temperature is now 42C (before it was 58C). The GPU idle also remained below 58C (before it used to be 75-80C). I used this thermal compound Arctic Silver 5. The thing had over 4,000 reviews(!), couldn’t go wrong. Data sheet: Arctic Silver 5. Here’s a cool-down plot (cooling down after 10 minutes of streaming the same video, 360p, full screen, CPU at 1 GHz) produced just by command-line thanks to gnuplot.

Categories: General

Freaky Assembly?

March 9, 2008 2 comments

After a looong time, I was debugging some embedded C code and thought I found something freaky:

C code

for (i = 0; i < 1000000; i++);

ARM code disassembly (as generated by GNU ARM gcc)

0x0000019c <main+196>: mov r3, #0 ; 0×0
0x000001a0 <main+200>: str r3, [r11, #-16]
0x000001a4 <main+204>: b 0x1b4 <main+220>
0x000001a8 <main+208>: ldr r3, [r11, #-16]
0x000001ac <main+212>: add r3, r3, #1 ; 0×1
0x000001b0 <main+216>: str r3, [r11, #-16]
0x000001b4 <main+220>: ldr r2, [r11, #-16]
0x000001b8 <main+224>: mov r3, #999424 ; 0xf4000
0x000001bc <main+228>: add r3, r3, #572 ; 0x23c
0x000001c0 <main+232>: add r3, r3, #3 ; 0×3

0x000001c4 <main+236>: cmp r2, r3
0x000001c8 <main+240>: bls 0x1a8 <main+208>

The three highlighted lines above in affect initialize r3 with 999999 (first initializes r3 with 999424, then adds 572 to it, then adds 3 to it).

What puzzled me was why couldn’t it do that directly (mov r3, #999999)?

After some scratching my head, a faint memory of ARM assembly language dawned on me… ARM instructions are 32-bit — of which Operand 2 can be only 12-bits. In addition (from the ARM book):

- Of these 12 bits, 8-bits are for data, and 4-bits are used for ROR.
- The ROR bits are in turn multiplied by 2 before being applied on the 8-bits.

The combination of ROR and shifting by 2 greatly extends the range. The assembler automatically does it for you if it sees an operand greater than 8-bits.

This can be a great (but wicked) interview question (I’d never do that to anyone ;-)).

Do verify, here’s the math…

999424 + 572 + 3 is the closest tuples you can get to add up to 999999 using the 12-bit ROR with x2 multiplier for the RoR.

Just for verification, here are the instructions from memory:

1b8: 3D39A0E3 ; 0xE3A0393D
1bc: 8F3F83E2 ; 0xE2833F8F
1c0: 033083E2 ; 0xE2833003

To get 999424 (0x0F4000):
0x0000003D ROR 18 (0×9 x 2) = 0x000F4000 (ROR 18 = LSL 6)
As confirmed by the instruction: E3A03 93D

To get 572 (0x023C):
0x0000008F ROR 30 (0xF x 2) = 0x0000023C (ROR 30 = LSL 2)
As confirmed by the instruction: E2833 F8F

To get 3 (0×0003):
0×00000003 ROR 00 (0×0 x 2) = 0×00000003 (ROR 00 = LSL 0)
As confirmed by the instruction: E2833 003

Note: the LSL is just for convenience, it’s good only if data has all zeros padded on the left (at least enough to cover the LSL).

Categories: ARM, Coding

Slug Flash

February 12, 2008 Leave a comment

Where is the bootloader, kernel and initial ramdisk? The boot sequence is documented here.

Some notes on the slug’s flash memory organization, taken from system logs:

From dmesg:

Searching for RedBoot partition table in IXP4XX-Flash.0 at offset 0x7e0000
6 RedBoot partitions found on MTD device IXP4XX-Flash.0
Creating 6 MTD partitions on “IXP4XX-Flash.0″:
0×00000000-0×00040000 : “RedBoot”           # 256 KB
0×00040000-0×00060000 : “SysConf”            # 128 KB
0×00060000-0×00080000 : “Loader”              # 128 KB
0×00080000-0x001e0000 : “Kernel”               # 1.375 MB
0x001e0000-0x007e0000 : “Ramdisk”            # 6 MB
0x007e0000-0×00800000 : “FIS directory”     # 128 KB

From /proc/mtd:

dev:    size   erasesize  name
mtd0: 00040000 00020000 “RedBoot”
mtd1: 00020000 00020000 “SysConf”
mtd2: 00020000 00020000 “Loader”
mtd3: 00160000 00020000 “Kernel”
mtd4: 00600000 00020000 “Ramdisk”
mtd5: 00020000 00020000 “FIS directory”

From /proc/partitions:

31     0        256 mtdblock0
31     1        128 mtdblock1
31     2        128 mtdblock2
31     3       1408 mtdblock3
31     4       6144 mtdblock4
31     5        128 mtdblock5

Categories: Slug

Balancing Robot

December 25, 2007 Leave a comment

Botka, The Barely Standing Robot. This is one impressive balancing robot. Not even a bit of jitter. Midway through the video the thing takes on some solid whacks and still standing. For comparison: NXTway-G (the Lego Mindstorms NXT uses the Atmel AT91SAM7S ARM processor).

Botka probably uses some sophisticated PID control? fuzzy logic enhanced or a Kalman Filter? given it’s amazing response even in motion.

I remember doing Kalman Filters way back in my graduate courses, pretty hairy level of mathematics, but real cool nevertheless once you got a simulation working. Never thought I’d see the daylight of that again. It seems to be integral to many embedded industrial control systems (anything which requires very accurate real-time prediction and correction like image stabilization, noise reduction, maglevs, satellite navigation, cruise control,…).

Categories: General

ARM Toolchain – Crosstool

November 28, 2007 Leave a comment

Was able to get an arm-elf toolchain built and working fine, but not so much luck in building an arm-elf-linux toolchain. It cross-compiled programs without errors, but the compiled executable crapped out at runtime. So googling for answers… I came across Dan Kegel’s crosstool – a really cool GNU toolchain builder. It downloads all the correct gcc, glibc, binutils, etc. and builds your toolchain. I built two toolchains, arm-unknown-linux and arm-xscale-linux. The toolchain built with it works great.

Note:
The Ubuntu shell is not bash by default! Instead it is linked to something called dash. Just make sure you relink /bin/sh to bash instead of dash. No idea when they did this, but I found that out after encountering this maddening error, pointing to some header files during the build:

missing terminating ” character.

Using it:

Example (for kernel compilation makefile):

export ARM_TOOLCHAIN=/opt2/crosstool/arm-unknown-linux-gnu/bin
export PATH=$ARM_TOOLCHAIN:$PATH

make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnu-

Categories: ARM, Linux

ARM Toolchain

November 22, 2007 1 comment

Updated (April 26, 2008)

Here’s how I built a 64-bit GNU ARM toolchain (cross-compiler x64 to ARM). So far this has been working well for me on an LPC2148 (ARM7TDMI-S), i.e. gcc and gdb via OpenOCD JTAG.

Notes:

  1. Some builds (like binutils-2.18 and newlib-1.15) needed the setting MAKEINFO=/usr/bin/makeinfo to be passed to the make (binutils-2.17 and newlib-1.16 didn’t need this).
  2. Update: some systems (like Ubuntu 8.10) have strict checking turned on, where warnings are treated as errors. You may need to disable this the build of binutils and gdb using the –disable-werror configuration option.

Here are the steps:

environment (needed only for build):

export BINUTILS_VERSION=2.18
export GCC_VERSION=4.2.3
export NEWLIB_VERSION=1.16.0
export GDB_VERSION=6.8
.
export DIST=/opt1/gnuarm.dist    # tars will be downloaded here
export WORKDIR=/opt4/gnuarm.tmp    # tars will be unzipped and built here
export GNUARM_HOME=/opt/gnuarm   # Resulting binaries will be installed here
.
export SRC=$WORKDIR/src
export BUILD=$WORKDIR/build
export PREFIX=$GNUARM_HOME
export TARGET=arm-elf
.
md -p $DIST
md -p $SRC
md -p $BUILD
.
sudo mkdir -p $PREFIX

download:

cd $DIST
wget ftp://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2
wget ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.bz2
wget ftp://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.bz2
wget ftp://sources.redhat.com/pub/newlib/newlib-${NEWLIB_VERSION}.tar.gz
wget http://www.gnuarm.com/t-arm-elf

untar:

cd $SRC
tar jxf $DIST/binutils-${BINUTILS_VERSION}.tar.bz2
tar jxf $DIST/gcc-${GCC_VERSION}.tar.bz2
tar jxf $DIST/gdb-${GDB_VERSION}.tar.bz2
tar zxf $DIST/newlib-${NEWLIB_VERSION}.tar.gz
cp $DIST/t-arm-elf gcc-${GCC_VERSION}/gcc/config/arm/t-arm-elf

binutils:

md $BUILD/binutils
cd $BUILD/binutils
$SRC/binutils-${BINUTILS_VERSION}/configure –target=$TARGET –prefix=$PREFIX –enable-interwork –enable-multilib
make all install 2>&1 | tee make.out

gcc core:

md $BUILD/gcc
cd $BUILD/gcc
$SRC/gcc-${GCC_VERSION}/configure –target=$TARGET –prefix=$PREFIX
–enable-interwork –enable-multilib –enable-languages=”c,c++” –with-newlib –with-headers=$SRC/newlib-${NEWLIB_VERSION}/newlib/libc/include

make all-gcc install-gcc 2>&1 | tee make.out

newlib:

md $BUILD/newlib
cd $BUILD/newlib
$SRC/newlib-${NEWLIB_VERSION}/configure –target=arm-elf –prefix=$PREFIX –enable-interwork –enable-multilib

make all install 2>&1 | tee make.out

gcc (phase two):

cd $BUILD/gcc
make all install 2>&1 | tee make.out

gdb:

md $BUILD/gdb
cd $BUILD/gdb
$SRC/gdb-${GDB_VERSION}/configure –target=$TARGET –prefix=$PREFIX –enable-interwork –enable-multilib

make all install 2>&1 | tee make.out

post-setup:

echo ‘export GNUARM_HOME=/opt/gnuarm’ >> ~/.profile
echo ‘export PATH=$GNUARM_HOME/bin:$PATH’ >> ~/.profile

The scripts can be downloaded from here.

Categories: ARM, Linux

ARM boards

September 8, 2007 Leave a comment

Just got back from a trip to Chicago – Oak Park, a lovely renovated “gentrified” neighborhood, west of Chicago. Just spent the night researching a good ARM board to buy. Narrowed it down to these (all these boards have USB and SD card reader):

ARM7TDMI-S boards:

  • Olimex SAM7-P256 (SAM7-Pxxx Rev. E) – Atmel AT91SAM7S256, 256K Flash, 64K RAM, 60MHz, 18MHz crystal. $87.
  • Olimex LPC-P2148 – NXP LPC2148, 512K Flash, 32K+8K RAM, 60MHz, 12MHz crystal. $77.

.
ARM7TDMI-S boards w/Ethernet:

  • Olimex SAM7-LA2 – Atmel AT91SAM7A2, 1MB Flash, 4MB SRAM, 30MHz, 6MHz crystal. $140.
  • Olimex SAM7-EX256 – Atmel AT91SAM7X256, 256K Flash, 64K RAM, 55MHz, 18MHz crystal. This board is loaded with stuff. $120.

.
ARM920T boards w/MMU (for running embedded Linux):

  • Olimex CS-E9302 – Cirrus Logic EP9302, 16MB Flash, 32MB SDRAM, 200MHz. Cirrus Logic has a very good linux forum. $180.
  • Olimex SAM9-L9260 – Atmel AT91SAM9260, 512MB NAND Flash, 64MB SDRAM, 180MHz, 18MHz crystal. $217.
  • … or just get another Slug – XScale IXP420 (ARMv5TE), 8MB Flash, 32MB SDRAM, 266MHz. $80.
Categories: ARM

Arduino GPS

August 27, 2007 6 comments

Just to get my hands dirty and wrap it up with the AVR’s, I created a GPS data logger – using an Arduino board, GPS receiver chip, 4×20 LCD, and a uALFAT microSD board.

A good document on NMEA commands and data formats used by GPS chips is here. Regarding the GPS unit, it was SiRF vs Trimble, and I went for SiRF, the SiRF III (the EM-406A by USGlobalSat). I picked it over the Trimble Lassen IQ and the Parallax.

Of course you can buy a GPS data logger board with LCD for about $200. But the whole point is that it’d be a learning exercise, an interesting one :-).

I decided to write it in raw C (UART driver, LCD driver, flash data logger,…) instead of Arduino’s Wiring language. This amounts to pretty much reading most of the 300 page data sheet for the MCU, giving you a thorough understanding of all aspects of the MCU – GPIO, clocks, counters, interrupts, UART, SPI, I2C,… all related considerations like registers, masks, timings, memory organization,…

(photo updated, 12/2007).

Categories: AVR

Arduino LCD

August 25, 2007 Leave a comment

My first step, in my foray into embedded systems: interfaced a 4×20 character LCD panel to the Arduino. Details on interfacing any Hitachi HD44780 based LCD panel can be found here.

Went for the default parallel LCD’s. They’re cheap, about $15 for a 20×4 panel on eBay (HD44780). The serial ones cost about 2-3 more. These LCD panels allow you to use 4 data lines (with some bit-banging) instead of 8. Get one that is STN and transflective (vs reflective and transmissive), known for better contrast and brighter.

Check out also LCDProc.

Categories: AVR

The Arduino

August 24, 2007 Leave a comment

Just got it today :-). The Arduino is a great learning platform for anyone interested in the embedded world. The entire platform is open (hardware schematics, bootloader, lots of examples, etc.).

It comes with a nice language that abstracts out lot of the bit-level stuff. But for learning purposes I’d recommend just using straight C – i.e. to get right down to the bare metal to get to know the AVR. Ubuntu has a nice ready-made GNU C toolchain for the AVR which works quiet well. There is also an Eclipse plugin. You’ll probably end up reading two-thirds of the 350 page ATmega168 specs… but very worthwhile. Once you’ve done one, you’re all set to handle any 8-bit MCU. I found Atmel’s AVR docs are very well done, complete with assembly language and bit-level C-language code snippets.

Also, check this site out: Atmel AVR Application Notes. Tons of stuff. You don’t really need to buy any embedded systems books. The stuff here plus the Atmel AVR 8-bit Instruction Set set document should be all that you need.

Categories: AVR
Follow

Get every new post delivered to your Inbox.