Sunday, April 24, 2016

STM32f429 Discovery on ucLinux

Working the ucLinux  get on easily the STM32f429 Doscpvery board. And making image can find github and clone your PC.

For running ucLinux on the STM32f429.

1. Host computer setup.
   My host computer is VM that is made VitrualBox.
   Host OS ubuntu 14.0.4LTS install to VM.

2. Host OS setup.
   Network configure on your environments.

   "git" install and setup.
   $ sudo apt-get update
   $ sudo apt-get install git

   If your environment use proxy when setup proxy environment.
   $ export http_proxy=http://<<PROXY HOST URL>>:<<PORT>>/
   $ export ftp_proxy=http://<<PROXY HOST URL>>:<<PORT>>/
   $ export https_proxy=http://<<PROXY HOST URL>>:<<PORT>>/

3. Install and Build OpenOCD
   OpenOCD needs several packages, so you can find and install them.
   $ sudo apt-get install libtool autoconf automake texinfo
   $ sudo apt-get install libusb-dev libusb-1.0

   OpenOCD download from the github.
   $ git clone http://git.code.sf.net/p/openocd/code

   Build OpenOCD.
   $ cd code
   $ ./bootstrap
   $ ./configure --prefix=/usr/local --enable-stlink
   $ echo -e "all:\ninstall:" > doc/Makefile
   $ make
   $ sudo make install

4. Installing Toolchain.
   Down load “arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2”
   The file exruct, made arm-2010q1 directory. Toolchain are under bin directory. So make path.
   $ export PATH=/home/XXXX/stm32/uclinux/arm-2010q1/bin:$PATH

   In case of execute toolchain when fail commands.
   $ arm-uclinuxeabi-gcc
   bash: /home/XXXX/stm32/uclinux/arm-2010q1/bin/arm-uclinuxeabi-gcc: No such file or directory

   The toolchain commands are made by 32bit program, and need 32bit running environment.
   (My host OS is ubuntu 64bit)
   $ sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0

   If toolchain behave to below as OKAY.
   $ arm-uclinuxeabi-gcc
   arm-uclinuxeabi-gcc: no input files

5. Install romfs
   $ sudo apt-get install genromfs


6. stm32f429 linux download, build and install.
   $ git clone http://github.com/jserv/stm32f429-linux-builder
   $ make
   $ make install

7. But! I can't install!!
   Installing use STLink v2 that needs USB2.0, but VirtualBox has only USB1.0.
   VirtualBox add to USB2.0 function via extension pack.
   Latest VirtualBox version download and install, and more download extension pack. Olacle's VirtualBox here .

   And usb device is "root"
   $ make install
   libusb_open() failed with LIBUSB_ERROR_ACCESS

   $ sudo make install

If you want to change kernel or busybox configuration when need ncurses for "make menuconfig". Top level "make" using configuration files exists in ~/stm32f429-linux-builder/configs are busybox_config and  kernel_config.

Running needs environment:
   STM32F429I-Discovery board
   USB mini B(429) <---> A(PC) for ST-Link

   USB serial conversion cable, I bought that.
      Txd and Rxd line cable.
      Ex. serial connections.
         STM32 PC11 --> Cable connector Orange Txd(PC)
         STM32 PC10 --> Cable connector Yellow Rxd(PC)

   Terminal settings:
      Baud rate: 115200
      Data: 8 bit
      Parity: none
      Stop: 1 bit
      Flow control: none

Booting console output.
U-Boot 2010.03-00003-g934021a ( 4? 21 2016 - 10:17:03)

CPU  : STM32F4 (Cortex-M4)
Freqs: SYSCLK=180MHz,HCLK=180MHz,PCLK1=45MHz,PCLK2=90MHz
Board: STM32F429I-DISCOVERY board,Rev 1.0
DRAM:   8 MB
Using default environment

