|Design| Communicate with Kernel driver

User space can not exchange data with kernel space directly.
They need to use system call.
e.g. fopen, ioctl, write, read …… etc.

In Kernel Space ……
1. Register your device with “register_chrdev”, defined in linux/fs.h .
 https://ithelp.ithome.com.tw/articles/10159749
2. Implement driver functions, ioctl, open,…
 struct file_operations fops = {
  .owner = THIS_MODULE,
  .read = device1_read,
  .write = device1_write,
  .ioctl = device1_ioctl,
  .open = device1_open,
  .release = device1_release,
 };

 int ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 is in linux/ioctl.h
 http://ccckmit.wikidot.com/lk:io
 開發 driver 需要的基礎知識
 user space/kernel space 的IO觀念及實作

Copy data ……
 Kernel Space to User Space: copy_to_user()
 User Space to Kernel Space: copy_from_user()

In User Space ……
Use system call to control kernel driver.
 fopen (open)
 write
 read
 close
 seek
 poll / select
 ioctl
 mmap
 fcntl


e.g.

int main(int argc, char *argv[]){
  int devfd;
  int num = 0;

  if (argc > 1) num = atoi(argv[1]);
  if (num < 0) num = 0xff;

  devfd = open("/dev/debug", O_RDONLY);
  if (devfd == -1) {
    printf("Can't open /dev/debug\n");
    return -1;
  }

  printf("Write 0x%02x...\n", num);
  ioctl(devfd, IOCTL_WRITE, num);
  printf("Done. Wait 5 seconds...\n");
  sleep(5);
  close(devfd);

  return 0;
}

|Code| IPC methods

Originally, I though it is a basic interview question and everyone has at least a common answer .
Until I found someone did not know , I know I was wrong.

Threads can shares the same resources such as address space, file descriptors, stack and other process related attributes in the same process.
Processes can not share resources directly.

Processes will communicate to each other by IPC method.
There are two ways:
 1. Shared Memory
 2. Message passing

The following methods, which we often see, belong to message passing.
Pipe
Socket
Remote Procedural calls (RPCs)



https://www.geeksforgeeks.org/inter-process-communication-ipc/
https://stackoverflow.com/questions/200469/what-is-the-difference-between-a-process-and-a-thread

|Code| Makefile -I -L -l

e.g.
gcc -o hello hello.c -I /home/hello/include -L /home/hello/lib -lworld


Means:
-I /home/hello/include
Find headers in sequence of /home/hello/include–>/usr/include–>/usr/local/include

-L /home/hello/lib:
Find librarys in sequence of /home/hello/lib–>/lib–>/usr/lib–>/usr/local/lib

-lworld:
Find the library “libworld.so” in the path of “-L /home/hello/lib “

|Code| How to use control flow by pthread_cond_timedwait()

There are three parameters related with pthread_cond_timedwait().

Definition:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);

