Sunday, December 22, 2013

Micro and u-boot

One of the issues of using buildroot with imx233-OLinuxino Micro is any time the Linux image requires to be updated (adding drivers, or features for some user app needs from the kernel) the sdcard needed to be removed and re-imaged.

One way to fix this is to use a bootloader (u-boot).  u-boot is a simple boot loader able to read EXT4/EXT3/EXT2/FAT file systems and load Linux, device trees, and boot files.  It is a very powerful boot loader.

With u-boot, the linux binary zImage is in the EXT4 file system at /boot.  So, using simple ssh commands from Linux, the zImage can be updated like a normal file.

The project the Micro is going to be used for is to control a Multi-Chassis via WIFI using a web browser from an iPAD or Phone.   The reason of using a Web Browser, is it is cross platform; no code to be written for each OS.  To keep things simple, it does not support control from the desktop; will get into that more later.

Controlling the chassis is done via a motor controller via PWM.  The Micro has 3 PWM controllers.
For this project one of the biggest hurdle was the PWM pins are also used for the serial pins for u-boot and Linux.  PWM0 (RX) PWM1(TX) are on the debug serial port.  So, needed to reconfigure u-boot to use AUART APP0 serial port.

To move u-boot and Linux serial ports does take some doing.  Here are the basic steps:

1. edit build/uboot-2013.10/include/configs/mx23_olinuxino.h
Basic changes are the ENV to boot a zImage and use AUART

/* Extra Environment */
#define CONFIG_EXTRA_ENV_SETTINGS \
"update_sd_firmware_filename=u-boot.sd\0" \
"update_sd_firmware=" /* Update the SD firmware partition */ \
"if mmc rescan ; then " \
"if tftp ${update_sd_firmware_filename} ; then " \
"setexpr fw_sz ${filesize} / 0x200 ; " /* SD block size */ \
"setexpr fw_sz ${fw_sz} + 1 ; " \
"mmc write ${loadaddr} 0x800 ${fw_sz} ; " \
"fi ; " \
"fi\0" \
"script=boot.scr\0" \
"uimage=zImage\0" \
"console=ttyAMA0\0" \
"fdt_file=imx23-olinuxino.dtb\0" \
"fdt_addr=0x41000000\0" \
"boot_fdt=try\0" \
"ip_dyn=yes\0" \
"mmcdev=0\0" \
"mmcpart=2\0" \
"mmcroot=/dev/mmcblk0p3 rw rootwait\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} " \
"root=${mmcroot}\0" \
"loadbootscript="  \
"ext4load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
"bootscript=echo Running bootscript from mmc ...; " \
"source\0" \
"loaduimage=ext4load mmc ${mmcdev}:${mmcpart} ${loadaddr} /boot/${uimage}\0" \
"loadfdt=ext4load mmc ${mmcdev}:${mmcpart} ${fdt_addr} /boot/${fdt_file}\0" \
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \
"if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
"if run loadfdt; then " \
"bootz ${loadaddr} - ${fdt_addr}; " \
"else " \
"if test ${boot_fdt} = try; then " \
"bootz; " \
"else " \
"echo WARN: Cannot load the DT; " \
"fi; " \
"fi; " \
"else " \
"bootz; " \
"fi;\0" \
"netargs=setenv bootargs console=${console},${baudrate} " \
"root=/dev/nfs " \
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
"netboot=echo Booting from net ...; " \
"usb start; " \
"run netargs; " \
"if test ${ip_dyn} = yes; then " \
"setenv get_cmd dhcp; " \
"else " \
"setenv get_cmd tftp; " \
"fi; " \
"${get_cmd} ${uimage}; " \
"if test ${boot_fdt} = yes; then " \
"if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
"bootz ${loadaddr} - ${fdt_addr}; " \
"else " \
"if test ${boot_fdt} = try; then " \
"bootz; " \
"else " \
"echo WARN: Cannot load the DT; " \
"fi;" \
"fi; " \
"else " \
"bootz; " \
"fi;\0"

#define CONFIG_BOOTCOMMAND \
"mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \
"run bootscript; " \
"else " \
"if run loaduimage; then " \
"run mmcboot; " \
"else run netboot; " \
"fi; " \
"fi; " \
"else run netboot; fi"

#define CONFIG_MXS_AUART
#define CONFIG_MXS_AUART_BASE  MXS_UARTAPP0_BASE
/* The rest of the configuration is shared */
#include <configs/mxs.h>


  • Change spl_boot.c in uboot-2013.10/board/olimex/mx23_olinuxino/spl_boot.c

/* DUART */
// MX23_PAD_PWM0__DUART_RX,
// MX23_PAD_PWM1__DUART_TX,
MX23_PAD_I2C_SDA__AUART1_RX,
MX23_PAD_I2C_SCL__AUART1_TX,


For Linux, it is a little easier, need to change the (2) device tree files and one driver file
  • Device tree files imx23.dtsi
pwm0_pins_a: pwm0@0 {
reg = <0>;
fsl,pinmux-ids = <
0x11a0 /* MX23_PAD_PWM0__DUART_RX */
>;
fsl,drive-strength = <0>;
fsl,voltage = <1>;
fsl,pull-up = <0>;
};

pwm1_pins_a: pwm1@0 {
reg = <0>;
fsl,pinmux-ids = <
0x11b0 /* MX23_PAD_PWM1__DUART_TX */
>;
fsl,drive-strength = <0>;
fsl,voltage = <1>;
fsl,pull-up = <0>;
};

pwm2_pins_a: pwm2@0 {
reg = <0>;
fsl,pinmux-ids = <
0x11c0 /* MX23_PAD_PWM2__PWM2 */
>;
fsl,drive-strength = <0>;
fsl,voltage = <1>;
fsl,pull-up = <0>;
};

  • imx23-olinuxino.dts
lradc@80050000 {
status = "okay";
};


  pwm: pwm@80064000 {
pinctrl-names = "default";
pinctrl-0 = <&pwm0_pins_a &pwm1_pins_a &pwm2_pins_a>;
status = "okay";
}; 


auart0: serial@8006c000 {
pinctrl-names = "default";
pinctrl-0 = <&auart0_2pins_a>;
status = "okay";
};

What this does is move the UART and enable the PWM on the proper pins.  One issue is now the PWM clocks are not enabled.  So, need to and the pwm to the clocks when enabled.

  • the clock driver at clk-imx23.c 
Now add pwm to:

static enum imx23_clk clks_init_on[] __initdata = {
cpu, hbus, xbus, emi, uart,pwm,
};

See the last entry is pwm.  Now.. U-boot and the kernel are done.

busybox must also know which tty interface to use along with the boot messages when Linux boots up.

  • CONFIG_CMDLINE="root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyAPP0,115200"
  • And tty is ttyAPP0
If there are questions please post.  The goal is to provide background information on how to do this and it is possible.

The next couple of blogs is how to setup WIFI, use PWM and web page to control ..






No comments:

Post a Comment