2010-09-29

The first charactor of 'ls -l'

  • -   normal file
  • d  directory
  • s  socket file
  • l   link file
  • c  character special
  • p  fifo (named pipe)
  • b  block speical
Reference:
http://www.thegeekstuff.com/2009/07/linux-ls-command-examples/

Solve Warning of minicom: unable to open an initial console.

The situation is:
I want to use nfs system on my linux host (debian, squezze) to start the embedded device (mini2440). The system can successfully start but the minicom didn't work any more. A warning message was reported:

Warning: unable to open an initial console.


The reason: 
The nfs system on my linux host has no /dev/console.

The solution:
>cp -rf /dev/console $rootf/dev/

Reference:
http://kerneltrap.org/node/6854

2010-09-21

Configure with --host, --target and --build options

When people configure a project like './configure', man often meets these three confusing options, which are more related with cross-compilation

  • --host: In which system the generated program will run.
  • --build: In which system the program will be built.
  • --target: this option is only used to build a cross-compiling toolchain. When the tool chain generates executable program, in which target system the program will run.
An example of tslib (a mouse driver library)
'./configure --host=arm-linux --build=i686-pc-linux-gnu': the dynamically library is built on a x86 linux computer but will be used for a embedded arm linux system.

An example of gcc:
'./configure --target=i686-pc-linux-gnu --host=arm-linux --build=i686-pc-linux-gnu':
  • A gcc compiler is build on x86 linux computer. [--build]
  • The gcc will be executed on an embedded arm linux system.[--host]
  • But the gcc will generate the binary program, which run in a x86 linux system. [--target]

Reference:
http://matrix.wearlab.de/en/wiki/index.php?title=ArmCrossCompiler&redirect=no

Increase fsck fequency at startup

Totally disable forced fsck at startup is a bad idea. But it takes more than 5 minutes to scanning a huge disk for every 24 times boot. Why not just change the fequency of forced fsck? The solution is using tune2fs.

1) Check your disk.
>df
/dev/sda1              7850996   5316724   2135460  72% /
tmpfs                   257324         0    257324   0% /lib/init/rw
udev                    252876       144    252732   1% /dev
tmpfs                   257324         0    257324   0% /dev/shm

So, my disk is /dev/sda1
2) Configure the fequency of forced fsck.
  • sudo tune2fs -c 100 /dev/sda1 (100 boot)
  • sudo tune2fs -i 365d /dev/sda1 (365 day)

