Skip to content
Wei-Lun edited this page Jun 30, 2023 · 8 revisions
typedef struct sh_io_desc
{
    int (*sh_read)();
    int (*sh_write)();
} sh_io_desc_t;

void foo()
{
    union {
        uint32_t   value;
        float      fvalue;
    } v;
    
    v.fvalue = 3.14;
    printf("%d\n", v.value);

}
#include <conio.h>
int main()
{
    while(1)
    {
        char   c = getch();
        putc(c, stdout);
    }
    return 0;
}
// ARM 3-cycles per count
static inline void delay(uint32_t count) 
{
    asm volatile(
        "1: \n\t"
        "sub %0, %0, #1 \n\t"
        "bne 1b"
        : "+r" (count)
    );
}
typedef struct broadcast_upgrade
{
    uint32_t        tftp_mac_addr;
    uint32_t        dhcp_mac_addr;

    /**
     *  compare image version if need upgrade
     */
    uint32_t        img_version;

    /**
     *  if get IP fail from dhcp server
     */
    uint32_t        wait_time_gap_sec;

} broadcast_upgrade_t;

typedef struct img
{
    uint32_t    magic;
    uint32_t    length;
    uint8_t     data[n];
    uint32_t    crc32;

} img_t;


#if defined(__linux__)
#define pause()     do { printf("Press Enter key to continue..."); fgetc(stdin);} while(0)
#else
#define pause()     system("pause")
#endif
void HardFault_Handler(void)
{
    /* Go to infinite loop when Hard Fault exception occurs */
    __asm(" nop");
    __asm(" BX lr");
}
static void
_hexdump(unsigned char *data, int cnt)
{
    int run;
    int offset;

    offset = 0;
    while (cnt) {
        printf ("%04X : ", offset);
        if (cnt >= 16)
            run = 16;
        else
            run = cnt;
        cnt -= run;
        for (int i = 0; i < run; i++)
            printf ("%02X ", (unsigned int) data[i]);
        printf (": ");
        for (int i = 0; i < run; i++)
            printf ("%c", (data[i] >= 32 && data[i] < 127) ? data[i] : '.');
        printf ("\n");
        data = &data[16];
        offset += run;
    }
}
void print_binary(unsigned int number)
{
    if (number >> 1) {
        print_binary(number >> 1);
    }
    putc((number & 1) ? '1' : '0', stdout);
}
void LogHex(uint32_t val)
{
    uint32_t    zero = 1;

    for(uint32_t i = 8; i != 0; i--)
    {
        uint8_t     c = val >> 28;

        if( !zero || i == 1 || c != 0 )
        {
            zero = 0;

            if( c < 0xa )   c += '0';
            else            c += 'A' - 0xa;

            __putc(c);
        }

        val <<= 4;
    }

    return;
}
static void
dump_mem(
    char                *prefix,
    uint8_t             *pAddr,
    int                 bytes,
    unsigned int        has_out_u32le)
{
    if( has_out_u32le )
    {
        uintptr_t   addr = (uintptr_t)pAddr;
        uint32_t    cnt = (bytes + 0x3) >> 2;
        uint32_t    *pCur = (uint32_t*)pAddr;

        for(int i = 0; i < cnt; i++)
        {
            if( (i & 0x3) == 2 )
                printf(" -");
            else if( !(i & 0x3) )
            {
                printf("\n%s%08X |", prefix, addr);
                addr += 16;
            }

            printf(" %08X", pCur[i]);
        }
        printf("\n\n");
    }
    else
    {
    #if 1
        uintptr_t   addr = (uintptr_t)pAddr;
        uint8_t     *pCur = pAddr;

        for(int i = 0; i < bytes; i++)
        {
            if( (i & 0xF) == 8 )
                printf(" -");
            else if( !(i & 0xF) )
            {
                printf("\n%s%08X |", prefix, addr);
                addr += 16;
            }

            printf(" %02X", pCur[i]);
        }
        printf("\n\n");
    #else

        int         i = 0;
        size_t      length = bytes;
        size_t      line_size = 16;
        uint8_t     *addr = pAddr;
        uint8_t     *line = addr;
        uint8_t     c;

        printf("%s%08X | ", prefix, (uintptr_t)addr);
        while( length-- > 0 )
        {
            if( (i & 0xF) == 8 )
                printf("- ");

            printf("%02X ", *addr++);
            if( !(++i % line_size) || (length == 0 && i % line_size) )
            {
                if( length == 0 )
                {
                    while( i++ % line_size )
                    {
                        if( (((i-1) % line_size) & 0xF) == 8 )
                            printf("- ");
                        printf("__ ");
                    }
                }

                printf(" | ");  /* right close */
                while( line < addr )
                {
                    c = *line++;
                    printf("%c", (c < 33 || c == 255) ? 0x2E : c);
                }

                printf("\n");

                if( length > 0 )
                    printf("%s%08X | ", prefix, (uintptr_t)addr);
            }
        }
    #endif // 0
    }

    return;
}
static inline int __ssat_sw(int32_t VAL, int32_t BITPOS)
{
    int32_t min = -(1 << (BITPOS - 1));
    int32_t max = (1 << (BITPOS - 1)) - 1;

    return (VAL < min) ? min :
           (VAL > max) ? max :
           VAL;
}
#define __SSAT(VAL, BITPOS)     __ssat_sw(VAL,BITPOS)
int _clz_sw(uint32_t x)
{
    int n = 0;
    if (x == 0) return 32;
    if (x <= 0x0000FFFF) { n += 16; x <<= 16; }
    if (x <= 0x00FFFFFF) { n += 8; x <<= 8; }
    if (x <= 0x0FFFFFFF) { n += 4; x <<= 4; }
    if (x <= 0x3FFFFFFF) { n += 2; x <<= 2; }
    if (x <= 0x7FFFFFFF) { n += 1; x <<= 1; }
    return n;
}
#define __CLZ(x)    _clz_sw(x)
$ grep -A 1 '^[a-fA-F0-9]* | ' ./data_patt.txt | awk -F'|' '{print $2}' | sed -e :x -e 'N; s/\n//; tx'
# rm all white spaces and blanks
$ cat tmp.h | tr -d " \t\n\r" > _tmp.h
#!/bin/bash
###
# mbed_setup_build.sh
set -e

