Building Energy Micro EFM32 binaries from OS X

I’m currently evaluating the EFM32 Gecko MCU from Energy Micro for a project. I’m using the Developer’s Kit with the EFM32G290F128 MCU.

I mainly work in OS X and Linux and don’t much like having to boot up the Windows Virtual Machine to develop and debug firmwares. The tools mostly suck (I <3 the CLI) or are very expensive (often both). So I wanted a way to use open source tools like gcc, gdb and openocd.

First step was getting a binary to compile.

1. visit https://github.com/jsnyder/arm-eabi-toolchain and install as directed, make sure you run the make install-bin-extras after all the make-ing and make install-ing.

2. try a sample EFM32G firmware like the one included in the DVK_BSP_1.6.1.zip copy the ‘blink’ one to some directory of your choosing for this project.

3. Download the EFM CMSIS Library and copy it to the parent directory of the project directory you chose in step 2. Do the same with the ‘bsp’ and ‘efm32lib’ directories from the DVK_BSP.

4. Edit the Makefile from the ‘codesourcery’ part of the example. Mine looks like this:

####################################################################
# Makefile #
####################################################################

.SUFFIXES: # ignore builtin rules
.PHONY: all debug release clean

####################################################################
# Definitions #
####################################################################

DEVICE = EFM32G290F128
PROJECTNAME = blinkG290

OBJ_DIR = build
EXE_DIR = exe
LST_DIR = lst

####################################################################
# Definitions of toolchain. #
# You might need to do changes to match your system setup #
####################################################################

# Change path to CodeSourcery tools according to your system configuration
WINDOWSCS = CodeSourcery/Sourcery G++ Lite
LINUXCS = /Users/nemik/code/arm-cs-tools
GCCVERSION = $(shell $(CC) -dumpversion)

ifeq ($(ComSpec),)
ifeq ($(COMSPEC),)
# Assume we are making on a linux platform
TOOLDIR = $(LINUXCS)
RM = rm -rf
else
TOOLDIR = $(PROGRAMFILES)/$(WINDOWSCS)
RM = "$(TOOLDIR)/bin/cs-rm" -rf
endif
else
TOOLDIR = $(ProgramFiles)/$(WINDOWSCS)
RM = "$(TOOLDIR)/bin/cs-rm" -rf
endif

CC = "$(TOOLDIR)/bin/arm-none-eabi-gcc"
LD = "$(TOOLDIR)/bin/arm-none-eabi-ld"
AR = "$(TOOLDIR)/bin/arm-none-eabi-ar"
OBJCOPY = "$(TOOLDIR)/bin/arm-none-eabi-objcopy"
DUMP = "$(TOOLDIR)/bin/arm-none-eabi-objdump" --disassemble

####################################################################
# Flags #
####################################################################

# -MMD : Don't generate dependencies on system header files.
# -MP : Add phony targets, useful when a h-file is removed from a project.
# -MF : Specify a file to write the dependencies to.
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
# Add -Wa,-ahlms=$(LST_DIR)/$(@F:.o=.lst) to CFLAGS to produce assembly list files
CFLAGS += -D$(DEVICE) -mcpu=cortex-m3 -mthumb -Wall $(DEPFLAGS)
ASMFLAGS += -Ttext 0x0
LDFLAGS += -Xlinker -Map=$(LST_DIR)/$(PROJECTNAME).map -mcpu=cortex-m3 -mthumb -T../CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/startup/cs3/efm32g.ld -L"$(TOOLDIR)/arm-none-eabi/lib/thumb2" \
-L"$(TOOLDIR)/lib/gcc/arm-none-eabi/$(GCCVERSION)/thumb2"
LIBS += -lc -lcs3 -lcs3unhosted

INCLUDEPATHS += \
-I.. \
-I../CMSIS/CM3/CoreSupport \
-I../CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32 \
-I../efm32lib/inc \
-I../bsp \
-I../drivers

####################################################################
# Files #
####################################################################

C_SRC += \
../CMSIS/CM3/CoreSupport/core_cm3.c \
../CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/system_efm32.c \
../bsp/dvk.c \
../bsp/dvk_boardcontrol.c \
../bsp/dvk_ebi.c \
../bsp/dvk_spi.c \
../efm32lib/src/efm32_assert.c \
../efm32lib/src/efm32_cmu.c \
../efm32lib/src/efm32_gpio.c \
../efm32lib/src/efm32_emu.c \
../efm32lib/src/efm32_ebi.c \
../efm32lib/src/efm32_system.c \
../efm32lib/src/efm32_usart.c \
blink.c