Hit any key to stop autoboot:  0
## Booting kernel from Legacy Image at 08020000 ...
   Image Name:   Linux-2.6.33-arm1
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    738336 Bytes = 721 kB
   Load Address: 08020040
   Entry Point:  08020041
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Linux version 2.6.33-arm1 (XXXX@STM32-Dev) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #1 Thu Apr 21 10:19:25 JST 2016
CPU: ARMv7-M Processor [410fc241] revision 1 (ARMv7M)
CPU: NO data cache, NO instruction cache
Machine: STMicro STM32
Ignoring unrecognised tag 0x54410008
Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 1778
Kernel command line: stm32_platform=stm32429-disco mem=7M console=ttyS2,115200n8 consoleblank=0 root=/dev/mtdblock0 rdinit=/sbin/init video=vfb:enable,fbmem:0x90700000,fbsize:0x100000
PID hash table entries: 32 (order: -5, 128 bytes)
Dentry cache hash table entries: 1024 (order: 0, 4096 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 7MB = 7MB total
Memory: 6976k/6976k available, 192k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0x00000000 - 0x00001000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0x00000000 - 0xffffffff   (4095 MB)
    lowmem  : 0x90000000 - 0x90700000   (   7 MB)
    modules : 0x90000000 - 0x90800000   (   8 MB)
      .init : 0x9000a000 - 0x9000e000   (  16 kB)
      .text : 0x08028000 - 0x080c4000   ( 624 kB)
      .data : 0x90008000 - 0x90018460   (  66 kB)
Hierarchical RCU implementation.
NR_IRQS:90
Console: colour dummy device 80x30
Calibrating delay loop... 168.34 BogoMIPS (lpj=841728)
Mount-cache hash table entries: 512
bio: create slab <bio-0> at 0
Switching to clocksource cm3-systick
ROMFS MTD (C) 2007 Red Hat, Inc.
io scheduler noop registered
io scheduler deadline registered (default)
Console: switching to colour frame buffer device 60x53
fb0: Virtual frame buffer device, using 1024K of video memory
Serial: STM32 USART driver
stm32serial.2: ttyS2 at MMIO 0x40004800 (irq = 39) is a STM32 USART Port
console [ttyS2] enabled
brd: module loaded
uclinux[mtd]: ROM probe address=0x8120000 size=0x59000
Creating 1 MTD partitions on "ROM":
0x000000000000-0x000000059000 : "ROMfs"
ARMv7-M VFP Extension supported
VFS: Mounted root (romfs filesystem) readonly on device 31:0.
Freeing init memory: 16K
starting pid 27, tty '/dev/ttyS2': '/bin/login -f root'
Welcome to
          ____ _  _
         /  __| ||_|
    _   _| |  | | _ ____  _   _  _  _
   | | | | |  | || |  _ \| | | |\ \/ /
   | |_| | |__| || | | | | |_| |/    \
   |  ___\____|_||_|_| |_|\____|\_/\_/
   | |
   |_|

For further information check:
http://www.uclinux.org/

Jan  1 00:00:01 login[27]: root login on 'ttyS2'
~ #

cpuinfo
~ # cat /proc/cpuinfo
Processor       : ARMv7-M Processor rev 1 (v7ml)
BogoMIPS        : 168.34
Features        : swp half thumb fastmult vfp edsp
CPU implementer : 0x41
CPU architecture: ?(11)
CPU variant     : 0x0
CPU part        : 0xc24
CPU revision    : 1

Hardware        : STMicro STM32
Revision        : 0000
Serial          : 0000000000000000

meminfo
~ # cat /proc/meminfo
MemTotal:           6992 kB
MemFree:            4144 kB
...


free
~ # free
             total         used         free       shared      buffers
Mem:          6992         2848         4144            0            8
-/+ buffers:               2840         4152

hello.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv) {

    printf("   Hello World!!\n");
}

$ arm-uclinuxeabi-gcc  -g  -Os   -g2 -mthumb -mcpu=cortex-m3 -O2 hello.c -o hello

# ./hello
   Hello World!!


Zork
I can play the game for now...
# ./zork
Welcome to Dungeon. This version created 11-MAR-91.
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.
>open mailbox
Opening the mailbox reveals:
A leaflet.
>take leaflet.
Taken.
>read leaflet
Welcome to Dungeon!

Dungeon is a game of adventure, danger, and low cunning. In it you will explore some of the most amazing territory ever seen by mortal man. Hardened adventurers have run screaming from the terrors contained within.

In Dungeon, the intrepid explorer delves into the forgotten secrets of a lost labyrinth deep in the bowels of the earth, searching for vast treasures long hidden from prying eyes, treasures guarded by fearsome monsters and diabolical traps!

