Sunday, October 19, 2014

3.14 Beaglebone and PRU

Spent the weekend getting 3.14.19 and builtroot up and running.  For the past month I've been using 3.17 version from kernel.org.  But this version did not support uio or remoteproc without some patches.  The beaglebone Debian is moving to using the kernel from TI 3.14.19, this kernel has patches for remoteproc support for PRU.

So, what does remoteproc support do?

  • The kernel will auto load PRU0 and PRU1 if there are images in the /lib/firmware directory.  Here is a snippet from kernel boot:

[    4.141922]  remoteproc0: wkup_m3 is available
[    4.146591]  remoteproc0: Note: remoteproc is still under development and considered experimental.
[    4.156581]  remoteproc0: THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.
[    4.171128] pruss-rproc 4a300000.pruss: creating platform devices for PRU cores
[    4.179184]  remoteproc0: powering up wkup_m3
[    4.183806]  remoteproc0: Booting fw image am335x-pm-firmware.elf, size 154768
[    4.196764]  remoteproc1: 4a334000.pru0 is available
[    4.202978]  remoteproc0: remote processor wkup_m3 is now up
[    4.209029]  remoteproc1: Note: remoteproc is still under development and considered experimental.
[    4.218660]  remoteproc1: THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.
[    4.230579]  remoteproc1: failed to load rproc-pru0-fw
[    4.236211] pru-rproc 4a334000.pru0: booting the PRU core manually
[    4.242935]  remoteproc1: powering up 4a334000.pru0
[    4.248576]  remoteproc1: request_firmware failed: -2
[    4.253862] pru-rproc 4a334000.pru0: rproc_boot failed
[    4.259804] pru-rproc: probe of 4a334000.pru0 failed with error -2
[    4.267368]  remoteproc2: 4a338000.pru1 is available
[    4.272810]  remoteproc2: Note: remoteproc is still under development and considered experimental.
[    4.282292]  remoteproc2: THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.
[    4.293770]  remoteproc2: failed to load rproc-pru1-fw
[    4.299574] pru-rproc 4a338000.pru1: booting the PRU core manually
[    4.306039]  remoteproc2: powering up 4a338000.pru1
[    4.311536]  remoteproc2: request_firmware failed: -2
[    4.316818] pru-rproc 4a338000.pru1: rproc_boot failed
[    4.322460] pru-rproc: probe of 4a338000.pru1 failed with error -2

The kernel attempts to load rptoc-pru0-fw and rproc-pru1-fw.  At this time, there is no files, so it fails to load.

One other important issue, is, capemgr is not supported.  There is a nice project at github I'm going to start to use the the config-pin to setup digital lines for LEDs and interrupt from BMP180.  


  • using uio the firmware needs to be in tow parts, data and binary.  Now, using remoteproc, it can be in the elf file format. 
  • There are a couple of projects that use PRU remoteproc to DMA messages between the A8 and PRU.  

For this project, it will be a simple shared memory access from userspace to PRU memory to read a list of PWM decode values.

I'm using the github 3.14 branch and using the defconfig bb.org_defconfig.

The plan over the next few blogs to to get a simple PWM decode app connection to a hobbyking receiver. 

Here is a quick diagram.   



Sunday, October 12, 2014

Quad copter (BeagleBone and Teensy 3.1)

I've started two quad-copter projects:
The second quad-copter:

The Teensy/250 quad is flying well, the motors in the kit are a little to under power to lift anything but it is a great way to learn the software and quad-copter basics.  Will show more pictures and a basic tear-down. 

The BeagleBone (white) has a lot of advantages out of the box, i.e simple debugging via gdb on board, lots of memory, and easy of developing on Linux.  BaseFlight-Configurator application reports the loop time in microseconds, it is a little more jittery then Teensy 3.1 but within reason. Will report the actual numbers soon.

The basic interfaces for beaglebone:
  • I2C: Sensors and LCD interface
    • This is up and working and plotting in the GUI.
  • PWM decode input
    • Using PRU (starting to code this now)
    • Using the PRU keeps the Linux code clean.  Maybe after this is done, try to see if it can be done using a kernel driver.  
  • PWM generation for ESC control
    • This is using the internal ehwpwm via the sys
  • Serial Port
    • 115200 to Baseflight-configurator
  • Using buildroot
    • Linux 3.16
    • Enabled SMP with realtime scheduler
    • (Will update to use new buildroot, just added the pru package)
    • Since cape-mgr is not supported in the new kernel, will provide a device tree and simple start up scripts. 