S_SRC += \
../CMSIS/CM3/DeviceSupport/EnergyMicro/EFM32/startup/cs3/startup_efm32.s

####################################################################
# Rules #
####################################################################

C_FILES = $(notdir $(C_SRC) )
S_FILES = $(notdir $(S_SRC) )
#make list of source paths, sort also removes duplicates
C_PATHS = $(sort $(dir $(C_SRC) ) )
S_PATHS = $(sort $(dir $(S_SRC) ) )

C_OBJS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.o))
S_OBJS = $(addprefix $(OBJ_DIR)/, $(S_FILES:.s=.o))
C_DEPS = $(addprefix $(OBJ_DIR)/, $(C_FILES:.c=.d))

vpath %.c $(C_PATHS)
vpath %.s $(S_PATHS)

# Default build is debug build
all: debug

debug: CFLAGS += -DDEBUG -g3 -O0
debug: $(OBJ_DIR) $(LST_DIR) $(EXE_DIR) $(EXE_DIR)/$(PROJECTNAME).bin

release: CFLAGS += -DNDEBUG -O3
release: $(OBJ_DIR) $(LST_DIR) $(EXE_DIR) $(EXE_DIR)/$(PROJECTNAME).bin

# Create directories
$(OBJ_DIR):
mkdir $(OBJ_DIR)
@echo "Created build directory."

$(EXE_DIR):
mkdir $(EXE_DIR)
@echo "Created executable directory."

$(LST_DIR):
mkdir $(LST_DIR)
@echo "Created list directory."