No DECsystem should be without one!

Dungeon was created at the Programming Technology Division of the MIT Laboratory for Computer Science by Tim Anderson, Marc Blank, Bruce Daniels, and Dave Lebling. It was inspired by the Adventure game of Crowther and Woods, and the Dungeons and Dragons game of Gygax and Arneson. The original version was written in MDL (alias MUDDLE). The current version was translated from MDL into FORTRAN IV by a somewhat paranoid DEC engineer who prefers to remain anonymous, and was later translated to C.

On-line information may be obtained with the commands HELP and INFO.
>




Wednesday, April 20, 2016

How to get history from Google Chrome browser?

One day, I want to know myself behavior on use pc’s browser. But Google Chrome browser can be only watching that displayed history summary. So best result is text based historical summary (CSV format). How to get historical summary from Google Chrome browser?

Research Result:
  Historical recorded file
    \Users\<USER>\AppData\Local\Google\Chrome\User Data\Default\History
  File format
    SQLite
 Windows Version
    7 64bit, 8 64bit, 10 64bit


I found browser’s historical file and file format. To watch historical file can use SQLite browser then file format is SQLite. DB Browser for SQLite can open the historical DB.

DB structure:
Historical DB has nine tables.
  1) downloads
    Your downloaded files history on your PC.
  2) downloads_url_chains
    Downloading url history.
  3) keyword_search_terms
    Your search history keywords.
  4) meta
    Meta data is browser self?
  5) segment_usage
    ?
  6) segments
    ?
  7) urls
    Your access url history. Including page title, count and time.
  8) visit_source
    Visiting relation?
  9) visits
    Visiting history?

Browsing history convert to a text file the purpose of this. “urls”(7) table display by DB browser for SQLite then all record select and copy/paste to your favorite text editor or Excel …

Tuesday, April 19, 2016

Linux, how do signal use?

This example explain how do linux signal use sum calls.
Written signal handler function register signals and define behavior signals.
This example use two signals, SIGINT and SIGTSTP.

Program compiling.
$ gcc signal.c -o signal

Program running.
$ ./signal
I'm working...
^CCatch SIGNAL[2]    <-- Ctrl + c key in.
Work harder!              <-- Signal handler message. Don’t stop.
I'm working...
I'm working...
^ZCatch SIGNAL[20]   <-- Ctrl + z key in.
We have a break.        <-- Signal handler message. It’s goiung stop.
I've had enough!
$

signal.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

static void signalHandler(int sig) ;

static int  doit;

int main(int argc, char** argv) {

    struct sigaction   act;

    act.sa_handler = &signalHandler;
    act.sa_flags = 0;
    sigfillset(&act.sa_mask);

    if (sigaction(SIGINT, &act, NULL)<0) {
        perror("SIGINT sigaction()");
        exit(-1);
    }
    if (sigaction(SIGTSTP, &act, NULL)<0) {
        perror("SIGTSTP sigaction()");
        exit(-1);
    }

    doit = 1;

    while(doit) {
        printf("I'm working...\n");
        sleep(1);
    }

    printf("I've had enough!\n");
    return(0);
}

static void signalHandler(int sig) {

    printf("Catch SIGNAL[%d]\n", sig);

    switch(sig) {
        case SIGINT:
            printf("Work harder!\n");
            break;
        case SIGTSTP:
            printf("We have a break.\n");
            doit = 0;         // Quit process working
            break;
        default:
            printf("I don't know.\n");
    }
}


Linux system call fork(), exec(), wait()

This example explains the Linux system call fork(), execl() and wait().
   1) fork() system call duplicate self process image.
       Parent process branch child process and receive child process ID.
   2) Parent process wait child process ending.
      Parent process call wait() while child process doing.
      System call wait() retrieve child process exit code.
      Parent process can judge child process result.
   3) Child process image replace the new image.
      Current image replace /usr/bin/printf image by execl() in this examle.
      execl("/usx/bin/printf", "printf", "Name=%s\\nAge=%d\\n", "Tanaka", "36", NULL);
      --> "printf" is an example, You can execute favorite program.
      If child process fail replacing, when error exit.

Program compiling.
$ gcc fork-exec.c -o fork-exec