The goal is to re-code the loop and break it up to several loops using discrete timerfd for each loop and libev as the interface.  General coding for this has started, but, since the basic polling loop is working, the only big block to do is the PWM decode.  

The goal of porting to the BeagleBone is to then port to the Edison Intel board.  But, Intel has no RTOS support for Quark processor.  Once this is done, it should be easy to port Baseflight and run it on the Quark and keep the Atom processors Linux, to do Vision and flight navigation.  

More to come.... 





Friday, April 25, 2014

The tractor

Finally got it all together:


The goal was to use a phone or tablet to control the RC car/tuck/tractor via a web browser using touch events via WIFI.    This way, only one app is needed, no need to learn IOS, Android, or worse NOOK API.

So, to do this, the phone/tablet would need to be a hot spot or the RC "tractor" needs to be a hot spot.  iPhone/iTouch don't support being a hot spot, plus being a hot spot does drain the battery life.  So, the RC tractor needs to be a WIFI hot spot/access point.  Most newer USB WIFI dongles support SoftAP mode in the hardware.  Linux also provides support for this via hostapd.  More about this later..

Parts list
- Chassis
- Motor controller
- SBC (Linux single board computer)
- Battery pack
- USB Hub
- USB Wifi stick (Belkin) supports softAP

Controller
- Web Server
- daemon task to process  httpXMLRequests (There is a way to resolve the CORS issue)

Update:
- Changed the Wifi to a bluetooth USB.  This makes it easier to control outside in the sun.

Here us a very basic wiring diagram:   Changed the web client app to use the cwiid interface and use a basic wiiremote with classic controller.

Sunday, December 22, 2013

Olimex Micro and PWM Pin outs

Here are some of the issues of moving the Serial port to AUART

- During boot the RX AUART needs to be tied to VCC to prevent it from floating and having junk appear and cause u-boot to suspend booting.
- The debug UART does output a message if the SDCARD is not valid.


Added a couple of boot scripts to control the LED on the Micro. The idea is to let the user know the status of the boot process.

- solid green: u-boot is running.
- slow blink rate: Linux kernel us running
- flash blink rate: Wifi is connected to AP

During the Linux boot process /etc/init.d boot scripts are executed.  The lower the number the file will be started before others:

S10Led:

cd /sys/class/leds/green
cat trigger
echo none > trigger
cat trigger
echo 1 > brightness
echo 0 > brightness
echo timer > trigger
echo 500 > delay_on
echo 500 > delay_off

Sets up the LED to blink at 500ms off and 500ms on.



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 ..






Using buildroot

IMHO buildroot is the one of the smallest footprint Linux distribution in WWW for embedded devices. Having a small memory foot print is very useful when only 64MB of RAM is available; the amount on the Micro.

Here is a step by step to create a simple Linux distrubution for the Micro using buildroot on Linux.


  1. Create a directory in your home directory ie mkdir micro; cd micro; mkdir bld
  2. The idea is to have buildroot in one directory and your build directory bld as another directory,  This keeps things clean and able to know what is what. 
  3. Use git to retrieve buildroot git clone git://git.buildroot.net/buildroot
  4. Now there should be two directories under micro; bld and build
  5. cd into bld
  6. make -C ../buildroot/ O=$PWD olimex_imx233_olinuxino_defconfig
  7. The above step creates the proper make files to start the compile process of tools (compilers, tools, Linux, rootfs)
  8. Once this completes do a make
  9. This will take some time to complete. Once this a image directory is created with a sdcard image ready to program.
  10. There is directions to program a SD card image in the buildroot/board/olimex/imx233_olinuxino/readme.txt  Buildroot creates a boot-able Linux image.
In the next post how to create a u-boot image for the Micro... 


Saturday, October 5, 2013

How to pass command line arguments via the device tree



Need to append kernel boot arguments that are provided within the kernel image

Why would this be needed?

u-boot can pass device tree, boot arguments for the Linux kernel, load the Linux image from a sdcard or flash chip via the boot script.  Very flexible and powerful idea.  But, if changes need to be done of enhancing the kernel arguments due to some new feature, then u-boot environment needs change.  

To simplify this process, the kernel can provide a default boot arguments, so, if a kernel feature or some feature then the can be added.  But here is the issue, if the device tree is appended image then the boot arguments need to come from the device tree not the compiled in aurgments. 

For example:

chosen {
  bootargs = "console=ttyS0,115200 loglevel=8";
  
 }