pip install mbed-cli

# mbed import mbed-os-example-blinky
mbed import mbed-bootloader

mbed config root .

# mbed compile -t GCC_ARM -m K64F --profile=tiny.json
mbed compile -t GCC_ARM -m NUCLEO_F429ZI --profile=tiny.json


# [reference](https://www.twblogs.net/a/5bb2add12b71770e645e0c95)
# [reference](https://www.jianshu.com/p/900911a91a09)
$ repo init -u ssh://[email protected]:42985/system/manifest -b master -m a/sdk_full.xml # --depth=1
$ repo sync
$ repo start test/master --all
## convert
# objcopy --readonly-text -I binary -O elf32-i386 -B i386 jpg.jpg jpg.o

## insert section
# objcopy -I elf32-i386 --add-section .mydata=jpg.o --set-section-flags .mydata=noload,readonly rom.elf

## dump section
objcopy -I elf32-i386 -O binary --dump-section .mydata=mydata.bin rom.elf
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)

set(CMAKE_C_FLAGS_RELEASE "-std-gnu++0x")
set(CMAKE_CXX_FLAGS_RELEASE "-std=gnu99")


find_program(CMAKE_C_COMPILER NAMES gcc)
find_program(CMAKE_CXX_COMPILER NAMES g++)

set(CMAKE_FIND_ROOT_PATH /usr/bin)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

++*p, *p++和 *++p的不同