Program running.
$ ./fork-exec
Name=Tanaka
Age=36
Child process was normal end.

Chid process exec() can send return code, but it was limited 8bit size.
If you see behavior child process exit, when you try below code changing.

  1) Running program(/usr/bin/printf) error exit.
    Change line 47, execl() parameters 5 “36”  --> “ABC”
    $ ./fork-exec
    Name=Tanaka
    Age=printf: ABC: expected a numeric value
    0
    Error handling example 1.[1]

  2) Current image replacing error.(execl() error)
    Change line 47, execl() parameter 1 "/usr/bin/printf" --> "/usx/bin/printf"
    $ ./fork-exec
    execl(): No such file or directory
    Error handling example 2.[2]

Child process fail execl() when use _exec(). What does exec() differ at _exec()?
You can read Linux man _EXIT(2) NOTES.
The function _exit() is like exit(3), but does not call any functions registered with atexit() or on_exit().

fork-exec.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

static pid_t  childID;

int main(int argc, char** argv) {

    if((childID = fork()) < 0 ) {
        perror("fork()");
        exit(-1);
    }
    else {
        if(childID != 0) {        // Parent process
            int    status, ret;

            waitpid(childID, &status, 0);
            if(WIFEXITED(status)) {
                ret = WEXITSTATUS(status);
                if(ret != 0) {
                    // If you require child process exit code,
                    // You can write judgement code.
                    //   Child process exit status was limited 8bit.
                    // For example.
                    //  
                    ret = WEXITSTATUS(status);
                    if(ret == 1) {                // You can take 00H-FFH
                        // You code.
                        printf("Error handling example 1.[%d]\n", ret);
                    }
                    else {
                        printf("Error handling example 2.[%d]\n", ret);
                    }
                }
                else {
                    printf("Child process was normal end.\n");
                }
            }
            else {
                printf("Child process was fail stopped.\n");
                // ex. Segmentation Failt
            }
        }
        else {                    // Child process
            execl("/usr/bin/printf", "printf", "Name=%s\\nAge=%d\\n", "Tanaka", "36", NULL);
            perror("execl()");
            _exit(2);
        }
    }

    return(0);
}

Monday, April 18, 2016

Linux POSIX mutex an example source.

This example is mutex control with POSIX pthreads.

Linux POSIX example source is not synchronized inter thread.
Thread is able to synchronizing by the mutex. This
example is exclusive std-out on inter-threads.
When compiling source designate link library “libpthread” specify argument “-lpthread”.
$ gcc mutex.c -o mutex -lpthread

If do you watch behavior unsynchronized program, can you add a option with compiling.
$ gcc mutex.c -o mutex -lpthread -DNO_MUTEX

mutex.c

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

pthread_mutex_t mutex;

void* thread(void* arg); // Thread Entry function 1


//
// Main thread.
//
int main(int argc, char **argv) {

    int   ret;

    const char *arg1 = "Pneumonoultramicroscopicsilicovolcanoconiosis, Pneumonoultramicroscopicsilicovolcanoconiosis";
    const char *arg2 = "Supercalifragilisticexpialidocious, Pseudopseudohypoparathyroidism, floccinaucinihilipilification";
    const char *arg3 = "Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon";

    pthread_t thrd1, thrd2, thrd3;
    void *th_ret1, *th_ret2, *th_ret3;

    pthread_mutex_init(&mutex, NULL);

    // Make three threads
    ret = pthread_create(&thrd1, NULL, thread, (void*)arg1);
    if (ret) {
        perror("pthread_create[Thread 1]");
        exit(1);
    }

    ret = pthread_create(&thrd2, NULL, thread, (void*)arg2);
    if (ret) {
        perror("pthread_create[Thread 2]");
        exit(1);
    }

    ret = pthread_create(&thrd3, NULL, thread, (void*)arg3);
    if (ret) {
        perror("pthread_create[Thread 3]");
        exit(1);
    }


    // Waiting threads quit.
    pthread_join(thrd3, &th_ret1);
    pthread_join(thrd2, &th_ret2);
    pthread_join(thrd1, &th_ret3);

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    printf("Thread 3 [%d]\n", *(int*)th_ret1);
    free(th_ret1);                          // Free return value memory.
    printf("Thread 2 [%d]\n", *(int*)th_ret2);
    free(th_ret2);                          // Free return value memory.
    printf("Thread 1 [%d]\n", *(int*)th_ret3);
    free(th_ret3);                          // Free return value memory.

#ifndef NO_MUTEX
    pthread_mutex_unlock(&mutex);
#endif

    pthread_mutex_destroy(&mutex);

    return 0;
}