# Create objects from C SRC files
$(OBJ_DIR)/%.o: %.c
@echo "Building file: $<" $(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $< # Assemble .s files $(OBJ_DIR)/%.o: %.s @echo "Assembling $<" $(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $< # Link $(EXE_DIR)/$(PROJECTNAME).out: $(C_OBJS) $(S_OBJS) @echo "Linking target: $@" $(CC) $(LDFLAGS) $(C_OBJS) $(S_OBJS) $(LIBS) -o $(EXE_DIR)/$(PROJECTNAME).out # Create binary file $(EXE_DIR)/$(PROJECTNAME).bin: $(EXE_DIR)/$(PROJECTNAME).out @echo "Creating binary file" $(OBJCOPY) -O binary $(EXE_DIR)/$(PROJECTNAME).out $(EXE_DIR)/$(PROJECTNAME).bin # Uncomment next line to produce assembly listing of entire program # $(DUMP) $(EXE_DIR)/$(PROJECTNAME).out>$(EXE_DIR)/$(PROJECTNAME).lst

clean:
$(RM) $(OBJ_DIR) $(LST_DIR) $(EXE_DIR)

# include auto-generated dependency files (explicit rules)
ifneq (clean,$(findstring clean, $(MAKECMDGOALS)))
-include $(C_DEPS)
endif

5. Run the `make` command

6. You should have a ‘blinkG290.bin’ in the ‘exe’ directory. Seems a bit nuts that my bin is 14kb though…seems quite high for a blinking program; could that be CodeSourcery’s libcs3 adding so much?

7. Now you can use the energyAware Commander Windows program to load the firmware onto the board :/. I was not able to get openOCD working with the on-board JLink module and SWD. I’m now in the process of trying to get my BusPirate board to act as a JTAG interface for using the 20-pin adapter of the EFM32 Development Kit and hoping it does JTAG…
If not, one could also write a Python script with some XMODEM-CRC library to try to upload code to the built-in bootloader on the EFM32 chips using some FTDI USB-serial cable with something like the DST pin being used to pulse RESET and some other un-used serial pin to hold down DBG_SWCLK. But even then some way to debug is needed…really hoping JTAG can somehow work.

Has anyone tried to do something similar on Linux or OS X without the official Segger JLink software? They don’t produce OS X binaries and it’s closed source. Or has anyone gotten an EFM32 DK with its built-in JLink debugger to work with openOCD? Any suggestions would be awesome.

fuck you AT&T

64 bytes from 74.125.95.147: icmp_seq=2 ttl=51 time=39923.652 ms
64 bytes from 74.125.95.147: icmp_seq=3 ttl=51 time=38950.253 ms
64 bytes from 74.125.95.147: icmp_seq=4 ttl=53 time=38890.900 ms
64 bytes from 74.125.95.147: icmp_seq=5 ttl=51 time=37891.290 ms
64 bytes from 74.125.95.147: icmp_seq=6 ttl=53 time=36901.448 ms
64 bytes from 74.125.95.147: icmp_seq=7 ttl=51 time=35911.426 ms
64 bytes from 74.125.95.147: icmp_seq=8 ttl=51 time=34912.931 ms
64 bytes from 74.125.95.147: icmp_seq=9 ttl=53 time=33915.923 ms
64 bytes from 74.125.95.147: icmp_seq=10 ttl=51 time=32922.047 ms
64 bytes from 74.125.95.147: icmp_seq=11 ttl=51 time=31926.996 ms
64 bytes from 74.125.95.147: icmp_seq=12 ttl=53 time=31916.773 ms
64 bytes from 74.125.95.147: icmp_seq=13 ttl=53 time=30920.804 ms
64 bytes from 74.125.95.147: icmp_seq=14 ttl=51 time=30118.295 ms
64 bytes from 74.125.95.147: icmp_seq=15 ttl=51 time=30039.361 ms
64 bytes from 74.125.95.147: icmp_seq=16 ttl=53 time=29267.459 ms
64 bytes from 74.125.95.147: icmp_seq=17 ttl=51 time=30857.822 ms
64 bytes from 74.125.95.147: icmp_seq=18 ttl=53 time=31573.629 ms
64 bytes from 74.125.95.147: icmp_seq=19 ttl=53 time=30905.686 ms
64 bytes from 74.125.95.147: icmp_seq=20 ttl=53 time=30596.515 ms
64 bytes from 74.125.95.147: icmp_seq=21 ttl=51 time=29758.053 ms
64 bytes from 74.125.95.147: icmp_seq=22 ttl=51 time=28931.541 ms
64 bytes from 74.125.95.147: icmp_seq=23 ttl=53 time=28411.830 ms
64 bytes from 74.125.95.147: icmp_seq=24 ttl=51 time=27434.502 ms
64 bytes from 74.125.95.147: icmp_seq=25 ttl=51 time=26889.280 ms
64 bytes from 74.125.95.147: icmp_seq=26 ttl=51 time=25891.407 ms
64 bytes from 74.125.95.147: icmp_seq=27 ttl=53 time=26480.745 ms
64 bytes from 74.125.95.147: icmp_seq=28 ttl=51 time=26852.563 ms
64 bytes from 74.125.95.147: icmp_seq=29 ttl=51 time=27648.067 ms
64 bytes from 74.125.95.147: icmp_seq=30 ttl=53 time=26745.366 ms
64 bytes from 74.125.95.147: icmp_seq=31 ttl=53 time=26883.673 ms
^C
— www.l.google.com ping statistics —
60 packets transmitted, 31 packets received, 48.3% packet loss
round-trip min/avg/max/stddev = 25891.407/31589.761/39923.652/4217.973 ms

DSL is a heaping pile of shit.

cool bots

From my home network logs:

92.240.68.153 - - [05/Dec/2010:23:07:06 -0600] "GET http://www.colostate.edu/Dept/CoopExt/4dmg/images/stones1.jpg HTTP/1.1" 404 501 "-" "webcollage/1.135a"
92.243.78.170 - - [05/Dec/2010:23:50:54 -0600] "GET /w00tw00t.at.blackhats.romanian.anti-sec:) HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:54 -0600] "GET /scripts/setup.php HTTP/1.1" 404 472 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:54 -0600] "GET /admin/scripts/setup.php HTTP/1.1" 404 477 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:55 -0600] "GET /admin/pma/scripts/setup.php HTTP/1.1" 404 480 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:55 -0600] "GET /admin/phpmyadmin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:55 -0600] "GET /db/scripts/setup.php HTTP/1.1" 404 474 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:56 -0600] "GET /dbadmin/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:56 -0600] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:56 -0600] "GET /mysql/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:57 -0600] "GET /mysqladmin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:57 -0600] "GET /typo3/phpmyadmin/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:57 -0600] "GET /phpadmin/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:58 -0600] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 480 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:58 -0600] "GET /phpmyadmin/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:58 -0600] "GET /phpmyadmin1/scripts/setup.php HTTP/1.1" 404 480 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:59 -0600] "GET /phpmyadmin2/scripts/setup.php HTTP/1.1" 404 480 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:59 -0600] "GET /pma/scripts/setup.php HTTP/1.1" 404 476 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:59 -0600] "GET /web/phpMyAdmin/scripts/setup.php HTTP/1.1" 404 483 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:50:59 -0600] "GET /xampp/phpmyadmin/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:00 -0600] "GET /web/scripts/setup.php HTTP/1.1" 404 476 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:00 -0600] "GET /php-my-admin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:00 -0600] "GET /websql/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:01 -0600] "GET /phpmyadmin/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:01 -0600] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 480 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:01 -0600] "GET /phpMyAdmin-2/scripts/setup.php HTTP/1.1" 404 482 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:02 -0600] "GET /php-my-admin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:02 -0600] "GET /phpMyAdmin-2.2.3/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:02 -0600] "GET /phpMyAdmin-2.2.6/scripts/setup.php HTTP/1.1" 404 483 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:03 -0600] "GET /phpMyAdmin-2.5.1/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:03 -0600] "GET /phpMyAdmin-2.5.4/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:03 -0600] "GET /phpMyAdmin-2.5.5-rc1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:04 -0600] "GET /phpMyAdmin-2.5.5-rc2/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:04 -0600] "GET /phpMyAdmin-2.5.5/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:04 -0600] "GET /phpMyAdmin-2.5.5-pl1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:04 -0600] "GET /phpMyAdmin-2.5.6-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:05 -0600] "GET /phpMyAdmin-2.5.6-rc2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:05 -0600] "GET /phpMyAdmin-2.5.6/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:05 -0600] "GET /phpMyAdmin-2.5.7/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:06 -0600] "GET /phpMyAdmin-2.5.7-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:06 -0600] "GET /phpMyAdmin-2.6.0-alpha/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:06 -0600] "GET /phpMyAdmin-2.6.0-alpha2/scripts/setup.php HTTP/1.1" 404 491 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:07 -0600] "GET /phpMyAdmin-2.6.0-beta1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:07 -0600] "GET /phpMyAdmin-2.6.0-beta2/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:07 -0600] "GET /phpMyAdmin-2.6.0-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:08 -0600] "GET /phpMyAdmin-2.6.0-rc2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:08 -0600] "GET /phpMyAdmin-2.6.0-rc3/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:08 -0600] "GET /phpMyAdmin-2.6.0/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:08 -0600] "GET /phpMyAdmin-2.6.0-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:09 -0600] "GET /phpMyAdmin-2.6.0-pl2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:09 -0600] "GET /phpMyAdmin-2.6.0-pl3/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:09 -0600] "GET /phpMyAdmin-2.6.1-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:10 -0600] "GET /phpMyAdmin-2.6.1-rc2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:10 -0600] "GET /phpMyAdmin-2.6.1/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:10 -0600] "GET /phpMyAdmin-2.6.1-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:11 -0600] "GET /phpMyAdmin-2.6.1-pl2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:11 -0600] "GET /phpMyAdmin-2.6.1-pl3/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:11 -0600] "GET /phpMyAdmin-2.6.2-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:12 -0600] "GET /phpMyAdmin-2.6.2-beta1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:12 -0600] "GET /phpMyAdmin-2.6.2-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:12 -0600] "GET /phpMyAdmin-2.6.2/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:13 -0600] "GET /phpMyAdmin-2.6.2-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:13 -0600] "GET /phpMyAdmin-2.6.3/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:13 -0600] "GET /phpMyAdmin-2.6.3-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:13 -0600] "GET /phpMyAdmin-2.6.3/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:14 -0600] "GET /phpMyAdmin-2.6.3-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:14 -0600] "GET /phpMyAdmin-2.6.4-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:14 -0600] "GET /phpMyAdmin-2.6.4-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:15 -0600] "GET /phpMyAdmin-2.6.4-pl2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:15 -0600] "GET /phpMyAdmin-2.6.4-pl3/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:15 -0600] "GET /phpMyAdmin-2.6.4-pl4/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:16 -0600] "GET /phpMyAdmin-2.6.4/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:16 -0600] "GET /phpMyAdmin-2.7.0-beta1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:16 -0600] "GET /phpMyAdmin-2.7.0-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:17 -0600] "GET /phpMyAdmin-2.7.0-pl1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:17 -0600] "GET /phpMyAdmin-2.7.0-pl2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:17 -0600] "GET /phpMyAdmin-2.7.0/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:18 -0600] "GET /phpMyAdmin-2.8.0-beta1/scripts/setup.php HTTP/1.1" 404 490 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:18 -0600] "GET /phpMyAdmin-2.8.0-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:18 -0600] "GET /phpMyAdmin-2.8.0-rc2/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:18 -0600] "GET /phpMyAdmin-2.8.0/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:19 -0600] "GET /phpMyAdmin-2.8.0.1/scripts/setup.php HTTP/1.1" 404 486 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:19 -0600] "GET /phpMyAdmin-2.8.0.2/scripts/setup.php HTTP/1.1" 404 486 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:19 -0600] "GET /phpMyAdmin-2.8.0.3/scripts/setup.php HTTP/1.1" 404 486 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:20 -0600] "GET /phpMyAdmin-2.8.0.4/scripts/setup.php HTTP/1.1" 404 486 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:20 -0600] "GET /phpMyAdmin-2.8.1-rc1/scripts/setup.php HTTP/1.1" 404 489 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:20 -0600] "GET /phpMyAdmin-2.8.1/scripts/setup.php HTTP/1.1" 404 484 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:21 -0600] "GET /phpMyAdmin-2.8.2/scripts/setup.php HTTP/1.1" 404 485 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:21 -0600] "GET /sqlmanager/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:21 -0600] "GET /mysqlmanager/scripts/setup.php HTTP/1.1" 404 482 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:22 -0600] "GET /p/m/a/scripts/setup.php HTTP/1.1" 404 477 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:22 -0600] "GET /PMA2005/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:22 -0600] "GET /pma2005/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:22 -0600] "GET /phpmanager/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:23 -0600] "GET /php-myadmin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:23 -0600] "GET /phpmy-admin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:23 -0600] "GET /webadmin/scripts/setup.php HTTP/1.1" 404 479 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:24 -0600] "GET /sqlweb/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:24 -0600] "GET /websql/scripts/setup.php HTTP/1.1" 404 478 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:24 -0600] "GET /webdb/scripts/setup.php HTTP/1.1" 404 477 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:25 -0600] "GET /mysqladmin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"
92.243.78.170 - - [05/Dec/2010:23:51:25 -0600] "GET /mysql-admin/scripts/setup.php HTTP/1.1" 404 481 "-" "ZmEu"