++*p、*p++和 *++p是由 postfix ++(++在後)、prefix ++(++在前)和 *(deference)運算子組合而成, 其運算優先權與關聯性為:

  • prefix ++與 *的運算優先權相同, 關聯性為從右到左.
  • postfix ++的運算優先權高於 prefix ++與 *, 關聯性為從左到右.

++*p

因 prefix ++與 *的運算優先權相同, 因此從右到左, 可視為是 ++(*p), 將指標 p取值後加 1, 結果為 v = 11, array[0] = 11, array[1] = 20, *p = 11.

#include <stdio.h>

int main() {
  int array[] = { 10, 20};
  int *p = array;
  int v = ++*p;
  printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
  return 0;
}

*p++

因 postfix ++的運算優先權高於 *, 可視為是 *(p++), 將指標 p加 1, 因為是 postfix, 所以取的值為指標 p加 1之前所指向的值, 結果為 v = 10, array[0] = 10, array[1] = 20, *p = 20.

#include <stdio.h>

int main() {
  int array[] = { 10, 20};
  int *p = array;
  int v = *p++;
  printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
  return 0;
}

*++p

因 prefix ++與 *的運算優先權相同, 因此從右到左, 可視為是 *(++p), 將指標 p加 1後取值, 結果為 v = 20, array[0] = 10, array[1] = 20, *p = 20.

#include <stdio.h>

int main() {
  int array[] = { 10, 20};
  int *p = array;
  int v = *++p;
  printf("v = %d, array[0] = %d, array[1] = %d, *p = %d\n", v, array[0], array[1], *p);
  return 0;
}

Note

遇到 postfix ++的情況, 可視為在執行完; 之後, 才會執行 ++的運算.

Putting bash script in C program

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BASH_OUT_NAME       "t.sh"
int main()
{
    FILE    *fout = 0;
    char    bash_script[512] = {0};
    snprintf(bash_script, sizeof(bash_script), "%s",
             "ls -l && echo gggg && echo dddddd");
    system(bash_script);

    fout = fopen(BASH_OUT_NAME, "wb");
    fwrite(bash_script, 1, strlen(bash_script), fout);
    fclose(fout);

    system("bash " BASH_OUT_NAME);
    return 0;
}
- Error in command line "The system cannot find the path specified."

    1. Open the Registry Editor (press 'win+R', type 'regedit' and hit 'Enter') .
    2. Navigate to HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun and clear the values.
    3. Also check HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun

Linux command to compare all files in two directories

$ diff -qr dirA dirB |grep -v -e keyword1 -e keyword2 |sort > diffs.txt
  • diff -r : recursively compare all files and files in subdirectories

  • diff -q : output only whether files differ

  • |grep -e : grep multiple keywords in one command

  • |grep -v : inverse grep, catch the lines not containing keywords (只秀不包含 keyword)

  • |sort : sort the result

Samba

  • smb.conf
    [global]
        ...
        map archive = false
    

zephyr project (BLE)

$ sudo apt install -y ninga-build device-tree-compiler dfu-util python3-pip libssl-dev
$ wget https://github.com/Kitware/CMake/releases/download/v3.15.2/cmake-3.15.2.tar.gz
$ tar -zxvf cmake-3.15.2.tar.gz
$ cd cmake-3.15.2
$ ./bootstrap
$ make
$ sudo make install
$ pip3 install --user -r scripts/requirements.txt

$ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.11.3/zephyr-sdk-0.11.3-setup.run
$ chmod +x zephyr-sdk-0.11.3-setup.run
$ ./zephyr-sdk-0.11.3-setup.run -- -d ~/zephyr-sdk-0.11.3

$ cd zephyr
$ source ./zephyr-env.sh

$ cd samples/hello_world
$ mkdir build && cd build
$ cmake -GNinja -DBOARD=qemu_cortex_m3 ..
$ ninja
Clone this wiki locally