Monday, October 5, 2015

FreeRTOS on Zynq : recipe for target '*.s' failed

If you are working on FreeRTOS on Zynq, chances are high that you have come across this error while compiling FreeRTOS on Eclipse.

Running Make libs in ps7_cortexa9_0/libsrc/freertos822_xilinx_v1_0/src
make -C ps7_cortexa9_0/libsrc/freertos822_xilinx_v1_0/src -s libs  "SHELL=/bin/sh" "COMPILER=arm-xilinx-eabi-gcc" "ARCHIVER=arm-xilinx-eabi-ar" "COMPILER_FLAGS=  -O2 -c" "EXTRA_COMPILER_FLAGS=-g"
/bin/sh: arm-none-eabi-gcc: command not found
<builtin>: recipe for target '*.s' failed
make[1]: *** [*.s] Error 127
Makefile:27: recipe for target 'ps7_cortexa9_0/libsrc/freertos822_xilinx_v1_0/src/make.libs' failed


Fixing it is rather easy.
open the file Xilinx_FreeRTOS_BSP/repo/bsp/freertos822_xilinx_v1_0/src/Makefile_ps7_cortexa9

line 101 reads,
KERNEL_AR_OBJS = *.c *.S *.s

change it to read
KERNEL_AR_OBJS = *.c *.S

Save and exit

Re-Generate BSP sources and compile.

What happened is that, since there are no .s files at the very first go, make complains about it and halts processing. From next time onwards, since there are .s files created in the previous compilations, it does not complain or stop processing.

Looks like this is a bug in FreeRTOS makefile (In microblaze make file, there is no .s in the corresponding line)

Friday, September 25, 2015

Keeping your external hdd cooler (and last longer)

I have a 3TB external HDD -- it is a WDC WD30EZRX-00SPEB0 HDD in an USB3.0/eSATA 2.0 enclosure I bought from EBay. I have a cron job running to back up important git repos and other work I currently do

Since the cron job is scheduled to run every day 2 times, the drive sits idle for rest of the day. And after a couple of days, I noticed that the drive is getting really really warm

So, I started running hddtemp in my conky to keep a watch on the temperature and I realized that when I start my day,

$ hddtemp /dev/sdd
/dev/sdd: WDC WD30EZRX-00SPEB0: 30°C


After an hour or so,
$ hddtemp /dev/sdd
/dev/sdd: WDC WD30EZRX-00SPEB0: 48°C


Hmm... it is well within the operating range. (1-60, according to Spec here). But I don't like it. Must be using a lot of energy...

First I thought of keeping it switched off (the enclosure has a power switch). But I had to change my mind after 2 days...  I keep the drive under the table and it was hard to reach. Also, I hit my head on the underside of the table ... ouch!

So, I want a mechanism to mount the drive when required and unmount it after I am done with my backup (BTW, I use luckybackp on Debian. It is a pretty neat tool for backing up data)

configuring autofs on debian/ubuntu

Install autofs
# apt-get install autofs

Open /etc/auto.master and insert the following line (or similar one)

/export/esata    /etc/auto.scsi --timeout=60,user,defaults,exec,suid,dev

This line tells autofs to use the map /etc/auto.scsi with mount options user,defaults,exec,suid,dev and impose a time out of 60 seconds for the mount point /export/esata

$ cat /etc/auto.scsi

wdgreen        -fstype=auto    :/dev/esata5


This tells automount to mount /dev/esata5 onto the directory wdgreen in /export/esata/ with file system type set to auto (will resolve to ext4, since I use ext4 on the partition)

For another drive in another system, I have the following entry
$ cat /etc/auto.usb
seagate1-2      -fstype=auto            :/dev/disk/by-id/ata-ST31000528AS_6VPFKQAN-part2


Hmm... but how to make sure that the drive, when connected, will create a dev entry /dev/esata5?