Parameters:
pthread_cond_t *restrict cond : the condition you want to trigger this flow
pthread_mutex_t *restrict mutex : Mutual exclusion
const struct timespec *restrict abstime : absolutely waiting time ( = system time + waiting



【Step by Step】

Initial the mutex:
1. pthread_mutex_init(pthread_mutex_t *restrict  __mutex ,
              const pthread_mutexattr_t *restrict __mutex_attr);
   __mutex_attr can be NULL.
   __mutex_attr is the parameter about mutex.
  If it is not NULL, go to “2.”

2. pthread_mutexattr_init(pthread_mutexattr_t * __mutex_attr );
 pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
   type: PTHREAD_MUTEX_RECURSIVE,
      PTHREAD_MUTEX_NORMAL ……
3. pthread_cond_init(pthread_cond_t *restrict __cond ,
const pthread_condattr_t *restrict __cond_attr);

Start to wait for signal ” __cond “:
1. lock mutex: pthread_mutex_lock(&__mutex)
2. pthread_cond_timedwait(&__cond, &__mutex, &__abstime)
3. unlock mutex: pthread_mutex_unlock(&__mutex)

Start to send the signal ” __cond “:
1. lock mutex: pthread_mutex_lock(&__mutex)
2. pthread_cond_signal (&__cond)
3. unlock mutex: pthread_mutex_unlock(&__mutex)

Destroy the mutex:
1. pthread_mutex_destroy( pthread_mutex_t *restrict  __mutex );
2. pthread_mutexattr_destroy( pthread_mutexattr_t * __mutex_attr );
3. pthread_cond_destroy( pthread_cond_t *restrict __cond );

E.g.

// This thread will wait the signal.
void thread1(void *arg){
 int inArg = (int)arg;
 int ret = 0;
 struct timeval now;
 struct timespec outtime;

 pthread_mutex_lock(&g_mutex);

 gettimeofday(&now, NULL);
 outtime.tv_sec = now.tv_sec + 5;
 outtime.tv_nsec = now.tv_usec * 1000;
 ret = pthread_cond_timedwait(&g_cond, &g_mutex, &outtime);

 pthread_mutex_unlock(&g_mutex);
}


int main(void)
{
 pthread_t id1;
 int ret;

 // Initial mutex
 pthread_cond_init(&g_cond, NULL);
 pthread_mutex_init(&g_mutex, NULL);
 ret = pthread_create(&id1, NULL, (void *)thread1, (void *)1);

 if (0 != ret){
  printf(“thread 1 create failed!\n”);
  return 1;
 }

 printf(“Waiting %ds send the signal!\n”, SENDSIGTIME);
 sleep(SENDSIGTIME);

 // send the signal
 pthread_mutex_lock(&g_mutex);
 pthread_cond_signal(&g_cond);
 pthread_mutex_unlock(&g_mutex);
 pthread_join(id1, NULL);

 //Destroy the mutex
 pthread_cond_destroy(&g_cond);
 pthread_mutex_destroy(&g_mutex);
 return 0;
}

References:
https://blog.csdn.net/dead_g/article/details/73338960
https://linux.die.net/man/3/pthread_cond_timedwait
https://linux.die.net/man/3/pthread_cond_init
https://blog.csdn.net/yasi_xi/article/details/19112077

|Design| bit map

如果你的某個宣告有多重意義,
但你一次只想知道某的欄位的狀態,可以善加利用 bit map

舉例:

#define status1 (uint_8) 1<<0
#define status2 (uint_8) 1<<1
#define status3 (uint_8) 1<<2

uint_8 test_case = 2;
int test_hex_case = 0xFA;

If( test_case & status1 ){ // false; 00000000 <- 00000010 & 00000001
  //do nothing
}
If( test_case & status2 ){ // true, not zero; 00000010 <- 00000010 & 00000010
  //do something
}
If( test_hex_case & status2 ){ // true, not zero;
// 0xFA = 1111 1010
// 00000010 <- 1111 1010 & 00000010
  // do something
}

|Jobs| 利用 Samba 建立虛擬機與本機共享資料夾

環境
虛擬機:Virtual Box
主系統:Windows 10
子系統:Ubuntu 18.04

假設你網卡已經設定好且能在虛擬機利用主系統網路上網!
以下開始設定 Samba 共享資料夾!

Part 1. 在子系統的 Ununtu 裡面
Step 1. 固定子系統的 IP
    ifconfig
    找到 host-only 網路的那張網卡,設定固定 IP!
    因為 host-only 預設網段是192.168.56.0,
    因此 IP 設定上也要在同一個網段之下。
    sudo gedit /etc/network/interfaces
     auto 網卡名稱
     iface 網卡名稱 inet static
     address host-only網卡的IP
     netmask 255.255.255.0
     network 192.168.56.0

    reboot

Step 2. 安裝與設定 Samba
    sudo apt-get install samba smbclien    
    sudo gedit /etc/samba/smb.conf
     加入以下設定
      [Share]
      path = /
      public = yes
      writable = yes
      read only = no
      valid users = YOURNAME
      force create mode = 777
      create mask = 0777
      directory mask = 0777
      delete readonly = yes
      guest ok = yes
      available = yes
      browseable = yes

Step 3. 設定從 Windows 登入的密碼
     sudo smbpasswd -a YOURNAME

Step 4. 測試/etc/samba/smb.conf是否有問題
     sudo testparm

Step 5. 重啟Samba,使以上設定生效
    sudo /etc/init.d/smbd restart


Part 2. 在主系統的 Windows
Step 1. Ping 一下 Ubuntu
     ping host-only網卡的IP

Step 2. 到本機點右鍵
    連線到網路磁碟機,輸入 host-only網卡的IP
    記得兩個勾勾都要勾哦!
    讓它能用其他方式連線(程式自己會去找)

以上,感謝同事支援,之前我都直接用 Native Linux。

|Design| C++ getInstance

如果你要獲取特定的物件

就可以使用 getInstance()

這樣比全域變數看起來舒心一點

e.g. ————————————————————————

// test.h
class SomeService
{
public:
static SomeService &GetInstance();

}

// test.cpp
SomeService& SomeService::GetInstance()
{
static SomeService instance;
return instance;
}

————————————————————————


Ref. https://blog.csdn.net/fanyunda1988/article/details/51516930

WordPress.com.

Up ↑