Reference:
http://ubuntuforums.org/archive/index.php/t-1066069.html

    2010-09-20

    The Basic of PCM

    PCM stands for "Pulse Code Modulation". In plain text, an analog signal is sampled and the samples is encoded into a stream of PCM word.


    PCM data is relatively immune against noise during transmission because the reciever need only to tell "1" or "0" states of the inputing stream.

    Reference: 

    High impedance of output

    In digital circuit, the output line has usually three states, namely, 0, 1 and high impedance.
    In the state of 0 or 1, the output line has a low impedance. When the output in the high impedance state, the output line will be effectively removed from the rest of circuit. In such way, it allows multiple circuits to share the same output line.

    Arbiter

    Abiter is an eletronic device to determine the order of access to a shared resource, when the resource is almost at the same time requested by several processores.

    How SPI works

    Based on SPI wiki, a short summary of SPI mechimism.

    Four logic signals.
    • SCLK — Serial Clock (output from master)
    • MOSI/SIMO — Master Output, Slave Input (output from master)
    • MISO/SOMI — Master Input, Slave Output (output from slave)
    • SS — Slave Select (active low; output from master)


    Data transimission:

    During each SPI clock cycle, a full duplex data transmission occurs:
    • the master sends a bit on the MOSI line; the slave reads it from that same line
    • the slave sends a bit on the MISO line; the master reads it from that same line

    Scanning algorithm for 3 x 4 Keypad Matrix

    When a keypad is connected with a microprocessor, e.g 8051, a scanning algorithm is used to detect the pressed keys. See shown in [1]


    Scanning algorithm
    1.       Start.
    2.       Make All Pins High.
    3.       Make Column 1 pin low.
    4.       Check if Row 1 is low, if yes then Switch 1 has been pressed.
    5.       Check if Row 2 is low, if yes then Switch 4 has been pressed.
    6.       Check if row 3 is low if yes then Switch 7 has been pressed.
    7.       Check if row 4 is low if yes then Switch 10 has been pressed.
    8.       Make Column 1 Pin high & Column 2 Pin Low.
    9.       Check if Row 1 is low, if yes then Switch 2 has been pressed.
    10.   Check if Row 2 is low, if yes then Switch 5 has been pressed.
    11.   Check if row 3 is low if yes then Switch 8 has been pressed.
    12.   Check if row 4 is low if yes then Switch 11 has been pressed.
    13.   Make Column 2 Pin high & Column 3 Pin Low.
    14.   Check if Row 1 is low, if yes then Switch 3 has been pressed.
    15.   Check if Row 2 is low, if yes then Switch 6 has been pressed.
    16.   Check if row 3 is low if yes then Switch 9 has been pressed.
    17.   Check if row 4 is low if yes then Switch 12 has been pressed.
    18.   Make column 3 pin high
    19.   Stop
    Reference: 
    [1]http://www.dnatechindia.com/index.php/Tutorials/8051-Tutorial/Interfacing-Matrix-Keypad-to-8051.html

    2010-09-19

    Show Laptop battery status on Linux

    gnome-power-manager is good software to manager and show status of battery and power consumption.

    2010-09-18

    Useful tools for the problem 'undefined reference to..'

    ldd: prints the shared libraries required by each program or shared library specified on the command line.
    [example]
    >ldd /usr/lib/libACE.*
        librt.so.1 => /lib/librt.so.1 (0x4819f000)
        libdl.so.2 => /lib/libdl.so.2 (0x481ae000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x481ba000)
        libm.so.6 => /lib/libm.so.6 (0x48295000)
        libc.so.6 => /lib/libc.so.6 (0x48342000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x48469000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x4847d000)
        /lib/ld-linux.so.3 (0x40071000)

    nm: list symbols from object files
    [example]
    >nm -C -u libwx_baseu-2.8.so

    readelf: Displays information about ELF files.
    [example]
    >readelf -s /lib/libdl.so.2                                             

    Symbol table '.dynsym' contains 39 entries:
       Num:    Value  Size Type    Bind   Vis      Ndx Name
         0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
         1: 00000830     0 SECTION LOCAL  DEFAULT   10
         2: 00000000   200 FUNC    GLOBAL DEFAULT  UND strerror@GLIBC_2.4 (4)
    ....

    Solve 'undefined reference to' problem

    To learn how to use scratchbox2 for cross-compilation, I attempted to repeat the steps in the wiki [2]. Everything works fine, until I tested the example 'More complicated example: with libraries'. The example failed to link to library ACE:

    max@dev1:~/work/arena/sheeva_debian/source$ sb2 gcc -lACE test.o -o test
    /home/max/work/arena/sheeva_debian/debian_rootfs/lib/libdl.so.2: undefined reference to `_dl_tls_get_addr_soft@GLIBC_PRIVATE

    The reason is inconsistent version of dynamical libraries installed in  scratchbox system. The scratchbox system has following settings
    I checked the library dependency as followings:
    1) Since the '-lACE' is used, so we check the dependency of libACE by

    max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR ldd /usr/lib/libACE.so
        librt.so.1 => /lib/librt.so.1 (0x4819f000)
        libdl.so.2 => /lib/libdl.so.2 (0x481ae000)
        libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x481ba000)
        libm.so.6 => /lib/libm.so.6 (0x48295000)
        libc.so.6 => /lib/libc.so.6 (0x48342000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x48469000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x4847d000)
        /lib/ld-linux.so.3 (0x40071000)

    2) According to the error messages, libdl.so has a undefined reference, therefore, I continue to check the dependency of libdl.so.2

    max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR ldd /lib/libdl.so.2
        libc.so.6 => /lib/libc.so.6 (0x4807f000)
        /lib/ld-linux.so.3 (0x40071000)

    3) Obviously, libc.so.6 is a symbolic link to the real library /lib/libc.so.6. You can also check the 'undefined reference' reported in link error by

     max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR readelf -s /lib/libdl.so.2 | grep -i _dl_tls_get_addr_soft@GLIBC_PRIVATE
        10: 00000000   164 FUNC    GLOBAL DEFAULT  UND _dl_tls_get_addr_soft@GLIBC_PRIVATE (6)


    It seems that two libraries is involved:

    • /usr/lib/libACE.so 
    • /lib/libdl.so.2

    According to statement in [1]:

    When you link a shared library against other shared libraries (e.g. link libwx_baseu-2.8.so against libstdc++.so), the linker records versioned symbols used by libwx_baseu and provided by libstdc++.
    If at runtime you use a different copy of libstdc++ (one which doesn't provide the same versioned symbol(s)), you get a (dynamic) liking error and the program doesn't run at all (this is preferable to a "mystery" crash later on).
    The reason is these two libraries are inconsistent. The solution: reinstall the packages that contains the two libraries.


    After checking the in www.debian.org, I found the involved packages in lenny.
    Let's reinstall it by
    > sb2 -eR apt-get install --reinstall libace-dev libc6-dev

    The example is successfully linked.

    References:
    [1] http://stackoverflow.com/questions/2643738/elf-linking-why-do-i-get-undefined-references-in-so-files
    [2] http://www.plugcomputer.org/plugwiki/index.php/Scratchbox2_based_cross_compiling

    2010-09-17

    Virtualbox comes back to live after upgrade from lenny to squeeze

    After upgrade from lenny to squeeze, the installed virtualbox didn't work any more. Try to load the module manually
     
    >modprobe vboxdrv
    The following messages are shown:

    WARNING: The character device /dev/vboxdrv does not exist. 
             Please install the virtualbox-ose-modules package for your kernel and
             load the module named vboxdrv into your system.
    
             You will not be able to start VMs until this problem is fixed.
     
     

    The most important thing is to installed the right linux-headers packages.  For the updated system (squeeze) with a kernel 2.6.32-5-686,

    >sudo apt-get install linux-headers-2.6-686

    DKMS will build the VirtualBox OSE modules for your system.

    >modprobe vboxdrv
    >virtualbox
    Virtualbox comes back ...

    References:

    apt-get doesn't work anymore

    See http://journalxtra.com/2010/03/fixing-the-dreaded-errors-were-encountered-while-processing-errors/

    Upgrade from Lenny to Squeeze

    1)  Update /etc/apt/source.list

    deb http://ftp.de.debian.org/debian/ squeeze main
    deb-src http://ftp.de.debian.org/debian/ squeeze main

    deb http://ftp.us.debian.org/debian/ squeeze main
    deb-src http://ftp.us.debian.org/debian/ squeeze main


    2) update local package database
    >sudo aptitude update


    3) update package management
    >sudo aptitude install apt dpkg aptitude

    4) update kernel image
    >sudo aptitude install linux-image-2.6-686

    5) reboot computer and start with new kenerl 2.6.32
    6) update all packages
    >sudo aptitude full-upgrade


    Reference:

    Debian kernels version

    Lenny:  2.6.26
    Squeeze: 2.6.32
    Sid: 2.6.32

    2010-09-16

    scratchbox2 repository moves to maemo.gitorious.org

    See the sad announcement http://freedesktop.org/wiki/Software/sbox2
    "I have no further interest in any of this distribution cross-compilation stuff. " 
    New repository of sbox is here. http://maemo.gitorious.org/scratchbox2

    sb2-init: cannot run C compiled programs

    > sb2-init -c /opt/qemu/bin/qemu-arm sheeva_debian /root/opt/toolchains/arm-2010q1/bin/arm-none-eabi-gcc

    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... no
    checking for mawk... mawk
    checking whether make sets $(MAKE)... yes
    checking for gcc... gcc
    checking for C compiler default output file name... a.out
    checking whether the C compiler works... configure: error: cannot run C compiled programs.


    The reason of failed test was the gcc compiler was wrong. See
    I downloaded "Sourcery G++ Lite Edition for ARM" with target OS "EABI". After I switched to the one target OS "GNU/Linux", the error disappeared.

    2010-09-15

    Installation xp on Thinkpad Edge 13"

    • Enter BIOS, set S-ATA(AHCI) to S-ATA(Compatible), otherwise, you will get bluescreen during installation xp on a thinkpad notebook.
    • Find the latest drivers of Thinkpad laptop here.
    • Create an image for system disk after installation of system, driver, hotfix. Ghost 2003 BootCD, whose iso file can be downloaded here, is a good tool to do this job. It also supports USB CD-Rom, which old Ghost may not support. 
    • EASEUS Partition Master - Home Edition is very nice free disk partition software.

    2010-09-08

    Should I refactor?

    A more important question suppose to be "why should I refactor?"

    Becasue we have to constantly change our code. You may ask, "is it possible some computer genius can implement a software just for once, then the software works perfectly and it requires no further efforts?" The answer is NO. If it is a real software, not just a simple programming exercise task, this kind "once forever" story never happens. In this cruel world, we must be ready to change the given code, perhaps quite often, for example fixing new bugs, adding new features or porting to other programs.

    The structure of software becomes more and more complex, even a simple 'notepad' program has hundreds of lines. It is a nightmare for a programmer to changing a spaghetti code mess to make the software work as you wish. Thusfore, we need a good program struture. It can only save a lot of time, effort and money, but more importantly, it makes the software is maintainable, scalable and reliable against to modifications.

    Is it possible that architecture can design a nice structure from top to bottom at the beginning, then programmers just write the code execatly according to this perfect design? Theoretically maybe, in pracice almost IMPOSSIBLE. The truth is that you can only more clearly understand your problem, as you have start to tackle it. In a design phase of a software project, it is diffcult for architectures and developpers to fully understand all requirements, to see all aspects of implmenetation and design a perfect structure, until the implementation really is ongoing and people meet one unexpected problem after the other and little by little have a better idea to implement the software. Don't be frustrated, we are human with a limited perception, even the best programmer.

    As we constantly update our understanding of project and decide to improve the structure, refactor comes into the play. Refactor is a work that make the program have a better inner struture, but doesn't change it external function and behavior.

    "What is a better structure?" I think a good structure is a realization of a right design pattern, so that people can esily understand the code and easily change the code in future.

    Personally, I like to refactor before I have to change the code. For example, I want to implement a new feature of software and I find out that I need to change more than ten classes. It is a smell of bad structure. I'd better refactor the program at first. After refactoring, the program has a better inner strucure, perhaps I only need to write a tiny subclass to implement the feature. Summary: Before you want to change the existing code, think about at first the possiblity of refactor. Believe me, you will largely benifit from this good programming habit.

    Sometimes, if I don't have too much time pressure, I'd like to spend some hours to investigate whether some classes in the project are too big or too complicated. The command below could be useful to show the line number of class files:

    >find -type f -name '*.qml' | xargs wc -l | less

    A class with huge size may be a candidate of refactor, more specifically, decomposition: sperate it into several small classes. Small classes are better, easily to understand and easily to maintain than big ones.

    2010-09-07

    Processing each line of a file by batch

    An example of processing each line of a given file
    @echo off
    for /f "delims=] tokens=1*" %%a in ('find /v /n "" ^<.\newsources.txt') do (
       echo %%b
    )
    

    QML Weather

    Based on Google online API, Max implemented a weather panel using QML (Qt 4.7 declarative).


    The three XmlListModels are used to extract need information for display.


    RssModeInfo.qml
    XmlListModel {
        source: "http://www.google.com/ig/api?weather=forchheim"
        query: "/xml_api_reply/weather/forecast_information"
    
        //forecast information
        XmlRole { name: "city"; query: "city/@data/string()" }
        XmlRole { name: "forecast_date"; query: "forecast_date/@data/string()" }
        XmlRole { name: "current_date_time"; query: "current_date_time/@data/string()" }
    

    RssModeCurrent.qml
    XmlListModel {
        source: "http://www.google.com/ig/api?weather=forchheim"
        query: "/xml_api_reply/weather/current_conditions"
    
        //current condition
        XmlRole { name: "condition"; query: "condition/@data/string()" }
        XmlRole { name: "temp_c"; query: "temp_c/@data/string()" }
        XmlRole { name: "humidity"; query: "humidity/@data/string()" }
        XmlRole { name: "icon"; query: "icon/@data/string()" }
        XmlRole { name: "wind_condition"; query: "wind_condition/@data/string()" }
    
    }
    

    RssModeDailyForecast.qml
    XmlListModel {
        property int index
    
        source: "http://www.google.com/ig/api?weather=forchheim"
        query: "/xml_api_reply/weather"
    
        XmlRole { name: "day_of_week"; query: "forecast_conditions[" + index.toString() + "]/day_of_week/@data/string()" }
        XmlRole { name: "low_f"; query: "forecast_conditions[" + index.toString() + "]/low/@data/string()" }
        XmlRole { name: "high_f"; query: "forecast_conditions[" + index.toString() + "]/high/@data/string()" }
        XmlRole { name: "icon"; query: "forecast_conditions[" + index.toString() + "]/icon/@data/string()" }
        XmlRole { name: "condition"; query: "forecast_conditions[" + index.toString() + "]/condition/@data/string()" }
    
    } 

    2010-09-06

    Google Weather API

    iGoogle Weather Feed API hasn't yet officially support the xml feed of weather. Anyway it can be used by http://www.google.com/ig/api?weather=$city.

    For example, you want the rss feed of shanghai:

    http://www.google.com/ig/api?weather=shanghai

    In the xml, you will get current conditions and 4-days forcast.

    22 Possible condition icons:

    chance_of_rain.gif
    sunny.gif
    mostly_sunny.gif
    partly_cloudy.gif
    mostly_cloudy.gif
    chance_of_storm.gif
    showers.gif
    rain.gif
    chance_of_snow.gif
    cloudy.gif
    mist.gif
    storm.gif
    thunderstorm.gif
    chance_of_tstorm.gif
    sleet.gif
    snow.gif
    icy.gif
    dust.gif
    fog.gif
    smoke.gif
    haze.gif
    flurries.gif

      Reference:

      2010-09-01

      QRegExp Extracts the Content of Online-News

      The following example shows how to extract the string between <div class="yn-story-content"> and </div>.

      ContentExtractor::ContentExtractor(QObject *parent)
          : QObject(parent)
      {
      
          //regexp pattern
          QString escape1 = QRegExp::escape("<div class=\"yn-story-content\">");
          QString escape2 = QRegExp::escape("</div>");
          QString aPattern = escape1 + "(.*)?" + escape2;
          regExp_.setPattern ( aPattern );
          regExp_.setMinimal ( true );
          regExp_.setCaseSensitivity(Qt::CaseInsensitive);
      }
      void ContentExtractor::extractContent(QString text_in)
      {
          if (regExp_.indexIn(text_in) != -1) {
              content_ = regExp_.cap(1);
              content_ = content_.trimmed();
              content_ = content_.remove('\n');
              content_ = content_.remove('\t');
          }
      }
      

      It could be very useful to extract the contents of online news. If the extractor is applied on the page "http://news.yahoo.com/s/ap/20100831/ap_on_re_us/us_obama" and content_ is displayed by Text element in QML, you will get well-formatted news text:


      If you want to get the source, please let me know.