chrony를 이용한 로컬 네트웍 기기 간 시간 동기화

리눅스 시스템에서 시간 동기화를 위해 ntp를 많이 사용한다. ntp를 이용하여 기기간 시간 동기화를 할 수도 있고, 인터넷에 많은 방법이 나와 있다.

chrony는 ntp의 개선 버전이다. 사용 방법도 ntp와 유사하고, 심지어 ntp와 호환도 된다.

로봇 시스템의 특성상 인터넷에 연결되어 있지 않고, 로컬 네트웍 망만 구축되어 있는 경우, 하나의 PC를 기준으로 삼아 다른 기기의 시간을 동기화 할 수 있다.

작업 순서


기준 PC

chrony 설치

$ sudo apt install chrony

서버 설정

$ sudo vi /etc/chrony/chrony.conf 

pool <기준PC IP주소> iburst maxsources 1

keyfile /etc/chrony/chrony.keys
driftfile /var/lib/chrony/chrony.drift

local stratum 10
allow 192.168.0.0/16

logdir /var/log/chrony
maxupdateskew 100.0
rtcsync
makestep 1 3

chrony 데몬 서비스 시작

$ sudo systemctl restart chronyd.service

chrony 서비스 시작

$ sudo systemctl restart chrony.service

chrony 서비스 동작 확인

$ watch chronyc tracking

Every 2.0s: chronyc tracking

Reference ID    : C0A80B36 (byeongkyu-XPS-17-9700)
Stratum         : 11
Ref time (UTC)  : Wed Apr 14 06:19:50 2021
System time     : 0.000000000 seconds slow of NTP time
Last offset     : +0.000002941 seconds
RMS offset      : 0.000002941 seconds
Frequency       : 7.161 ppm slow
Residual freq   : -0.063 ppm
Skew            : 9.612 ppm
Root delay      : 0.000010132 seconds
Root dispersion : 0.000493094 seconds
Update interval : 0.0 seconds
Leap status     : Normal


슬레이브 PC

chrony 설치는 동일.

설정파일

$ sudo vi /etc/chrony/chrony.conf

pool <기준PC IP주소> iburst maxsources 1

keyfile /etc/chrony/chrony.keys
driftfile /var/lib/chrony/chrony.drift

logdir /var/log/chrony
maxupdateskew 100.0
rtcsync
makestep 1 3

chrony 데몬 서비스 시작

$ sudo systemctl restart chrony.service

chrony 동작 확인

$ watch chronyc tracking

Every 2.0s: chronyc tracking
 
Reference ID    : C0A80B36 (192.168.11.54)
Stratum         : 12
Ref time (UTC)  : Wed Apr 14 06:26:28 2021
System time     : 0.000805050 seconds fast of NTP time
Last offset     : +0.001296174 seconds
RMS offset      : 0.005739228 seconds
Frequency       : 2.246 ppm slow
Residual freq   : +0.130 ppm
Skew            : 2.884 ppm
Root delay      : 0.009987777 seconds
Root dispersion : 0.003204302 seconds
Update interval : 260.5 seconds
Leap status     : Normal

끝.!

screen 사용 방법 정리

원격의 로봇에 ssh로 접속하여 작업을 수행할 경우,

  • 여러 개의 터미널이 필요하다면?
  • 어떤 작업을 수행해 놓고, ssh 접속을 끊고 싶다면? (물론 작업은 계속 수행하도록)

여러개의 터미널은 tmux로도 해결이 가능하지만, 작업을 수행해 놓고 ssh 접속만 끊고 싶다면 screen이 해결 방법이 될 수 있음.

설치

$ sudo apt install screen

별다른 설정은 필요하지 않고, 단순히 명령만 입력하면 실행. 옵션이 다음과 같이 있지만, 몇 개만 알면 사용하는데는 문제 없음.

$ screen -h
 Use: screen [-opts] [cmd [args]]
  or: screen -r [host.tty]
 Options:
 -4            Resolve hostnames only to IPv4 addresses.
 -6            Resolve hostnames only to IPv6 addresses.
 -a            Force all capabilities into each window's termcap.
 -A -[r|R]     Adapt all windows to the new display width & height.
 -c file       Read configuration file instead of '.screenrc'.
 -d (-r)       Detach the elsewhere running screen (and reattach here).
 -dmS name     Start as daemon: Screen session in detached mode.
 -D (-r)       Detach and logout remote (and reattach here).
 -D -RR        Do whatever is needed to get a screen session.
 -e xy         Change command characters.
 -f            Flow control on, -fn = off, -fa = auto.
 -h lines      Set the size of the scrollback history buffer.
 -i            Interrupt output sooner when flow control is on.
 -l            Login mode on (update /var/run/utmp), -ln = off.
 -ls [match]   or
 -list         Do nothing, just list our SockDir [on possible matches].
 -L            Turn on output logging.
 -Logfile file Set logfile name.
 -m            ignore $STY variable, do create a new screen session.
 -O            Choose optimal output rather than exact vt100 emulation.
 -p window     Preselect the named window if it exists.
 -q            Quiet startup. Exits with non-zero return code if unsuccessful.
 -Q            Commands will send the response to the stdout of the querying process.
 -r [session]  Reattach to a detached screen process.
 -R            Reattach if possible, otherwise start a new session.
 -s shell      Shell to execute rather than $SHELL.
 -S sockname   Name this session .sockname instead of ...
 -t title      Set title. (window's name).
 -T term       Use term as $TERM for windows, rather than "screen".
 -U            Tell screen to use UTF-8 encoding.
 -v            Print "Screen version 4.08.00 (GNU) 05-Feb-20".
 -wipe [match] Do nothing, just clean up SockDir [on possible matches].
 -x            Attach to a not detached screen. (Multi display mode).
 -X            Execute  as a screen command in the specified session.

실행시 screen 세션 이름 설정하기. 기본으로 부여되는 이름이 있지만 외우기 어려우므로, 사용자가 직접 지정 가능.

$ screen -S <session-name>

실행되어 있는 상태에서 세션과의 연결 끊기

Ctrl + A, d

실행되어 있는 세션에 다시 연결하기

$ screen -r <session-name>

실행되어 있는 세션 리스트 보기

$ screen -ls

팁.

screen를 실행해서 들어가면, 터미널 설정이 변경되어 PS1이 리셋되는 현상이 있는데, 이를 방지하려면 ~/.screenrc 파일에 다음과 같이 입력

$ vi ~/.screenrc

term screen-256color

screen를 실행하면, 이전 화면을 보는게 지원안됨. screen 내부 명령으로 해결해야 되는데,

Ctrl + A, Esc

이 상태에서, PgUp/PgDown, Up/Down으로 스크롤 가능.

끝!.

Install Ubuntu 20.04 on Windows 10

지난번 WSL2에서 좀더 업데이트 해서…

새로 인스톨 하는 경우. Windows PowerShell을 Administrator 권한으로 실행.

> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

위 명령을 실행하면, WSL 기능이 활성화 되고 자동으로 재부팅.

다음으로 VirtualMachinePlatform 기능 활성화. 마찬가지로 Windows PowerShell을 Administrator 권한으로 실행해야함.

> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform

Windows Store에서 Ubuntu 20.04를 선택하여 설치.

설치된 Ubuntu 20.04를 wsl2로 변환

> wsl --set-version Ubuntu-20.04 2

시간이 좀 흐르면…

> wsl --set-version Ubuntu-20.04 2                                                                                                                                                                                        Conversion in progress, this may take a few minutes…                                                                                                                                                                                          For information on key differences with WSL 2 please visit https://aka.ms/wsl2                                                                                                                                                                  Conversion complete.                  

와 같이 나오고 종료. 이제 시작메뉴에서 Ubuntu 20.04를 실행하면,

와 같이 나오고, 이제 실제 Ubuntu 사용하는 것과 동일하게 사용 가능.

STM32CubeIDE에서 printf를 USART와 연결하기

printf 출력을 USART와 연결하여 사용 가능. 디버깅 시 상당한 이점을 가질 수 있음.

main.c 파일에 다음의 함수를 추가.

이때 uart의 인스턴스를 설정해야 하는데, STM32F746G-DISCO 보드에선 USART1번이 ST-Link의 Virtual Com Port와 연결되어 있음. 따라서 huart1를 선택.

int __io_putchar(int ch) 
{
     (void) HAL_UART_Transmit(&huart1, (uint8_t*) &ch, 1, 100);
     return ch;
}

프로젝트 설정에서 printf 문에 float 구문을 사용할 수 있도록 설정.

덧.

위 방법을 사용할 때, FreeRTOS 환경 내에선 알 수 없는 이유로 동작이 되지 않음. 메모리 관련 (heap 등등)의 문제로 추정된다는데… 이를 해결하기 위해선 경량화 되어 구현된 printf 함수를 사용하면 됨.

https://github.com/mpaland/printf

이 Repository의 printf.h, printf.c 파일을 해당 프로젝트에 추가하고, printf.h를 인클루드하여 사용.

사용자의 환경에 따라 _putchar 함수를 구현하면 됨.

void _putchar(char c)
{
    /* Place your implementation of fputc here */     
    /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */     
    HAL_UART_Transmit(&huart1, (uint8_t) &c, 1, 0xFFFF);
}

끝!

Set static IP on Jetson Nano/Jetpack

Install netplan

$ sudo apt install netplan.io

Add yaml to /etc/netplan/config.yaml

network:
   version: 2
   renderer: networkd
   ethernets:
     eth0:
       addresses:
         - 192.168.10.99/24
       gateway4: 192.168.10.1
       nameservers:
           addresses: [8.8.8.8, 8.8.4.4]

Save, and apply.

$ sudo netplan apply

That’s it.