// Thread entry function
//   The function converts characters from a giving argument string.
void* thread(void* arg) {

    int   i;
    char* c = (char*)arg;
    int*  ret = malloc(sizeof(int));       // Allocate a return value area.

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    for(i=0; i<strlen(c); i++) {
        if (isupper(*(c+i))) {
            printf("%c", (char)tolower(*(c+i)));
        }
        else {
            printf("%c", (char)toupper(*(c+i)));
        }
        usleep(1);
    }
    printf("\n");

#ifndef NO_MUTEX
    pthread_mutex_lock(&mutex);
#endif

    *ret = i;
    pthread_exit(ret);                     // Return value for main thread.
}

Linux POSIX thread an example source.

This example uses POSIX Pthread control calls.
   1) Three new threads create from main thread by pthread_create().
       Main thread give argument, when create a new thread.
   2) Each thread runs own working.
       This example has two thread function.
        1. Timer wait
        2. Character change upper-lower.
   3) Main thread wait other threads complete by pthread_join().
       Created thread make return value and send main thread by pthread_exit().
       Main thread wait and receive child thread return by pthread_join().

This example's return value code memory is using malloc() memory, so must free one in main thread.

When compiling source designate link library “libpthread” specify argument “-lpthread”.

$ gcc pthread.c -o pthread -lpthread

pthread.c

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

void* thread1(void* arg); // Thread Entry function 1
void* thread2(void* arg); // Thread Entry function 2


//
// Main thread.
//
int main(int argc, char **argv) {

    int   ret;

    const char *arg1 = "Tokyo";
    const char *arg2 = "Supercalifragilisticexpialidocious";
    const char *arg3 = "Hokkaido";

    pthread_t thrd1, thrd2, thrd3;
    void* th_ret;

    // Make three threads
    ret = pthread_create(&thrd1, NULL, thread1, (void*)arg1);
    if (ret) {
        perror("pthread_create[Thread 1]");
        exit(1);
    }

    ret = pthread_create(&thrd2, NULL, thread2, (void*)arg2);
    if (ret) {
        perror("pthread_create[Thread 2]");
        exit(1);
    }

    ret = pthread_create(&thrd3, NULL, thread1, (void*)arg3);
    if (ret) {
        perror("pthread_create[Thread 3]");
        exit(1);
    }


    // Waiting threads quit.
    pthread_join(thrd3, &th_ret);
    printf("Thread 3 [%d]\n", *(int*)th_ret);
    free(th_ret);                          // Free return value memory.

    pthread_join(thrd2, &th_ret);
    printf("Thread 2 [%d]\n", *(int*)th_ret);
    free(th_ret);                          // Free return value memory.

    pthread_join(thrd1, &th_ret);
    printf("Thread 1 [%d]\n", *(int*)th_ret);
    free(th_ret);                          // Free return value memory.


    return 0;
}

// Thread entry function 1
//   The function waits from a giving string size.
void* thread1(void* arg) {

    int   t = 0;
    int*  ret = malloc(sizeof(int));       // Allocate a return value area.

    t = strlen((char*)arg);
    sleep( t );
    printf("[%s] %ds\n", (char*)arg, t);

    *ret = t;
    pthread_exit(ret);                     // Return value for main thread.
}

// Thread entry function 2
//   The function converts characters from a giving argument string.
void* thread2(void* arg) {

    int   i;
    char* c = (char*)arg;
    int*  ret = malloc(sizeof(int));       // Allocate a return value area.

    printf("%s --> ", c);
    for(i=0; i<strlen(c); i++) {
        if (isupper(*(c+i))) {
            printf("%c", (char)tolower(*(c+i)));
        }
        else {
            printf("%c", (char)toupper(*(c+i)));
        }
    }
    printf("\n");

    *ret = i;
    pthread_exit(ret);                     // Return value for main thread.
}