顯示具有 Linux Coding 標籤的文章。 顯示所有文章
顯示具有 Linux Coding 標籤的文章。 顯示所有文章

2017年7月12日 星期三

[docker] Build up Linux kernel research environment by using docker/qemu

Download

    $ git clone https://github.com/tinyclub/cloud-lab.git
    $ cd cloud-lab && tools/docker/choose linux-lab

Install

    $ tools/docker/pull        # Pull from docker hub
    or
    $ tools/docker/build       # Build from source

Run

    $ tools/docker/run        # Start to run
[Happy@localhost cloud-lab]$ sudo tools/docker/rm
[sudo] password for Happy: 
LOG: Current Lab is linux-lab
LOG: Running ' docker rm -f linux-lab-27586 '
linux-lab-27586
[Happy@localhost cloud-lab]$ sudo tools/docker/run
LOG: Current Lab is linux-lab
LOG: Wait for lab launching...
LOG: Container ID: 89fadc31d6ae Container Name: linux-lab-28086
LOG: User: ubuntu Password: e9nU1doA7nhtsUA VNC Password: 1tC2ya4RCMRrXXA
LOG: Current Lab is linux-lab
LOG: No chromium-browser found, use firefox instead.
Please login http://localhost:6080/vnc.html?token=2dcb0b51f6f2a6a6800bc33a93dfc210&password=1tC2ya4RCMRrXXA&autoconnect=0&encrypt=0

Connect to Docker by ssh

ssh 172.17.0.3 -l ubuntu

Connect to simulation board

    $ cd /labs/linux-lab
    $ make boot

Get Source Code

    $ make source -j3             # Download linux-stable, qemu 和 buildroot

Reference:

2016年4月16日 星期六

[OS][mini-arm-os] 02-ContextSwitch-1

happy@happy-laptop:/tmp/test/mini-arm-os/02-ContextSwitch-1$ make
arm-none-eabi-gcc -fno-common -ffreestanding -O0 -gdwarf-2 -g3 -Wall -Werror -mcpu=cortex-m3 -mthumb -Wl,-Tos.ld -nostartfiles  os.c startup.c context_switch.S -o os.elf
arm-none-eabi-objcopy -Obinary os.elf os.bin
arm-none-eabi-objdump -S os.elf > os.list

happy@happy-laptop:/tmp/test/mini-arm-os/02-ContextSwitch-1$ make qemu
Press Ctrl-A and then X to exit QEMU

