Linux - HowardWhile/2023_note GitHub Wiki

Linux

程式之間的通訊

#IPC

#include "arc_console.hpp"

#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdint.h>

typedef struct
{
    int32_t ActualPosition[6]; 
    int32_t ActualVelocity[6]; 
    int16_t ActualTorque[6];   
} Share_Memeber_t;

static int inline createShareMem(key_t share_key)
{
    int shmId = shmget(share_key, sizeof(Share_Memeber_t), IPC_CREAT | 0666);
    if (shmId == -1)
    {
        console("Failed to create shared memory");
        return -1;
    }
    return shmId;
}

static int inline getShareMem(key_t share_key)
{
    int shmId = shmget(share_key, sizeof(Share_Memeber_t), 0666);
    if (shmId == -1)
    {
        console("Failed to get shared memory");
        return -1;
    }
    return shmId;
}

static int inline attachShareMem(int id, Share_Memeber_t **o_mem)
{
    Share_Memeber_t *mem = (Share_Memeber_t *)shmat(id, NULL, 0);
    if (mem == (Share_Memeber_t *)-1)
    {
        console("Failed to attach shared memory");
        return -1;
    }
    *o_mem = mem;
    return 0;
}

static int inline detachShareMem(Share_Memeber_t *mem)
{
    if (shmdt(mem) == -1)
    {
        console("Failed to detach shared memory");
        return -1;
    }
    return 0;
}

static int inline removeShareMem(int share_mem_id)
{
    if (shmctl(share_mem_id, IPC_RMID, NULL) == -1)
    {
        console("Failed to remove shared memory");
        return -1;
    }
    return 0;
}

client

Share_Memeber_t* share_memeber = NULL;

int shared_mem_id = createShareMem(1234);
if (shared_mem_id != -1)
{
    if (attachShareMem(shared_mem_id, &share_memeber) == 0)
    {
        console("create share memrory..." LIGHT_GREEN "succeeded" RESET);
    }
}
...
    
if (share_memeber != NULL)
{
    // deinit share memory
    detachShareMem(share_memeber);
    removeShareMem(shared_mem_id);
}

開關圖形介面

https://www.cnblogs.com/minerw/p/switch-to-tty-on-ubuntu.html

關閉圖形介面

sudo systemctl set-default multi-user.target 
sudo reboot

開啟圖形介面

sudo systemctl set-default graphical.target 
sudo reboot
echo "sudo systemctl set-default multi-user.target " > ~/desktop-disable.sh
echo "sudo reboot" >> ~/desktop-disable.sh
chmod +x ~/desktop-disable.sh

echo "sudo systemctl set-default graphical.target  " > ~/desktop-enable.sh
echo "sudo reboot" >> ~/desktop-enable.sh
chmod +x ~/desktop-enable.sh

Benchmark

sudo apt install sysbench

硬體工具

sudo apt install hardinfo

開機好久

https://magiclen.org/ubuntu-start-job-wait-network/

A start job is running for wait for Network to be configured 卡你兩分鐘

https://caloskao.org/using-netplan-to-configure-ubuntu-nic/

執行 sudo netplan try 套用設定,這時候通常會斷線個幾秒鐘,之後終端機上就會出現一個倒數計時,代表設定正確。這時候再按下 Enter 就會保存設定。

https://blog.csdn.net/qq_43743124/article/details/103804211

改timeout時間

cd /etc/systemd/system/network-online.target.wants/
sudo nano systemd-networkd-wait-online.service

在[Service]下添加TimeoutStartSec=2sec

在这里插入图片描述

可以禁用的服務

test

sudo systemctl stop ufw.service 
sudo systemctl stop snapd.socket snaped.service
sudo systemctl stop ubattended-upgrades.service
sudo systemctl stop avahi-daemon.socket avahi-daemon.service
sudo systemctl stop approt.service

最小安裝的ubuntu server

sudo apt install bash-completion nano net-tools cmake htop screen

LXDE桌面環境設定終端機的快速鍵

https://unix.stackexchange.com/questions/449194/ctrl-alt-t-not-working-in-lubuntu-18-04

https://superuser.com/questions/807047/how-to-add-a-shortcut-key-to-the-terminal-in-lxde

code ~/.config/openbox/lxde-rc.xml

找到<keyboard>...</keyboard>

新增

<keybind key="C-A-t">
  <action name="Execute"><command>lxterminal</command></action>
</keybind>

image-20230301151406937

保存後reconfigure生效

sudo openbox --reconfigure

如何讓系統記得開機選擇的kernel

https://askubuntu.com/questions/148662/how-to-get-grub2-to-remember-last-choice

grub, kernel, 開機選項

code /etc/default/grub
#GRUB_DEFAULT=0
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
sudo update-grub

Real-Time (preempt_rt)

https://wiki.linuxfoundation.org/realtime/documentation/howto/applications/preemptrt_setup

https://blog.csdn.net/qq_28882933/article/details/118293544

https://www.twblogs.net/a/5d8745c4bd9eee5327000981?lang=zh-cn

https://hackmd.io/@oscarshiang/peempt_rt_raspi

https://docs.ros.org/en/humble/Tutorials/Miscellaneous/Building-Realtime-rt_preempt-kernel-for-ROS-2.html#

https://askubuntu.com/questions/1349568/installing-real-time-patch-for-ubuntu-20-04

https://chenna.me/blog/2020/02/23/how-to-setup-preempt-rt-on-ubuntu-18-04/

下載

https://www.kernel.org/pub/linux/kernel/ 例如 linux-5.4.19 kernel from kernel.org and the rt patch

wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.19.tar.xz
wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/5.4/patch-5.4.19-rt11.patch.xz

解壓與patch

xz -cd linux-5.4.19.tar.xz | tar xvf -
cd linux-5.4.19
xzcat ../patch-5.4.19-rt11.patch.xz | patch -p1

config

複製本機的config檔,並且以之為基礎修改成RT kernel的版本

這邊我是先透過mainline將os kernel先換成跟要編譯的kernel版本一樣

cd linux-5.4.19
cp /boot/config-5.3.0-40-generic .config

配置

make oldconfig

主要是提示Preemption Model要修改成Fully Preemptible Kernel如圖:

image-20221202095739944

make menuconfig
# Enable CONFIG_PREEMPT_RT
 -> General Setup
  -> Preemption Model (Fully Preemptible Kernel (Real-Time))
   (X) Fully Preemptible Kernel (Real-Time)

image-20230223154714136

# Enable CONFIG_HIGH_RES_TIMERS
 -> General setup
  -> Timers subsystem
   [*] High Resolution Timer Support

image-20230223155117681

# Enable CONFIG_NO_HZ_FULL
 -> General setup
  -> Timers subsystem
   -> Timer tick handling (Full dynticks system (tickless))
    (X) Full dynticks system (tickless)

image-20230223155017758

# Set CONFIG_HZ_1000 (note: this is no longer in the General Setup menu, go back twice)
 -> Processor type and features
  -> Timer frequency (1000 HZ)
   (X) 1000 HZ

image-20230223155359860

# Set CPU_FREQ_DEFAULT_GOV_PERFORMANCE [=y]
 ->  Power management and ACPI options
  -> CPU Frequency scaling
   -> Default CPUFreq governor
     (X) performance

image-20230223155812191

要修改.config之中的兩個參數

CONFIG_SYSTEM_TRUSTED_KEYS=""

CONFIG_SYSTEM_REVOCATION_KEYS=""

編譯

#make -j8 deb-pkg 

我用deb-pkg編譯打包會出錯誤改用bindeb-pkg則正常

編譯好久 I7-8700 12核心編譯要2個小時

#/bin/bash

now=$(date +%s)sec

make
#date '+%Y-%m-%d %H:%M:%S'

printf "%s\r" $(TZ=UTC date --date now-$now +%H:%M:%S.%N)

編譯環境需要的pkg

apt install make libncurses-dev

make這應該不用解釋

libncurses-dev 使用配置config的指令時make menuconfig會提示缺少

編譯報錯

https://blog.csdn.net/qq_36393978/article/details/118157426

要修改.config之中的兩個參數

CONFIG_SYSTEM_TRUSTED_KEYS CONFIG_SYSTEM_REVOCATION_KEYS

https://blog.csdn.net/qq_36393978/article/details/124274364

sudo apt install dwarves

測試實時性

apt install rt-tests
#cyclictest
cyclictest -p 90 -S

-p: 優先級記得要打

-S: 標準測試

執行緒綁CPU

C/C++ Linux/Unix 讓執行緒跑在指定 CPU 的方法 sched_setaffinity https://shengyu7697.github.io/cpp-sched_setaffinity/

#include <stdio.h>  
#include <sched.h> // for sched_setaffinity()  
#include <unistd.h> // for getpid()  
  