Arduinoponics with OpenWRT

I updated my GitHub repo: http://github.com/nemik/arduinoponics with code I wrote for the OpenWRT firmware (version 8.09.1). It provides an AJAXy-updating page to OpenWRT’s Luci web-interface which displays the analog pin values from the Arduino which the Arduinoponics sketch runs on.

Here is a screenshot, notice the extra ‘Sensors’ link on the top right to access the info, the page does not require login
Arduinoponics OpenWRT screenshot

Fixing broken JFFS2 partition

Lesson #1 of embedded development: don’t write all your code to your device and not backup/check-in. I did just that when writing some code for the hydroponics monitoring setup on my Fon2100 router running OpenWRT. After trying to opkg install ntpclient and getting a segfault and NTP not working, I restarted  the network on it which restarted the router. For whatever reason, the router choked and each restart went into failsafe mode. When I telnet’d into it, dmesg told me the jffs2 partition had trouble mounting with an error in jffs2_link_node_ref.

I had written a bunch of Lua code to read the serial communications coming from the ATMega168 microcontroller (it was sending its analog input values) and store it into files in /tmp which were then read by some more Lua code in the (awesome) LuCI framework to make those sensors all cool and AJAXy on the router’s web-admin menu. This worked great until the NTP attempt. So I wanted all this code back. So in case anyone is as foolish as I was to lose their code in the router, here are the steps I took to recover it. David Woodhouse (dwmw2) and dedekind at #mtd on irc.ipv6.oftc.net were extremely helpful with all this and pointed me in all the right directions.

  1. backup the jffs2 image from the router using dd. mine was coming up in failsafe mode so i had to telnet into 192.168.1.1 and then run command `dd if=/dev/mtdblock2 | gzip -c | ssh nemik@pillbox ‘dd of=/tmp/mtd2.gz’ bs=2048` but make sure you do the right mtdblock2 device. do `cat /proc/mtd` and choose the one that is for “rootfs_data”. pillbox is a Linux box on my network I transferred this all to.
  2. `gunzip /tmp/mtd2.gz` on the Linux box and i got my 5.5MB partition.
  3. `sudo mknod /dev/mtd0 c 90 0`
  4. `sudo modprobe mtdblock`
  5. `sudo dd if=/tmp/mtd2 of=/dev/mtd0 bs=2048`
  6. `sudo mount -t jffs2 mtd0 /tmp/1/` THIS DIDN’T WORK! (right away). The Fon router and openWRT are big-endian and I was trying to mount this on a little-endian x86 box. I needed to recompile the jffs2 kernel module to be big-endian. David Woodhouse (creator of JFFS2) writes how here: [http://www.infradead.org/pipermail/linux-mtd/2007-May/018227.html] I needed to get the kernel source and recompile the jffs2 module
  7. get the kernel source `apt-get source linux-image-$(uname -r)`
  8. go into the source and do `make prepare_modules`
  9. copy /usr/src/linux-headers-2.6.27-14-generic/Module.symvers to the source. this will be different for you, but the Module.symvers is important otherwise the module won’t load properly
  10. Change the native_endian #define in fs/jffs2/nodelist.h to be little_endian as David writes in the infraread link on step 7.
  11. do `make CONFIG_MODVERSIONS=y M=fs/jffs2`
  12. if it compiled correctly, you then have a jffs2.ko module. load it via `sudo insmod /home/nemik/code/jffs2/linux-2.6.27/fs/jffs2/jffs2.ko`
  13. now try `sudo mount -t jffs2 /dev/mtdblock0 /tmp/1/` and it worked for me!

I was now able to see all my lost files in /tmp/1/ !!! the whole filesystem was there and worked great. I extracted all the code I wrote and learned my lesson never to do development on a router and always backup and check in. Hopefully this helps someone out.

New project: Arduinoponics

So I started a new personal project in the past week or so. I built a very crude hydroponics setup using old Gatorade bottles and a Ford windshield washer pump to push nutrient-water through the system from a 2L Coke bottle as the “reservoir”. Ghetto. As. Hell. You can check out pics of it here: http://www.flickr.com/photos/nemik/sets/72157622608195083/

So I thought it would be cool to automatically control all this via the Arduino. I built a simple little circuit to control the pump so it runs for a few seconds every 10 minutes. However this could be expanded further so that the entire hydroponics setup can be automated via a computer that talks serially to the Arduino.

The Firmata (http://firmata.org/) firmware is designed to let a host computer talk to the Arduino in this way. So I modified it a little to for the project. It can use the Firmata functions of reading analog pins to get sensor readings but I wanted to have critical functionality like the turning on/off of the pump at specific intervals to be under the Arduino’s control. Just in case the host computer crashes or a connection is lost somehow, that a critical part of the plant’s needs such as water does not break as well.

The project is hosted here http://github.com/nemik/arduinoponics and licensed freely under and MIT license.

There is still a lot of work to do here. I should post schematics for my setup first I suppose. So I’ll do that once I find a decent software in Mac or Linux that can draw schematics, never done this before.
Also, I need to write host-software for the setup. I have a FON2100 Linux modem running the OpenWRT firmware and it has the Lua language on it. I’ve never used it before but it doesn’t seem too hard. I’m thinking to maybe write a Firmata implementation for Lua (probably based on the existing Java one used in Processing). I already got it talking serial to the Arduino so it might not be too bad. Or I could just use an old laptop and then maybe modify some existing Firmata host software rather than have to make the Lua one; I’ll have to see. The Fon router is just attractive now because it comes in such a small size and runs off 5V so it could share the power for the Arduino. Provided the 12V adapter I’m using for the pump and 7805 regulator to the Arduino can handle all this…it’s only rated for 1A. I may have to get a larger one.

Anyway, let me know what you think. I would love suggestions for this.