qemu-system-arm -M stm32-p103 -nographic -kernel os.bin
STM32_UART: UART1 clock is set to 0 Hz.
STM32_UART: UART1 BRR set to 0.
STM32_UART: UART1 Baud is set to 0 bits per sec.
STM32_UART: UART2 clock is set to 0 Hz.
STM32_UART: UART2 BRR set to 0.
STM32_UART: UART2 Baud is set to 0 bits per sec.
STM32_UART: UART3 clock is set to 0 Hz.
STM32_UART: UART3 BRR set to 0.
STM32_UART: UART3 Baud is set to 0 bits per sec.
STM32_UART: UART4 clock is set to 0 Hz.
STM32_UART: UART4 BRR set to 0.
STM32_UART: UART4 Baud is set to 0 bits per sec.
STM32_UART: UART5 clock is set to 0 Hz.
STM32_UART: UART5 BRR set to 0.
STM32_UART: UART5 Baud is set to 0 bits per sec.
STM32_UART: UART5 clock is set to 0 Hz.
STM32_UART: UART5 BRR set to 0.
STM32_UART: UART5 Baud is set to 0 bits per sec.
STM32_UART: UART4 clock is set to 0 Hz.
STM32_UART: UART4 BRR set to 0.
STM32_UART: UART4 Baud is set to 0 bits per sec.
STM32_UART: UART3 clock is set to 0 Hz.
STM32_UART: UART3 BRR set to 0.
STM32_UART: UART3 Baud is set to 0 bits per sec.
STM32_UART: UART2 clock is set to 0 Hz.
STM32_UART: UART2 BRR set to 0.
STM32_UART: UART2 Baud is set to 0 bits per sec.
STM32_UART: UART1 clock is set to 0 Hz.
STM32_UART: UART1 BRR set to 0.
STM32_UART: UART1 Baud is set to 0 bits per sec.
LED Off
CLKTREE: HSI Output Change (SrcClk:None InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HSI/2 Output Change (SrcClk:HSI InFreq:8000000 OutFreq:4000000 Mul:1 Div:2 Enabled:1)
CLKTREE: SYSCLK Output Change (SrcClk:HSI InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HCLK Output Change (SrcClk:SYSCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
STM32_RCC: Cortex SYSTICK frequency set to 8000000 Hz (scale set to 125).
STM32_RCC: Cortex SYSTICK ext ref frequency set to 1000000 Hz (scale set to 1000).
CLKTREE: PCLK1 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: PCLK2 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HSE Output Change (SrcClk:None InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HSE/128 Output Change (SrcClk:HSE InFreq:8000000 OutFreq:62500 Mul:1 Div:128 Enabled:1)
CLKTREE: HSE/2 Output Change (SrcClk:HSE InFreq:8000000 OutFreq:4000000 Mul:1 Div:2 Enabled:1)
CLKTREE: PLLXTPRE Output Change (SrcClk:HSE InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: GPIOA Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: AFIO Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: UART2 Output Change (SrcClk:PCLK1 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
STM32_UART: UART2 clock is set to 8000000 Hz.
STM32_UART: UART2 BRR set to 0.
STM32_UART: UART2 Baud is set to 0 bits per sec.
OS Starting...
User Task #1

2016年3月27日 星期日

[Embedded System] Server Framework in modern C

Learning how to use doxygen
  1. Install doxygen in Archlinux
    pacman -S doxygen
  2. get from github
    git clone git@github.com:embedded2016/server-framework.git
  3. To create document
    cd server-framework
    make doc
Vedio:
Reference:

2016年3月17日 星期四

[C] How to memory copy to pointer


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

void main()
{
    char tmp[256] = {'\0'};

    char *go = (char *)malloc(sizeof(char)); // Must assign a space to the pointer of go
    sprintf(tmp,"gogo");

    memcpy(go,tmp,sizeof(tmp));  // memory copy
    printf("%s\n",go);
}


Reference:

2016年3月5日 星期六

[IPC] Using socket to communication with each other


socket_server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>

#define NSTRS       3           /* no. of strings  */
#define ADDRESS     "mysocket"  /* addr to connect */

/*
 * Strings we send to the client.
 */
char *strs[NSTRS] = {
    "This is the first string from the server.\n",
    "This is the second string from the server.\n",
    "This is the third string from the server.\n"
};

main()
{
    char c;
    FILE *fp;
    int fromlen;
    register int i, s, ns, len;
    struct sockaddr_un saun, fsaun;

    /*
     * Get a socket to work with.  This socket will
     * be in the UNIX domain, and will be a
     * stream socket.
     */
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("server: socket");
        exit(1);
    }

    /*
     * Create the address we will be binding to.
     */
    saun.sun_family = AF_UNIX;
    strcpy(saun.sun_path, ADDRESS);

    /*
     * Try to bind the address to the socket.  We
     * unlink the name first so that the bind won't
     * fail.
     *
     * The third argument indicates the "length" of
     * the structure, not just the length of the
     * socket name.
     */
    unlink(ADDRESS);
    len = sizeof(saun.sun_family) + strlen(saun.sun_path);

    if (bind(s, &saun, len) < 0) {
        perror("server: bind");
        exit(1);
    }

    /*
     * Listen on the socket.
     */
    if (listen(s, 5) < 0) {
        perror("server: listen");
        exit(1);
    }

    /*
     * Accept connections.  When we accept one, ns
     * will be connected to the client.  fsaun will
     * contain the address of the client.
     */
    if ((ns = accept(s, &fsaun, &fromlen)) < 0) {
        perror("server: accept");
        exit(1);
    }

    /*
     * We'll use stdio for reading the socket.
     */
    fp = fdopen(ns, "r");

    /*
     * First we send some strings to the client.
     */
    for (i = 0; i < NSTRS; i++)
        send(ns, strs[i], strlen(strs[i]), 0);

    /*
     * Then we read some strings from the client and
     * print them out.
     */
    for (i = 0; i < NSTRS; i++) {
        while ((c = fgetc(fp)) != EOF) {
            putchar(c);

            if (c == '\n')
                break;
        }
    }

    /*
     * We can simply use close() to terminate the
     * connection, since we're done with both sides.
     */
    close(s);

    exit(0);
}


socket_client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>

#define NSTRS       3           /* no. of strings  */
#define ADDRESS     "mysocket"  /* addr to connect */

/*
 * Strings we send to the server.
 */
char *strs[NSTRS] = {
    "This is the first string from the client.\n",
    "This is the second string from the client.\n",
    "This is the third string from the client.\n"
};

main()
{
    char c;
    FILE *fp;
    register int i, s, len;
    struct sockaddr_un saun;

    /*
     * Get a socket to work with.  This socket will
     * be in the UNIX domain, and will be a
     * stream socket.
     */
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("client: socket");
        exit(1);
    }

    /*
     * Create the address we will be connecting to.
     */
    saun.sun_family = AF_UNIX;
    strcpy(saun.sun_path, ADDRESS);

    /*
     * Try to connect to the address.  For this to
     * succeed, the server must already have bound
     * this address, and must have issued a listen()
     * request.
     *
     * The third argument indicates the "length" of
     * the structure, not just the length of the
     * socket name.
     */
    len = sizeof(saun.sun_family) + strlen(saun.sun_path);

    if (connect(s, &saun, len) < 0) {
        perror("client: connect");
        exit(1);
    }

    /*
     * We'll use stdio for reading
     * the socket.
     */
    fp = fdopen(s, "r");

    /*
     * First we read some strings from the server
     * and print them out.
     */
    for (i = 0; i < NSTRS; i++) {
        while ((c = fgetc(fp)) != EOF) {
            putchar(c);

            if (c == '\n')
                break;
        }
    }

    /*
     * Now we send some strings to the server.
     */
    for (i = 0; i < NSTRS; i++)
        send(s, strs[i], strlen(strs[i]), 0);

    /*
     * We can simply use close() to terminate the
     * connection, since we're done with both sides.
     */
    close(s);

    exit(0);
}


Execute :
gcc socket_server.c -o socket_server
gcc socket_client.c -o socket_client


./socket_server
./socket_client
When connection establish, the message will send to each other.


Reference:

2016年3月3日 星期四

[Kernel][Linux] How to write kenel driver

Template of Kernel Code
/* example.c */
#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

static int example_init(void) {
    printk("<1>EXAMPLE: init\n");
    return 0;
}

static void example_exit(void) {
    printk("<1>EXAMPLE: exit\n");
}

module_init(example_init);
module_exit(example_exit);


Makefile
obj-m := example.o

ifeq ($(KERNELDIR),)
KERNELDIR=/lib/modules/$(shell uname -r)/build
endif

all:
    make -C $(KERNELDIR) M=$(PWD) modules

clean:
    make -C $(KERNELDIR) M=$(PWD) clean

$ sudo insmod ./example.ko
$ sudo rmmod example


Use following comamnd to show any message from our kernel.
$ sudo dmesg | tail






Register as Character Device
Add following code into example.c.
#include <linux/fs.h>


static int example_open(struct inode *inode, struct file *filp) {
    printk("<1>EXAMPLE: open\n");
    return 0;
}

static int example_close(struct inode *inode, struct file *filp) {
    printk("<1>EXAMPLE: close\n");
    return 0;
}

static ssize_t example_read(struct file *filp, char *buf, size_t size, loff_t *f_pos) {
    printk("<1>EXAMPLE: read  (size=%zu)\n", size);
    return 0;
}

static ssize_t example_write(struct file *filp, const char *buf, size_t size, loff_t *f_pos) {
    printk("<1>EXAMPLE: write  (size=%zu)\n", size);
    return size;
}

static struct file_operations example_fops = {
    .open = example_open,
    .release = example_close,
    .read = example_read,
    .write = example_write,
};
Change example_init
#define EXAMPLE_MAJOR 60
#define EXAMPLE_NAME "example"

static int example_init(void) {
    int result;
    printk("<1>EXAMPLE: init\n");

    /* Register character device */
    result = register_chrdev(EXAMPLE_MAJOR, EXAMPLE_NAME, &example_fops);
    if (result < 0) {
        printk("<1>EXAMPLE: Failed to register character device\n");
        return result;
    }

    return 0;
}
Change example_exit
static void example_exit(void) {
    printk("<1>EXAMPLE: exit\n");

    /* Unregister character device */
    unregister_chrdev(EXAMPLE_MAJOR, EXAMPLE_NAME);
}
Compile code (example.c)


Remove the example from kernel
$ sudo rmmod example


Insert the kernel
$ sudo insmod ./example.ko


Create a node under /dev
$ sudo mknod /dev/example c 60 0
# /dev/example (the path of file),c represent Character Device,60 (Major ID),0 (Minor ID)。

$ sudo chmod 666 /dev/example (permission - all can read and write)


Write message to /dev/example
$ echo -n 'abcd' > /dev/example


Show message
$ sudo dmesg | tail


Read from user space.
Kernel space and user space have different storage address, so can’t load them directly.
Must use the API of copy_from_user() to read from user space.


Add follow code to modify example.c
#include <asm/uaccess.h>

ssize_t example_write(struct file *filp, const char *buf, size_t size, loff_t *f_pos) {
    size_t pos;
    uint8_t byte;
    printk("<1>EXAMPLE: write  (size=%zu)\n", size);
    for (pos = 0; pos < size; ++pos) {
        if (copy_from_user(&byte, buf + pos, 1) != 0) {
            break;
        }
        printk("<1>EXAMPLE: write  (buf[%zu] = %02x)\n", pos, (unsigned)byte);
    }
    return pos;
}


If data want copy from kernel space to user space must use copy_to_user().


Remove the example from kernel
$ sudo rmmod example


Insert the kernel
$ sudo insmod ./example.ko


Show message
$ sudo dmesg | tail

Reference:

2016年1月14日 星期四

[C] How to check number


char usage[]="Usage: %s [-p port] \n";


     case 'p': /* port number */
      for (cp=optarg; *cp; cp++)
          if (!isdigit((int)*cp)){
              printf("Wrong: port number must be an unsigned integer\n");
              printf(usage,argv[0]);
              exit(1);
          }
      portnum = atoi(optarg);
      break;

2016年1月11日 星期一

[C] Announce multiple structure in one structure

struct exit_function {
        /*
         * 'type' should be of type of the 'enum ef_type' above but since we
         * need this element in an atomic operation we have to use 'long int'.
         */
        long int type; /* enum ef_type */
        union {
                struct {
                        oefuncp func;
                        void *arg;
                } on_exit;
                struct {
                        cxaefuncp func;
                        void *arg;
                        void* dso_handle;
                } cxa_atexit;
        } funcs;
};

Reference:

2016年1月5日 星期二

[C] Use graph to show the structure of C


/* rfc2030
 *                      1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |LI | VN  |Mode |    Stratum    |     Poll      |   Precision   |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                          Root Delay                           |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                       Root Dispersion                         |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                     Reference Identifier                      |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * |                   Reference Timestamp (64)                    |
 * |                                                               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * |                   Originate Timestamp (64)                    |
 * |                                                               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * |                    Receive Timestamp (64)                     |
 * |                                                               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * |                    Transmit Timestamp (64)                    |
 * |                                                               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                 Key Identifier (optional) (32)                |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                                                               |
 * |                                                               |
 * |                 Message Digest (optional) (128)               |
 * |                                                               |
 * |                                                               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */
struct ntpdata {
        u_char status;          /* status of local clock and leap info */
        u_char stratum;         /* Stratum level */
        u_char ppoll;           /* poll value */
        int precision:8;
        struct s_fixedpt root_delay;
        struct s_fixedpt root_dispersion;
        u_int32_t refid;
        struct l_fixedpt ref_timestamp;
        struct l_fixedpt org_timestamp;
        struct l_fixedpt rec_timestamp;
        struct l_fixedpt xmt_timestamp;
        u_int32_t key_id;
        u_int8_t  message_digest[16];
};


Reference :
  • Tcpdump - ntp.h

2015年10月7日 星期三

[C] fputs & fgets


Purpose :
Remove
—–BEGIN CERTIFICATE—–
—–END CERTIFICATE—–
and copy to file.txt

C code

#include <stdio.h>

#define Max_CA_String 128

int main()
{
   FILE *fp, *fpw;
   char str[Max_CA_String];

   /* opening file for reading */
   fp = fopen("/tmp/test/ca.crt" , "r");
   if(fp == NULL) 
   {
       perror("Error opening file");
       return(-1);
   }

   fpw = fopen("/tmp/test/file.txt" , "w");
   if(fpw == NULL) 
   {
       perror("Error opening file");
       return(-1);
   }

   while((fgets (str, Max_CA_String, fp))!= NULL) 
   {
       if ((strstr(str,"BEGIN CERTIFICATE") != NULL) || (strstr(str,"END CERTIFICATE") != NULL))
           continue;
       fputs(str,fpw);
   }
   fclose(fp);
   fclose(fpw);

   return(0);
}

ca.crt
-----BEGIN CERTIFICATE-----
MIIDQzCCAqygAwIBAgIJAOj/t8m56DlHMA0GCSqGSIb3DQEBBQUAMHUxCz
7gjIfkFm3FvchePjijmp66F5pHcwdTELMAkGA1UEBhMCVFcxCzAJBgNVBAgTAlRX
MRAwDgYDVQQHEwdIc2luQ2h1MREwDwYDVQQKEwhQZWdhdHJvbjERMA8GA1UEAxMI
UGVnYXRyb24xITAfBgkqhkiG9w0BCQEWEm1lQG15aG9zdC5teWRvbWFpboIJAOj/
t8m56DlHMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAIZI/R8VJzapg
Nko8/nO93I+/w/7MaWyB7LwDiRXEttnPcBsdE+/Gr+veu+351yCS8p187fTg5ONi
sW+yth0mAIA276DTDOdstdXuAPBVIfFZ2o/bnz+diiQm9qWkwRIzyye/n+wgGA4P
IXw/aBgtRn/NBJgGDmaacAv/2EvZ8PU=
-----END CERTIFICATE-----

2015年10月6日 星期二

[C][important] Copy string to char pointer



#include<stdio.h>

int main()
{
    void *data = NULL;
    char tmpdata[128] = {"\0"};
    char *a = NULL;
    int len = 0;

    sprintf(tmpdata,"HAPPY");

    /*allocate memory to char pointer*/
    a = malloc(128);

    strcpy (a,tmpdata);
    len = (unsigned short) strlen(a);
    data=(void *)a;
    printf("%s %d\n",a ,len);

    /*Free memory*/
    free(a);

    return 0;
}

Result :

HAPPY 5

2015年9月22日 星期二

[C] Creating a Daemon Process in C Language

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
int main(int argc, char* argv[])
{
    FILE *fp= NULL;
    pid_t process_id = 0;
    pid_t sid = 0;
    // Create child process
    process_id = fork();
    // Indication of fork() failure
    if (process_id < 0)
    {
        printf("fork failed!\n");
        // Return failure in exit status
        exit(1);
    }
    // PARENT PROCESS. Need to kill it.
    // Because pid > 0 is entering paraent process.
    // So "exit(0)" tell parent to leave.
    
    if (process_id > 0)
    {
        printf("process_id of child process %d \n", process_id);
        // return success in exit status
        exit(0);
    }
    //unmask the file mode
    umask(0);
    //set new session
    sid = setsid();
    if(sid < 0)
    {
        // Return failure
        exit(1);
    }
    // Change the current working directory to root.
    chdir("/");
    // Close stdin. stdout and stderr
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    // Open a log file in write mode.
    fp = fopen ("/tmp/Log.txt", "w+");
    while (1)
    {
        //Dont block context switches, let the process sleep for some time
        sleep(1);
        fprintf(fp, "Logging info...\n");
        fflush(fp);
        // Implement and call some function that does core work for this daemon.
    }
    fclose(fp);
    return (0);
}

Result :
$ gcc -Wall deamon.c -o deamon
$ sudo ./deamon
process_id of child process 2936
$

When cat /tmp/Log.txt will see the string become more and more.
$ cat /tmp/Log.txt
Logging info...
Logging info...
Logging info...
Logging info...

Reference:

2015年9月18日 星期五

[C] How to use API which in other C code


CFLAGS="-I$(CURDIR)/../../OBJ/include/happy/" \
LDFLAGS="-L$(CURDIR)/../../OBJ/lib/" \
LIBS="-lhappy" \

CFLAGS = where is happy.h
LDFLAGS = Where is happy.so
LIBS = include happy.so

happy.h define into C code.
The example like following code.

#include <stdio.h>
#include <happy.h>

int main()
{
    printf("happy");
}

2015年9月17日 星期四

[C] All example to execute file


        sprintf(&buffer[0], "/etc/openvpn/vpnserver%d --cd /etc/openvpn/server%d --config config.ovpn", serverNum, serverNum);
        vpnlog(VPN_LOG_INFO,"Starting OpenVPN: %s",&buffer[0]);
        for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
        if ( _eval(argv, NULL, 0, &pid) )
        {
                vpnlog(VPN_LOG_ERROR,"Starting VPN instance failed...");
                stop_vpnserver(serverNum);
                return;
        }

        sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
        argv[0] = &buffer[0];
        argv[1] = NULL;
        _eval(argv, NULL, 0, NULL);

        vpnlog(VPN_LOG_EXTRA,"Adding cron job");
        argv[0] = "cru";
        argv[1] = "a";
        sprintf(&buffer[0], "CheckVPNServer%d", serverNum);
        argv[2] = &buffer[0];
        sprintf(&buffer[strlen(&buffer[0])+1], "*/%d * * * * service start_vpnserver%d", nvi, serverNum);
        argv[3] = &buffer[strlen(&buffer[0])+1];
        argv[4] = NULL;
        _eval(argv, NULL, 0, NULL);

        sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
        argv[0] = "sed";
        argv[1] = "-i";
        argv[2] = "s/-A/-D/g;s/-I/-D/g";
        argv[3] = &buffer[0];
        argv[4] = NULL;
        if (!_eval(argv, NULL, 0, NULL))
        {
                argv[0] = &buffer[0];
                argv[1] = NULL;
                _eval(argv, NULL, 0, NULL);
        }

Delete process which create by _eval
void killall_tk(const char *name)
{
    int n;

    if (killall(name, SIGTERM) == 0) {
        n = 10;
        while ((killall(name, 0) == 0) && (n-- > 0)) {
            _dprintf("%s: waiting name=%s n=%d\n", __FUNCTION__, name, n);
            usleep(100 * 1000);
        }
        if (n < 0) {
            n = 10;
            while ((killall(name, SIGKILL) == 0) && (n-- > 0)) {
                _dprintf("%s: SIGKILL name=%s n=%d\n", __FUNCTION__, name, n);
                usleep(100 * 1000);
            }
        }
    }
}


static int ovpn_waitfor(const char *name)
{
    int pid, n = 5;


    killall_tk(name);
    while ( (pid = pidof(name)) >= 0 && (n-- > 0) )
    {
        // Reap the zombie if it has terminated
        waitpid(pid, NULL, WNOHANG);
        sleep(1);
    }
    return (pid >= 0);
}

Reference:

2015年9月2日 星期三

[C] Send message to syslogd


#include<stdio.h>
#include <stdarg.h>
#include <syslog.h>

/*
 *  * logmessage
 *   *
 *    */
void logmessage(char *logheader, char *fmt, ...)
{
  va_list args;
  char buf[512];

  va_start(args, fmt);

  vsnprintf(buf, sizeof(buf), fmt, args);
  openlog(logheader, 0, 0);
  syslog(0, buf);
  closelog();
  va_end(args);
}

int main()
{
    logmessage("HAHA", "write error : %s\n", "happy");    
}

Test :
journalctl | grep happy
Sep 02 19:32:50 freeman HAHA[6738]: write error : happy

Reference:

[C] Concatenate two strings together into a buffer

c.h
/*
 *  * Concatenate two strings together into a buffer
 *  * @param       s1      first string
 *  * @param       s2      second string
 *  * @param       buf     buffer large enough to hold both strings
 *  * @return      buf
 *  */
static inline char * strcat_k(const char *s1, const char *s2, char *buf)
{
        strcpy(buf, s1);
        strcat(buf, s2);
        return buf;
}

c.c
#include<stdio.h>
#include <string.h>
#include "c.h"
int main()
{
    char buf[128];   

    strcat_k("happy_","GOOD",buf);
    printf("%s \n",buf);
    return 0;

}

Result:
happy_GOOD


Reference:

2015年9月1日 星期二

2015年8月26日 星期三

2015年8月23日 星期日

[Operation System] Learn how to build mini-arm-os and understand it

Preparation to build environment for jserv/mini-arm-os
Download python (2.7.10)

Archlinux :
pacman -S --noconfirm gcc # The GNU Compiler Collection - C and C++ frontends
pacman -S --noconfirm pkg-config # A system for managing library compile/link flags
pacman -S --noconfirm pixman # The pixel-manipulation library for X and cairo
pacman -S --noconfirm dtc # Open Firmware device tree compiler
pacman -S --noconfirm git # version control system
pacman -S --noconfirm lib32-glibc # GNU C Library (32-bit)

Ubuntu :
sudo apt-get install glibc* gthread* gcc dtc


Start to build:
Download QEMU with an STM32 microcontroller implementation (tar.gz)
git clone git://github.com/beckus/qemu_stm32.git
cd qemu_stm32
git submodule update --init dtc
./configure --disable-werror --enable-debug \
    --target-list="arm-softmmu" \
    --extra-cflags=-DDEBUG_CLKTREE \
    --extra-cflags=-DDEBUG_STM32_RCC \
    --extra-cflags=-DDEBUG_STM32_UART \
    --extra-cflags=-DSTM32_UART_NO_BAUD_DELAY \
    --extra-cflags=-DSTM32_UART_ENABLE_OVERRUN \
    --disable-gtk

make
sudo make install



Download GCC for ARM(Download Point - gcc arm embedded)

Set the path of gcc compile tool
PATH=/tmp/test/gcc-arm-none-eabi-5_3-2016q1/bin:$PATH

Reference:

Cross-Compiler: gcc-arm-none-eabi-5_4-2016q2-20160622-linux.tar.bz2

Download mini-arm-os
git clone https://github.com/jserv/mini-arm-os.git

cd /home/happy/test/mini-arm-os/00-HelloWorld
make

Result:

arm-none-eabi-gcc -fno-common -O0 -mcpu=cortex-m3 -mthumb -T hello.ld -nostartfiles  hello.c startup.c -o hello.elf

arm-none-eabi-objcopy -Obinary hello.elf hello.bin

arm-none-eabi-objdump -S hello.elf > hello.list


make qemu
Result :

STM32_UART: UART3 Baud is set to 0 bits per sec.
STM32_UART: UART2 clock is set to 0 Hz.
STM32_UART: UART2 BRR set to 0.
STM32_UART: UART2 Baud is set to 0 bits per sec.
STM32_UART: UART1 clock is set to 0 Hz.
STM32_UART: UART1 BRR set to 0.
STM32_UART: UART1 Baud is set to 0 bits per sec.
LED Off
CLKTREE: HSI Output Change (SrcClk:None InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HSI/2 Output Change (SrcClk:HSI InFreq:8000000 OutFreq:4000000 Mul:1 Div:2 Enabled:1)
CLKTREE: SYSCLK Output Change (SrcClk:HSI InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: HCLK Output Change (SrcClk:SYSCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
STM32_RCC: Cortex SYSTICK frequency set to 8000000 Hz (scale set to 125).
STM32_RCC: Cortex SYSTICK ext ref frequency set to 1000000 Hz (scale set to 1000).
CLKTREE: PCLK1 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: PCLK2 Output Change (SrcClk:HCLK InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: GPIOA Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: AFIO Output Change (SrcClk:PCLK2 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
CLKTREE: UART2 Output Change (SrcClk:PCLK1 InFreq:8000000 OutFreq:8000000 Mul:1 Div:1 Enabled:1)
STM32_UART: UART2 clock is set to 8000000 Hz.
STM32_UART: UART2 BRR set to 0.
STM32_UART: UART2 Baud is set to 0 bits per sec.
Hello World!


Next Chapter: [OS][mini-arm-os] 02-ContextSwitch-1

Reference:

[C] swap by using bitwise operation

#include <stdio.h>
void swap(int *a,int *b){
    int t ;
    t= *a;
    *a=*b;
    *b=t;
}

void swap1(int *a,int *b){
    printf("a = %d ,b = %d\n",*a,*b);
    *a = *a ^ *b;
    printf("a = %d ,b = %d\n",*a,*b);
    *b = *a ^ *b;
    printf("a = %d ,b = %d\n",*a,*b);
    *a = *a ^ *b;
    printf("a = %d ,b = %d\n",*a,*b);
}

int main()
{
    int a = 2, b = 3;
    printf("%d , %d \n",a,b);
    swap1(&a,&b);
    printf("%d , %d \n",a,b);
}

Result :
2 , 3 
a = 2 ,b = 3
a = 1 ,b = 3
a = 1 ,b = 2
a = 3 ,b = 2
3 , 2 

Reference: