Ajay on Non-MMU Embedded Linux
Making a buildroot based Hello world application for STM32F469

Hello World

It becomes much easier to work with buildroot when we work with an external tree. An external tree is nothing but a folder structure that can be pointed to in the buildroot main folder structure. Then when we can make code changes in that folder and not have to worry about buildroot code changes. Our application stays in our tree. Its much more manageable.

Create folder structure as below. I call it br2-ext-stm32f469 for a few reasons. br2 is buildroot 2, ext is external and stm32f469 is our board. For now make the files empty. Just do a touch command to create empty files.

1. Skeleton Directory structure

$ touch file
br2-ext-stm32f469/
├── external.desc
├── external.mk
├── Config.in
└── package/
    └── hello_world/
        ├── Config.in
        ├── hello_world.mk
        └── src/
            ├── Makefile
            └── main.c

2. External tree boilerplate

external.desc

This file is used to describe what this whole tree is about. It has a name which is used as a variable and a description. These show up when we call make menuconfig

name: SS_STM32F469_EXT
desc: External tree for STM32F469-Discovery (custom DTS + sample app)

external.mk

We are going to traverse various folders and find .mk files in them and run them. This is pretty standard.

include $(sort $(wildcard $(BR2_EXTERNAL_SS_STM32F469_EXT_PATH)/package/*/*.mk))

Config.in

Now we are going to present an option or menu item in the menuconfig for hello_world. Just continue and later this will be shown. So source this Config.in

menu "External options (STM32F469_EXT)"

source "$BR2_EXTERNAL_SS_STM32F469_EXT_PATH/package/hello_world/Config.in"

endmenu

3. Hello World Application

Config.in

Now when we show the hello world applcation, we also need to show some sample help, and have a boolean flag that “checks” the application and provides a variable to use The variable is called BR2_PACKAGE_HELLO_WORLD

config BR2_PACKAGE_HELLO_WORLD
    bool "hello world (sample app)"
    help
      Simple hello-world style application installed to /usr/bin/hello_world.

hello_world.mk

This is a makefile, It says version, location, method etc.. about the hello_world package. It shows that make needs to be called and how this will be installed on the system

################################################################################
# Hello world - simple example package
################################################################################
HELLO_WORLD_VERSION = 1.0
HELLO_WORLD_SITE = "$(BR2_EXTERNAL_SS_STM32F469_EXT_PATH)/package/hello_world/src"
HELLO_WORLD_SITE_METHOD = local

HELLO_WORLD_LICENSE = Proprietary
HELLO_WORLD_LICENSE_FILES =

# If you had deps, list them here (e.g. HELLO_WORLD_DEPENDENCIES = zlib)
HELLO_WORLD_DEPENDENCIES =

define HELLO_WORLD_BUILD_CMDS
	$(TARGET_MAKE_ENV) $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D)
endef

define HELLO_WORLD_INSTALL_TARGET_CMDS
	$(INSTALL) -D -m 0755 $(@D)/hello_world \
		$(TARGET_DIR)/usr/bin/hello_world
endef

$(eval $(generic-package))

Makefile

Finally we have our Makefile. Someone who has worked with Makefile can spot that this compiles a hello_world application depending on main.c file and when clean is called, it deletes the binary. But for someone new to makefile, You may want to read the Makefile manual first.

all: hello_world

hello_world: main.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o hello_world main.c

clean:
	$(RM) hello_world

We finally have the main.c file which has the printf() to print hello.

main.c

#include <stdio.h>

int main(void)
{
    printf("Hello from myapp on Buildroot!\n");
    return 0;
}

4. Build the application

Now go to buildroot folder and run make menuconfig. Notice that the BR2_EXTERNAL is specified pointing to an external directory which contains our top skeleton structure.

$ cd buildroot
$ make BR2_EXTERNAL=../br2-ext-stm32f469/ menuconfig 

You will see how nicely the application shows up in the menu.

Alt menuconfig 1

Fig 1: Menuconfig 1

Now select the external options

Alt menuconfig 1

Fig 2: Menuconfig 2

Select the Hello World. Press esc all the way to the end and save the config.

Alt menuconfig 3

Fig 3: Menuconfig 3

Now simply build it.

$ make 

...
...
INFO: vfat(boot.vfat): cmd: "MTOOLS_SKIP_CHECK=1 mcopy -sp -i '/home/asharma/ext_ssd/stm32f469/buildroot/output/images/boot.vfat' '/home/asharma/ext_ssd/stm32f469/buildroot/output/images/extlinux' '::'" (stderr):
INFO: hdimage(sdcard.img): adding partition 'u-boot' (in MBR) from 'boot.vfat' ...
INFO: hdimage(sdcard.img): adding partition 'rootfs' (in MBR) from 'rootfs.ext2' ...
INFO: hdimage(sdcard.img): adding partition '[MBR]' ...
INFO: hdimage(sdcard.img): writing MBR

The build succceeds and output/build/hello_world-1.0/hello_world is the output file which gets installed in output/target/usr/bin/

$ ls output/build/hello_world-1.0/
hello_world  hello_world.gdb  main.c  Makefile
$ ls output/target/usr/bin/hello_world 
output/target/usr/bin/hello_world

5. Install the application

Follow the previous buildroot part to burn image to the SD Card. When you run it. It shows up like below.

Welcome to Buildroot
login: root
Jan  1 00:02:20 login[45]: root login on 'console'
~ # hello_world
Hello from myapp on Buildroot!
~ #

Similarly one can make complex application. This is a good starting point. Checkin this code into git and keep it safe