int main() {  
    int cpu_id = 3; // set thread to cpu3  
    cpu_set_t cpuset;  
    CPU_ZERO(&cpuset);  
    CPU_SET(cpu_id, &cpuset);  
  
    printf("sched_setaffinity cpu%d\n", cpu_id);  
    sched_setaffinity(getpid(), sizeof(cpuset), &cpuset);  
  
    printf("sched_getcpu = %d\n", sched_getcpu());  
  
    return 0;  
}

讓linux排除CPU

指定Linux使用CPU核心的數量 Linux如何排除CPU核心 https://unix.stackexchange.com/questions/326579/how-to-ensure-exclusive-cpu-availability-for-a-running-process

sudo gedit /etc/default/grub
GRUB_CMDLINE_LINUX="isolcpus=7"

記得要

sudo update-grub

快照的工具

https://iter01.com/448946.html https://ost.51cto.com/posts/97

sudo apt install timeshift

常用的指令

sudo apt install htop stress glmark2 git net-tools nmap

家目錄資料夾的語言改英文

https://blog.jaycetyle.com/2018/06/ubuntu-home-folder-lang/ https://developer.aliyun.com/article/572028

export LANG=en_US
xdg-user-dirs-gtk-update

同意切換成資料夾路徑名稱 重新啟動後會提示改回中文路徑記得選不同意勾選不再提醒

GRUB 選單怎麼切換回去

https://askubuntu.com/questions/381613/how-to-return-from-grub-prompt-to-the-grub-menu

開機時連按Esc可以跳到切換Kernel的畫面,但是時常會按太快跳到GRUB的命令列...

鍵入「normal」,按下 Enter,然後重複按 Esc 直到菜單顯示。此時按 Esc 不會使你降至 grub 命令提示符(因此不用擔心按太多次)。

其他的桌面環境

https://www.eet-china.com/mp/a10976.html

Ubuntu 22.04打注音

https://ivonblog.com/posts/ubuntu-fcitx5/

Realtime測試

# sudo apt install rt-tests
sudo cyclictest -l 100000 -Sp 99

顯示卡壓力測試

#sudo apt install glmark2
glmark2 --run-forever

CPU RAM 硬體 壓力測試

#sudo apt install stress
stress --cpu 8 --io 4 --vm 8 --vm-bytes 384M

cyclictest & histogram

https://www.osadl.org/Create-a-latency-plot-from-cyclictest-hi.bash-script-for-latency-plot.0.html

建立一個cyclictest-hist-plot.sh

#!/bin/bash

# 1. Run cyclictest
sudo cyclictest -l ${1-10000} -m -Sp99 --policy=fifo -h ${2-400}  -q >output

# 2. Get maximum latency
max=`grep "Max Latencies" output | tr " " "\n" | sort -n | tail -1 | sed s/^0*//`

# 3. Grep data lines, remove empty lines and create a common field separator
grep -v -e "^#" -e "^$" output | tr " " "\t" >histogram

# 4. Set the number of cores, for example
cores=`nproc`

# 5. Create two-column data sets with latency classes and frequency values for each core, for example
for i in `seq 1 $cores`
do
  column=`expr $i + 1`
  cut -f1,$column histogram >histogram$i
done

# 6. Create plot command header
echo -n -e "set title \"Latency plot\"\n\
set terminal png\n\
set xlabel \"Latency (us), max $max us\"\n\
set logscale y\n\
set xrange [0:*]\n\
set yrange [0.8:*]\n\
set ylabel \"Number of latency samples\"\n\
set output \"plot.png\"\n\
plot " >plotcmd

# 7. Append plot command data references
for i in `seq 1 $cores`
do
  if test $i != 1
  then
    echo -n ", " >>plotcmd
  fi
  cpuno=`expr $i - 1`
  if test $cpuno -lt 10
  then
    title=" CPU$cpuno"
   else
    title="CPU$cpuno"
  fi
  echo -n "\"histogram$i\" using 1:2 title \"$title\" with histeps" >>plotcmd
done

# 8. Execute plot command
gnuplot -persist <plotcmd

# 9. Clean temporary file
rm histogram
for i in `seq 1 $cores`
do
 rm histogram$i
done
rm plotcmd

使用範例

cyclictest-hist-plot.sh 
cyclictest-hist-plot.sh 5000 # 5000次循環 (預設值10000)
cyclictest-hist-plot.sh 5000 8 # 8執行緒 (預設值4)
cyclictest-hist-plot.sh 5000 8 10000 # 統計的最大延遲時間 (預設值400 以微秒為單位)
⚠️ **GitHub.com Fallback** ⚠️