[[By using /dev/disk/by-id/* entries, you can avoid the following udevadm gymnastics.]]


Udev is the answer
# udevadm info --query=name --attribute-walk /dev/sdd |less # replace sdd with your drive's  block device

From the long list, pick an attribute that identifies the drive unambiguously. In my case, it is
ATTRS{model}=="WDC WD30EZRX-00SPEB0"
under
SUBSYSTEMS=="scsi"

A word of caution : the spaces within double quotes are important, do not miss them if you have space(s) at the beginning or end

Use this string to create a udev rule
# cat /etc/udev/rules.d/89-esata-disk.rules

SUBSYSTEMS=="scsi", ATTRS{model}=="WDC WD30EZRX-00SPEB0", SYMLINK+="esata%n"


Save the rule and restart udev (Sometimes you may need to restart the system, I have no idea why)

 Now all is set
$ ls /export/esata
<nothing>
$ cd /export/esata/wdgreen
<will take a few seconds, you may hear the drive spinning up as well>
$ ls 
<file list here>

Similarly,
$ cd /export/usbdisk/seagate1-2
$ ls 
<file list here>

The auto.usb for that drive is here
$ cat /etc/auto.usb
seagate1-2      -fstype=auto            :/dev/disk/by-id/ata-ST31000528AS_6VPFKQAN-part2

Putting the drive to sleep


# hdparm -y  /dev/esata

/dev/esata:
 issuing standby command


Shedule it in cron
# crontab -e

5,25,45 * * * * /sbin/hdparm -y /dev/

This means cron will issue the command to sleep every hour 5th, 25th and 45th minutes
You can run it at the interval you want. But please note that once the drive is in sleep mode, it takes 5-15 seconds to spin up and be accessible

After all these, when I check the temperature,
# hddtemp /dev/esata
/dev/esata: WDC WD30EZRX-00SPEB0   : drive is sleeping


# cd /export/esata/wdgreen
<takes around 10 seconds here ...>

$ hddtemp /dev/sdd
/dev/sdd: WDC WD30EZRX-00SPEB0: 34°C


Success!

Edit:
Apparently hdparm -y applies only to HGST drives (hitachi)
For other drives (e.g. ones connected over USB 3.0, you can use smartctl)

$ if [ -L /dev/disk/by-id/ata-ST31000528AS_6VPFKQAN ] ; then smartctl -d sat -s standby,60 /dev/disk/by-id/ata-ST31000528AS_6VPFKQAN ; fi

This commands sets the drive standby time to 300 seconds.
-d sat is for some USB to SATA chipsets. check smartctl for other possible values to use with -d option

Sunday, September 20, 2015

awk: symbol lookup error: awk: undefined symbol: mpfr_z_sub

Well, I have been working with Vivado 2014.4 for a while for a client's microZed board. After upgrading to Vivado (and XSDK) 2015.2, I started seeing this error


[1253]$ cat !!:$
cat ~/bin/xilinx-2015_2-setup.sh
#! /bin/bash
if [ "X$(basename -- "$0")" = "Xsetup-xilinx-sdk.sh" ] ; then
        echo "$0 must be sourced. Cannot execute"
        exit -1
fi

# set -x
XILINX_SDK_PATH=/export/space/xilinx/opt/SDK/2015.2
XILINX_UBOOT_SRC=/export/space/xilinx/src/u-boot-xlnx.git
XILINX_LINUX_SRC=/export/space/xilinx/src/linux-xlnx.git
XILINX_PETA_PATH=/export/space/xilinx/petalinux-v2015.2-final
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-

echo $PATH | grep -q ${XILINX_SDK_PATH}
if [ $? != 0 ] ; then
    PATH=$PATH:${XILINX_SDK_PATH}/bin:/export/space/xilinx/petalinux-v2015.2-final/tools/linux-i386/petalinux/bin/unexport:/export/space/xilinx/petalinux-v2015.2-final/tools/linux-i386/petalinux/bin:${XILINX_UBOOT_SRC}/tools
    echo "PATH=${PATH}"
fi
source ${XILINX_SDK_PATH}/settings64.sh
source ${XILINX_PETA_PATH}/settings.sh
#set +x

$source ~/bin/xilinx-setup


[1277]$ petalinux-config --get-hw-description=../hwdef
awk: symbol lookup error: awk: undefined symbol: mpfr_z_sub
awk: symbol lookup error: awk: undefined symbol: mpfr_z_sub
INFO: Checking component...
awk: symbol lookup error: awk: undefined symbol: mpfr_z_sub

...
Repeats a number of times.
Now, I am stuck because petalinux-project fails with these messages.

After some web searches, I came across the following site where this is documented - googoolia. The suggestion is to do
LD_LIBRARY_PATH=”” awk

I tried whether it would work with petalinux-project,
[1282]$ LD_LIBRARY_PATH="" petalinux-config --get-hw-description=../hwdef
INFO: Checking component...
INFO: Getting hardware description...


hooray! It did

Later I thought about a better method
 $ ldd `which awk` | grep Vivado
        libmpfr.so.4 => /export/space/xilinx/opt/Vivado/2015.2/lib/lnx64.o/libmpfr.so.4 (0x00007f8b1e72e000)
        libgmp.so.7 => /export/space/xilinx/opt/Vivado/2015.2/lib/lnx64.o/libgmp.so.7 (0x00007f8b1d0c0000)


 [1283]$ pushd   /export/space/xilinx/opt/Vivado/2015.2/lib/lnx64.o
/export/space/xilinx/opt/Vivado/2015.2/lib/lnx64.o ~/labcyte.git/peta/plnx-project
[1284]$ mv  libmpfr.so.4  libmpfr.so.4.orig
[1285]$ mv libgmp.so.7 libgmp.so.7.orig
[1286]$ ldd `which awk` | grep Vivado


[1289]$ petalinux-config --get-hw-description=../hwdef
INFO: Checking component...
INFO: Getting hardware description...


Good, I eliminated some keystrokes :-D