레이블이 Debug-Info인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Debug-Info인 게시물을 표시합니다. 모든 게시물 표시

8/09/2020

systemd 의 logrotate 분석 과 Timer 사용법

1. systemd의 logrotate 기본구성 과 분석

syslog가 log 파일을 생성을 한다고 하면, 매번 Log를 주기적으로 backup을 하여 보관의 필요성을 느낄 것이며, 이를 위해서 사용되어지는 program이 logrotate이다 

만약 기본설치가 되어있다면, /etc/logrotate.conf 설정이 존재할 것이다. 
다만 logrotate가 자동으로 실행되는 program이 아니며, Linux Filesystem에 따라 sysvInit 일 경우는  cron 을 이용하여 주기적으로 호출되고, 
systemd일 경우는 timer를 이용하여 이를 주기적으로 호출되어 동작가능하다 


  • syslog 관련내용 
logrotate를 알기전에 syslogd에 대해 알자.
  https://ahyuo79.blogspot.com/2019/04/syslog.html


  • 기본설정파일 
  1. /etc/logrotate.conf  : 
  2. /etc/logrotate.d/btmp : 기본으로 설치됨 
  3. /etc/logrotate.d/wtmp


  • systemd의 timer 사용시 분석할 파일 
  1. /lib/systemd/system/logrotate.timer
  2. /lib/systemd/system/logrotate.service
  3. /etc/systemd/system/timers.target.wants/logrotate.timer  (Timer가 enable일 경우 존재)



1.1 logrotate 의 timer 와 service 분석 


  • logrotate 의 service 와 timer 분석

반드시 logrotate.service 와 logrotate.timer 의 prefix name이 logrotate.는 이름으로 동일해야 제대로 동작한다
logrotate.service는  logrotate.timer가 주기적으로 호출되어 를 구동하는 구조로 동작되어있기 때문에, systemd의 timer 현재 systemctl enable이 된 상태이다.


  • logrotate.timer 구조 파악  
분석으로 보면 매일 밤 12시, 즉 0시에 동작이 되며, Timer를 확인하는 주기는 12시간으로 정확성을 많이 떨어트리지만, Persistent를 이용

$ cat /lib/systemd/system/logrotate.timer 
[Unit]
Description=Daily rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)

[Timer]
OnCalendar=daily
AccuracySec=12h
Persistent=true

[Install]
WantedBy=timers.target
// systemctl enable logrotate.timer 할 경우  아래 link 생성됨
// systemctl disable logrotate.timer 할 경우 아래 link 제거됨

// timers.target.wants에 timer가 존재하는 것은 현재 enable 되는 상태
$ ls -al /etc/systemd/system/timers.target.wants/logrotate.timer
/etc/systemd/system/timers.target.wants/logrotate.timer -> /lib/systemd/system/logrotate.timerrotate.timer
$ systemctl status logrotate.timer // 매일 0시에 Trigger되어 동작함 $ systemctl is-enabled logrotate.timer // logrotate.timer enable enabled

systemd.timer 의 OnCalendar 설정정보 시간설정방법
onCalendar Time 설정을 보면 전부 0시기준으로 동작 
daily → *-*-* 00:00:00

시간동기화문제
OnCalendar 일반적으로 사용할 경우 time-sync.target 이후에 설정하도록 의존성을 넣는다고한다. 
  https://www.freedesktop.org/software/systemd/man/systemd.timer.html#Default%20Dependencies


기타 다른예제 (좋은예제)


  • 상위 timer에 의해 실행되는 logrotate.service 
기존의 Service 구조와 다르게 [Install] Section 이 없으며, *wants 및 에 위치 하지도 않는다
현재 systemctl disable logrotate.service 인 상태이지만 상위 timer가 구동을 시켜준다.

$ cat /lib/systemd/system/logrotate.service
[Unit]
Description=Rotate log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
RequiresMountsFor=/var/log
ConditionACPower=true

[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf

# performance options
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7

# hardening options
#  details: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
#  no ProtectHome for userdir logs
#  no PrivateNetwork for mail deliviery
#  no ProtectKernelTunables for working SELinux with systemd older than 235
MemoryDenyWriteExecute=true
PrivateDevices=true
PrivateTmp=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectSystem=full
RestrictRealtime=true

$ systemctl status logrotate.service // logrotate.service 동작시간 확인 

$ systemctl is-enabled logrotate.service // logrotate.timer에 의해 동작 
static

1.2 logrotate 설정분석 


기본적으로 설정은 /etc/logrotate.conf에서 하지만, 확장설정이 가능하므로, 
아래와 같이 include를 사용하여 /etc/logrotate.d 안에 있는 존재하는 모든 파일도 허용한다

  • 기본설정구성 
$ cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may be also be configured here.

mail command가 지원되며 e-mail에 log 정보도 같이 수신받을 수 있다. 

  • /var/log/btmp 설정 
실패한 Login 정보 (lastb 명령어로 확인)
$ cat /etc/logrotate.d/btmp
# no packages own btmp -- we'll rotate it here
/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

  • /var/log/wtmp 설정 
사용자의 Login/out과 시스템정보를 관리 (last 명령어로 확인)
$ cat /etc/logrotate.d/wtmp
# no packages own wtmp -- we'll rotate it here
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    minsize 1M                # 상위 monthly 와 별개로 사이즈가 넘으면 rotate 
    rotate 1
}

last 와 lastb

  • /var/log/message 와 /var/log/test 설정 예 

$ cat /etc/logrotate.d/test1   // kill -HUP  syslogd 재시작 
/var/log/messages /var/log/test {
    missingok              ## 로그파일을 없어도, 에러없이 진행 (nomissingok 로그파일 없으면 에러발생 default) 
    monthly
    rotate 5
    dateext                ## 저장된 log에 날짜표시 
#   ifempty                ## ifempty 이 default (log파일 비어 있어도 rotate 진행)    
#   nosharedscripts        ## nosharedscripts 이 default 이며, 상위 /var/log/test*이면 여러개를 다 실행 
    postrotate             ## logroate가 실행된 후 script로 kill로 Signal 전송하여 Refresh 
        /bin/kill -HUP 'cat /var/run/syslogd.pid 2> /dev/null' 2> /dev/null
    endscript

$ kill -l
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS RTMIN RTMIN+1 RTMIN+2 RTMIN+3 RTMIN+4 RTMIN+5 RTMIN+6 RTMIN+7 RTMIN+8 RTMIN+9 RTMIN+10 RTMIN+11 RTMIN+12 RTMIN+13 RTMIN+14 RTMIN+15 RTMAX-14 RTMAX-13 RTMAX-12 RTMAX-11 RTMAX-10 RTMAX-9 RTMAX-8 RTMAX-7 RTMAX-6 RTMAX-5 RTMAX-4 RTMAX-3 RTMAX-2 RTMAX-1 RTMAX
## 1 -HUP SIGHUP  Refresh
##-2 INT  SIGINT Interrupt (Ctrl+C)
##-3 QUIT SIGQUIT Quit (Ctrl+z)  (이하 생략)

}

Process에 문제가 있어서 다시 시작하고자 할 때에는 SIGHUP, SIGTERM, SIGKILL
kill 명령어 
  https://ko.wikipedia.org/wiki/Kill
  https://en.wikipedia.org/wiki/SIGHUP


$ cat /etc/logrotate.d/test2   // kill -HUP  syslogd 재시작 
/var/log/test {
    missingok
    daily
    rotate 10
    dateext
    sharedscripts          ## sharedscripts /var/log/news/*  같이 log가 여러개 중복될때 한번만실행 
    postrotate
         /bin/kill -HUP 'cat /var/run/syslogd.pid 2> /dev/null' 2> /dev/null
    endscript
}

/var/log/messages {
    missingok
    daily
    rotate 20
    dateext    
    postrotate
        /bin/kill -HUP 'cat /var/run/syslogd.pid 2> /dev/null' 2> /dev/null
    endscript
}

$ cat /etc/logrotate.d/test3   // kill -HUP  syslogd 재시작 

/var/log/messages {
    rotate 3
    minsize 1M
    sharedscripts
    postrotate
        /bin/kill -HUP 'cat /var/run/syslogd.pid 2> /dev/null' 2> /dev/null
    endscript
}

$ cat /var/lib/logrotate.status  // 각 logroate가 된 후 상태확인 
logrotate state -- version 2
"/var/log/test" 2020-08-06-0:0:58
"/var/log/wtmp" 2020-07-10-11:0:0
"/var/log/btmp" 2020-07-10-11:0:0
"/var/log/message" 2020-07-10-11:0:0


logrotate(cron) and syslogd
  http://heart4u.co.kr/tblog/370
  



2. systemd 의 timer 사용방법


SysVinit에서는 cron을 사용했지만, systemd에서는 Timer를 사용해서 본인이 원하는 것을 주기적으로 실행해야하며, 
systemd의 timer는 monotonic timercalendar time(Realtime)으로 구분이되는데, 거의 monotonic timer를 많이 사용할 것이므로 아래로 처럼 구성한다


  • 현재 Timer 구성확인
$ systemctl list-timers   // Timer 상태확인 
or
$ systemctl list-timers --all | cat   // 모든 Timer 상태확인 (inactive timer 포함)
or
$ systemctl list-timers | cat
NEXT                         LEFT     LAST                         PASSED  UNIT                         ACTIVATES
Tue 2020-07-17 17:44:51 KST  7h left  Mon 2020-07-16 17:44:51 KST  16h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Wed 2020-07-18 00:00:00 KST  14h left Tue 2020-07-17 00:00:36 KST  9h ago  logrotate.timer              logrotate.service

  • monotonic timer 예제
 $ cat monotonic.timer   // booting 후 15분 후 동작후 매주 돌아가는 timer (미테스트)
[Unit]
Description=Run foo weekly and on boot

[Timer]
OnBootSec=15min
OnUnitActiveSec=1w 

[Install]
WantedBy=timers.target 

  • realtime timer 예제
 $ realtime.timer    // 일주일에 한번  12:00am on Monday 동작 (미테스트) 
[Unit]
Description=Run foo weekly

[Timer]
OnCalendar=weekly
Persistent=true

# Persistent          true이며, Timer가 실행한 서비스 Trigger정보를 Disk가 저장후 Timer가 동작할때, 즉각 Service 동작하도록 설정 

[Install]
WantedBy=timers.target

출처 

Realtime 으로 Monotonic Timer 구현 


2.1 systemd 의 TEST Timer 구성 


Timer를 잘 사용하기 위해서 monotonic timer 기반으로 구성 후 간단한 예제를 만들고, 이를 테스트 할 수 있는 shell script 와 함께 
내부의 환경변수 값들을 변경해보면 직접 테스트 진행. 

  • Test Timer 전체구성 
  1. /usr/bin/foo.sh 
  2. /lib/systemd/system/foo.timer
  3. /lib/systemd/system/foo.service 

  • timer로 실행될 service의 shell script 작성
$ vi /usr/bin/foo.sh   // 주기적으로 실행할 Shell Script 
#!/bin/sh
# Author: Jeonghun
#

WAIT_100MS() {
    sleep 0.1
}
# NOW 현재시간 
# UPTIME 은 부팅후 시간 측정용 1st arg (Booting 후 Sec)  2nd arg (Idle Time Sec) 
NOW=$(date +"%H:%M:%S")
UPTIME=`cat /proc/uptime`
echo -e "\x1b[1;93m *** TIMER $NOW  $UPTIME  \x1b[0m" > /dev/kmsg

$ chmod +x /usr/bin/foo.sh  // 실행권한 설정 

  • systemd 의 foo.timer 작성 (sample)
$ vi /etc/systemd/system/foo.timer
or
$ vi /lib/systemd/system/foo.timer
[Unit]
Description=Run 3 Secs foo timer from 1 min after boot

[Timer]
OnBootSec=1min
OnUnitActiveSec=3s
#OnActiveSec=3s

[Install]
WantedBy=timers.target

#
#
# [Timer] Section 
#
# 반드시 Monotonic Timer로 설정시 아래 설정을 포함을 해야하며, 중복 설정도 가능 
# OnActiveSec=, OnBootSec=, OnStartupSec=, OnUnitActiveSec=, OnUnitInactiveSec= 
# 
# 상위 설정을 한 후 세부 설정을 별도로 진행


$ systemctl enable foo.timer
Created symlink /etc/systemd/system/timers.target.wants/foo.timer → /etc/systemd/system/foo.timer.

$ ls -al /etc/systemd/system/timers.target.wants/foo.timer   // 생성된 링크확인 

  https://www.freedesktop.org/software/systemd/man/systemd.timer.html

  • systemd 의 timer 에 의해 실행될 service 설정
$ vi /etc/systemd/system/foo.service    
or
$ vi /lib/systemd/system/foo.service  // 상위 foo.timer에 의해 실행되므로 별도로 service 설정을 안해도 됨 
[Unit]
Description=TEST
Requires=local-fs.target
After=local-fs.target

[Service]
Type=simple
ExecStart=/usr/bin/foo.sh

Test Timer 구성참조
  https://coderoad.ru/9619362/%D0%97%D0%B0%D0%BF%D1%83%D1%81%D0%BA-a-cron-%D0%BA%D0%B0%D0%B6%D0%B4%D1%8B%D0%B5-30-%D1%81%D0%B5%D0%BA%D1%83%D0%BD%D0%B4 

AccuracySec=의 이해 

2.2 TEST(foo.timer) 설정 변경 테스트  

Timer의 설정의 의미를 알기 위해서 foo.timer의 설정값에 변경하여 개별 테스트 진행하며, 아래와 같이 그 결과도 알아본다.


  • foo.timer 수정 후 테스트 및 분석 (전체 2번실행)

[Timer]
OnBootSec=1min
OnActiveSec=3s
# OnBootSec          Booting 후 실행되는 Timer 설정 1분이며, OnStartupSec= 값도 동일하게 설정
# OnStartupSec       OnBootSec 거의 유사하지만 다른점은 service manager가 동작한 시점부터라고함 (아직 정확한 차이는 모름)
# OnActiveSec        Timer 자신이 Active 된 순간의 시간이라고 하는데,  
# AccuracySec        Timer를 확인하는 주기 미설정시 기본 1분 
// 1st TEST, 상위설정값 TEST 많이 다르며, 전체 2번만 동작  
 *** TIMER 14:55:59  14.64 0.77               // OnActiveSec 14초 Timer가 Active되는 순간 
 *** TIMER 14:56:55  70.89 47.92              // OnBootSec 70초 (AccuracySec 1분, 정확성이 떨어짐) 

// 2nd TEST, 상위설정값 TEST 많이 다르며, 전체 2번만 동작  
 *** TIMER 15:21:56  14.81 0.90
 *** TIMER 15:22:53  72.45 50.00              // OnBootSec 72초 (AccuracySec 1분, 정확성이 떨어짐) 

  • foo.timer 수정 후 테스트 및 분석 (전체 1번실행)

[Timer]
OnBootSec=1min
AccuracySec=3s
# AccuracySec        Timer를 확인하는 주기를 설정이며, 기본은 1분이지만,3초로 변경, 즉 정확성을 높임  
// 1st TEST 상위 설정값대로 동작하며, 전체 1번만 동작   
 *** TIMER 15:33:52  62.05 39.34                // OnBootSec 62초 (AccuracySec 3초 이내) 
 
// 2nd TEST 상위 설정값대로 동작하며, 전체 1번만 동작   
 *** TIMER 15:38:43  62.95 40.51                // OnBootSec 62초 (AccuracySec 3초 이내)       



  • foo.timer 수정 후 테스트 및 분석 (계속실행)
[Timer]
OnBootSec=1min
OnUnitActiveSec=3s
# OnBootSec          Booting 후 실행되는 Timer 설정 1분이며, OnStartupSec= 값도 동일하게 설정 
# OnUnitActiveSec    마지막(OnBootSec)에 Timer가 실행한 Unit(즉 서비스) Active가 되었을때 기준으로 3초 설정 
# AccuracySec        Timer를 확인하는 주기 미설정시 기본 1분 
// 1st TEST, 상위설정값과 많이 다르지만 계속동작                         
 *** TIMER 14:51:42  73.61 50.83           // OnBootSec 73초 (AccuracySec 때문에 정확성이 떨어짐) 
 *** TIMER 14:52:19  111.12 87.40          // OnUnitActiveSec 111-73= 38초 
 *** TIMER 14:52:43  134.63 110.23         // OnUnitActiveSec 134-111= 23초 
 *** TIMER 14:53:01  153.08 128.23         // OnUnitActiveSec 153-134= 19초 
 *** TIMER 14:53:19  171.37 146.09

// 2nd TEST, 상위설정값과 많이 다르지만 계속동작       
 *** TIMER 15:02:58  78.25 55.14            // OnBootSec 78초 
 *** TIMER 15:03:32  111.50 87.60
 *** TIMER 15:04:04  143.61 118.85
 *** TIMER 15:04:19  158.80 133.61
 *** TIMER 15:04:33  173.25 147.56


  • foo.timer 수정 후 테스트 및 분석 (계속실행)

[Timer]
OnBootSec=1min
OnUnitActiveSec=3s
AccuracySec=3s
# OnUnitActiveSec    마지막(OnBootSec)에 Timer가 실행한 Unit(즉 서비스) Active가 되었을때 기준으로 3초 설정 
# OnUnitInactiveSec  마지막(OnBootSec)에 Timer가 실행한 Unit(즉 서비스) inActive가 되었을때 기준으로 시간설정 
# AccuracySec        Timer를 확인하는 주기를 설정이며, 기본은 1분이지만,3초로 변경, 즉 정확성을 높임  
// 1st TEST 상위 설정값과 유사하게 동작 (3~6 초)   
 *** TIMER 15:14:11  60.66 37.90              // OnBootSec 60초 (AccuracySec 3초 이내) 
 *** TIMER 15:14:17  66.65 43.66              // OnUnitActiveSec 3초 (AccuracySec 3초 이내) 
 *** TIMER 15:14:21  70.65 47.49
 *** TIMER 15:14:27  76.65 53.23
 *** TIMER 15:14:31  80.65 57.03
 *** TIMER 15:14:37  86.64 62.80
 *** TIMER 15:14:41  90.64 66.65
 *** TIMER 15:14:47  96.65 72.41
 *** TIMER 15:14:51  100.64 76.23
 *** TIMER 15:14:57  106.65 81.98
 *** TIMER 15:15:01  110.64 85.82
 *** TIMER 15:15:07  116.65 91.63
 *** TIMER 15:15:11  120.65 95.41
 *** TIMER 15:15:14  123.70 98.31
 *** TIMER 15:15:20  129.65 103.99
 
// 2nd TEST 상위 설정값과 유사하게 동작 (3~6 초)   
 *** TIMER 15:18:38  62.95 40.17             // OnBootSec 62초 (AccuracySec 3초 이내) 
 *** TIMER 15:18:44  68.94 45.94             // OnUnitActiveSec 3초 (AccuracySec 3초 이내) 
 *** TIMER 15:18:50  74.94 51.72
 *** TIMER 15:18:54  78.95 55.56
 *** TIMER 15:19:00  84.95 61.33
 *** TIMER 15:19:04  88.95 65.16
 *** TIMER 15:19:10  94.95 70.94
 *** TIMER 15:19:14  98.94 74.77
 *** TIMER 15:19:20  104.94 80.57
 *** TIMER 15:19:24  108.94 84.39
 *** TIMER 15:19:30  114.95 90.17
 *** TIMER 15:19:34  118.94 94.01
 *** TIMER 15:19:40  124.94 99.87
 *** TIMER 15:19:44  128.95 103.73

  • foo.timer 수정 후 테스트 및 분석 (계속실행)

[Timer]
OnBootSec=1min
OnUnitActiveSec=1s
AccuracySec=3s
# OnUnitActiveSec    마지막(OnBootSec)에 Timer가 실행한 Unit(즉 서비스) Active가 되었을때 기준으로 1초 설정 
# AccuracySec        Timer를 확인하는 주기를 설정이며, 기본은 1분이지만,3초로 변경, 즉 정확성을 높임  
// 1st TEST 상위 설정값과 가장유사하게 동작 2-4초 간격   
 *** TIMER 15:27:55  61.66 38.97               // OnBootSec 61초 (AccuracySec 3초 이내) 
 *** TIMER 15:27:59  65.65 42.82               // OnUnitActiveSec 1초 (AccuracySec 3초 이내) 
 *** TIMER 15:28:03  69.65 46.64
 *** TIMER 15:28:05  71.66 48.50
 *** TIMER 15:28:09  75.65 52.26
 *** TIMER 15:28:13  79.65 56.07
 *** TIMER 15:28:15  81.65 57.98
 *** TIMER 15:28:19  85.65 61.80
 *** TIMER 15:28:23  89.66 65.65
 *** TIMER 15:28:25  91.65 67.52
 *** TIMER 15:28:29  95.65 71.35
 *** TIMER 15:28:33  99.66 75.17
 *** TIMER 15:28:35  101.65 77.06
 *** TIMER 15:28:39  105.65 80.92
 *** TIMER 15:28:43  109.65 84.74
 *** TIMER 15:28:45  111.65 86.63
 *** TIMER 15:28:49  115.66 90.47
 *** TIMER 15:28:53  119.65 94.29
 *** TIMER 15:28:55  121.66 96.18
 *** TIMER 15:28:59  125.66 99.99
 
// 2nd TEST 상위 설정값과 가장유사하게 동작   
 *** TIMER 15:30:39  63.05 40.48               // OnBootSec 63초 (AccuracySec 3초 이내) 
 *** TIMER 15:30:43  67.04 44.33               // OnUnitActiveSec 1초 (AccuracySec 3초 이내) 
 *** TIMER 15:30:47  71.04 48.17
 *** TIMER 15:30:50  74.04 51.06
 *** TIMER 15:30:54  78.04 54.87
 *** TIMER 15:30:58  82.04 58.69
 *** TIMER 15:30:59  83.30 59.84
 *** TIMER 15:31:03  87.04 63.42
 *** TIMER 15:31:07  91.04 67.23
 *** TIMER 15:31:10  94.04 70.10
 *** TIMER 15:31:14  98.04 73.91
 *** TIMER 15:31:18  102.04 77.74
 *** TIMER 15:31:20  104.04 79.61
 *** TIMER 15:31:24  108.04 83.43
 *** TIMER 15:31:28  112.04 87.29
 *** TIMER 15:31:30  114.04 89.20
 *** TIMER 15:31:34  118.04 93.01
 *** TIMER 15:31:38  122.04 96.81
 *** TIMER 15:31:40  124.04 98.69
 *** TIMER 15:31:42  126.39 100.92
 *** TIMER 15:31:46  130.04 104.45


2.3 systemd 의 timer 와 service 동시 설정


지금까지는 상위 service는 timer가 실행을 해줄 때까지 기다리고 동작을 했지만, service도 별도로 동작가능하도록 설정하여, 동시 설정하여 사용하자  

주로 이렇게 사용하는 이유는 booting 후 꼭 실행을 해야하는 경우가 될 것 같다. 


  • systemd의 timer 와 service 두개 중복 설정 
// 상위 foo.timer의 실행과 foo.service 독자적인 실행으로 중복실행방법  
$ vi /etc/systemd/system/foo.service    
or
$ vi /lib/systemd/system/foo.service  
[Unit]
Description=TEST
Requires=local-fs.target
After=local-fs.target

[Service]
Type=simple
ExecStart=/usr/bin/foo.sh

[Install]
WantedBy=multi-user.target

$ systemctl enable foo.service  // 이제 foo.service로도 동작가능 (timer가 죽어도 동작가능)  
Created symlink /etc/systemd/system/multi-user.target.wants/foo.service → /etc/systemd/system/foo.service.

$ ls -al /etc/systemd/system/multi-user.target.wants/foo.service   // 생성된 링크확인 


5/19/2020

ftrace 와 systrace (자료수집)

각 Ftrace 와 systrace 와 기타 자료수집을 하며, 별도의 설명을 하지 않겠다. 

NVIDIA-IDE Nsight(Ecplise 기반)
  https://ahyuo79.blogspot.com/2019/05/nvidia-nsight-tools-jetpack-42.html

systrace는 Google Android팀과 Google Chrome팀의 소유

  • systrace 의 이해
  https://source.android.com/devices/tech/debug/systrace
  https://developer.android.com/studio/profile/systrace.html

  • Android systrace 관련자료
  https://source.android.com/devices/tech/perf/boot-times#systrace
  https://developer.android.com/studio/profile/systrace
  https://google-developer-training.github.io/android-developer-advanced-course-practicals/unit-2-make-your-apps-fast-and-small/lesson-4-performance/4-1c-p-systrace-and-dumpsys/4-1c-p-systrace-and-dumpsys.html


  • Trace compass IDE (Ecplise 기반)
  https://archive.eclipse.org/tracecompass.incubator/doc/org.eclipse.tracecompass.incubator.ftrace.doc.user/User-Guide.html

  • Jetpack
  https://developer.android.com/jetpack

  • Ftrace
  https://source.android.com/devices/tech/debug/ftrace
  https://source.android.google.cn/devices/tech/debug/ftrace?hl=ko
  https://www.kernel.org/doc/Documentation/trace/ftrace.txt

  • GDB (VSCode)
  https://source.android.google.cn/devices/tech/debug/gdb?hl=ko
CONFIG_HZ
  https://source.android.google.cn/devices/tech/debug/jank_jitter?hl=ko

4/22/2020

Yocto User Config 의 Profiling and Tracing

1. Yocto 의 Profile 기능 추가 및 사용

Yocto 기반으로 Profile 기능과 Trace Debug기능을 추가하여 사용하는 방법을 알아보기 위해서 아래와 같이 설정변경 후,
이를 기반으로 Profile 과 Tracing 사용을 해본다.

Yocto에서 Profile 과 Tracing은 소스를 세부적으로 분석하는 Debug 기술이자, 성능측정도 가능하므로 중요한 기술이다. 
이를 제대로 사용하려면 각 IDE Tool 도 알아두어야 한다
대부분 Ecplise 기반으로 제공되어지며, 각 Chip 제조사 Application들도 보면 기반을 다 Ecplise 기반으로 되어있다. 


TI CCS (TI사 제공) 이외 각 제조사 IDE 참조 


1.1 Yocto 의 기본문법 및 User Config 이해 

Yocto의 기본적인 이해


Yocto Recipe 작성방법 (반드시 확인 및 이해)

Yocto User Configuration 수정방법
  https://ahyuo79.blogspot.com/2020/02/yocto-user-configuration.html

기본 Yocto Recipe 및 Kernel Recipe 수정방법
  https://ahyuo79.blogspot.com/2020/02/yocto-recipe.html

Yocto sysLog 구성 
  https://ahyuo79.blogspot.com/2020/04/yocto-syslogd.html


1.2  Yocto User Configuration 설정변경 

  • Yocto 의 User Configuration 수정 
$ cat conf/local.conf  //일반적인 설정

## Yocto Version에따라 설정변경될 수 있음 아래 Manual 참조
## 일반적인 EXTRA_IMAGE_FEATURES 설정으로 debug 기본정보포함 (기본 /sys/kernel/debug는 동작됨)
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"

별도로 추가하여 설정
## Profile 과 Tracing 을 위해 별도로 추가되는 명령들 
## IMAGE의 Profile Tool을 추가 
EXTRA_IMAGE_FEATURES += "tools-profile"

## Package들에 Debug 정보를 추가 (bitbake를 이용하여 xxx-dbg Manual로 해도됨)
EXTRA_IMAGE_FEATURES += "dbg-pkgs"

## Yocto는 default로 strip을 하여 debug정보 및 삭제하므로 이를 방지 
INHIBIT_PACKAGE_STRIP = "1"

##  *-dbg packages 만들 때 Bin 와 Debug 정보를 어떻게 분리할지를 결정 (bin 에 .debug 생성) 
PACKAGE_DEBUG_SPLIT_STYLE = 'debug-file-directory'

** EXTRA_IMAGE_FEATURES 는 항상 Yocto Version에 따라 반드시 참조 

gdb 와 같이 사용하고자 하면 아래와 같이 설정 
EXTRA_IMAGE_FEATURES += "dbg-pkgs"
EXTRA_IMAGE_FEATURES += "tools-debug"

Yocto에서 deb 방식으로 package 관리할 경우 (apt-get)
  https://imxdev.gitlab.io/tutorial/How_to_apt-get_to_the_Yocto_Project_image/
 
EXTRA_IMAGE_FEATURES 
  https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-features-image


1.3 Yocto 의 Kernel Config 수정 

  • WORKDIR 에서 현재 Kernel Config 확인
Yocto의 Build space에서 직접 빌드된 Kernel Source의 Config 확인

$ vi ./tmp/work/imx6sxsabresd-poky-linux-gnueabi/linux-imx/4.19.35-r0/build/.config  //직접 찾아서 확인 
CONFIG_BUILD_LTTNG       //확인했으나 없음
CONFIG_FUNCTION_TRACER   //확인했으나 없음 

$ vi ../sources/meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/linux-imx_4.19.35.bbappend // Kernel Recipe가 문제가 있음 
# 부분 막음 
do_preconfigure_append()   

  https://en.wikipedia.org/wiki/Ftrace


  • Kernel 의 CONFIG 설정변경 

$ bitbake linux-imx  -c configme    // patch 후 *cfg를 적용을 한다고하는데, 동작안됨
$ bitbake linux-imx  -c menuconfig    // 설정변경
//각 메뉴 선택 후 HELP에서 CONFIG 확인가능

//이미 설정되어있음 
> Kernel hacking > Compile-time checks and compiler options > Debug Filesystem (CONFIG_DEBUG_FS)

//새로설정 
> Kernel hacking > Tracers                                            // (CONFIG_FTRACE)
> Kernel hacking > Tracers > Kernel Function Tracer                  // (CONFIG_FUNCTION_TRACER)
> Kernel hacking > Tracers > Kernel Function Graph Tracer            // (CONFIG_FUNCTION_GRAPH_TRACER)
> Kernel hacking > Tracers > Interrupts-off Latency Tracer           // (CONFIG_IRQSOFF_TRACER)
> Kernel hacking > Tracers > Preemption-off Latency Tracer           // (CONFIG_PREEMPT_TRACER)
> Kernel hacking > Tracers > Scheduling Latency Tracer               // (CONFIG_SCHED_TRACER)
> Kernel hacking > Tracers > Trace max stack                         // (CONFIG_STACK_TRACER)
> Kernel hacking > Tracers > Support for tracing block IO actions    // (CONFIG_BLK_DEV_IO_TRACE)
> Kernel hacking > Tracers > Kernel function profiler                // (CONFIG_FUNCTION_PROFILER)
CONFIG_DYNAMIC_FTRACE="y"                                              // 찾지못함 (상위 설정시 자동설정됨)
CONFIG_FTRACE_MCOUNT_RECORD="y"                                        // 찾지못함 (상위 설정시 자동설정됨)


//추후 별도로 추가 
> Kernel hacking > Tracers > Trace syscalls                          // (CONFIG_FTRACE_SYSCALLS) 


fragment가 생성되었으나 이전 .config 의 나의 설정과 다름 (주의)
추후 필요한 것만 직접 적용하여 넣도록하자

$ bitbake linux-imx  -c diffconfig    //*.cfg 생성 후 이를 Kernel Recipe에 추가 
....
......../fragment.cfg

$ cat fragment.cfg  // 상위와 다르게 나옴 자세히 보면 선택한 것도 미선택으로 됨 
CONFIG_TRACEPOINTS=y
CONFIG_UPROBES=y
# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_ATH6KL_TRACING is not set
# CONFIG_MXC_GPU_VIV is not set
CONFIG_BINARY_PRINTF=y
# CONFIG_DEBUG_PAGE_REF is not set
CONFIG_TRACE_IRQFLAGS=y
CONFIG_STACKTRACE=y
CONFIG_NOP_TRACER=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_RING_BUFFER_ALLOW_SWAP=y
CONFIG_PREEMPTIRQ_TRACEPOINTS=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
# CONFIG_FUNCTION_GRAPH_TRACER is not set
CONFIG_TRACE_PREEMPT_TOGGLE=y
# CONFIG_PREEMPTIRQ_EVENTS is not set
CONFIG_IRQSOFF_TRACER=y
CONFIG_PREEMPT_TRACER=y
CONFIG_SCHED_TRACER=y
# CONFIG_HWLAT_TRACER is not set
# CONFIG_FTRACE_SYSCALLS is not set
CONFIG_TRACER_SNAPSHOT=y
CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
CONFIG_STACK_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_UPROBE_EVENTS=y
CONFIG_PROBE_EVENTS=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_TRACEPOINT_BENCHMARK is not set
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_RING_BUFFER_STARTUP_TEST is not set
# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
# CONFIG_TRACE_EVAL_MAP_FILE is not set
CONFIG_TRACING_EVENTS_GPIO=y

$ cp ./build/tmp/work/imx6sxsabresd-poky-linux-gnueabi/linux-imx/4.19.35-r0/fragment.cfg ../sources/meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/files/kernel_ftrace.cfg
//적용 Kernel Recipe 수정 

ftrace 의 Kernel config 설정
  https://stackoverflow.com/questions/41238386/how-to-enable-or-configure-ftrace-module
  https://docs.google.com/presentation/d/13zIFUTTdChr7JNpZnb1K56aUsv_E1cOWausjQpsqcGc/htmlpresent
  https://docs.windriver.com/bundle/Wind_River_Linux_Tutorial_Dynamic_Kernel_Debugging_with_ftrace_and_kprobes_LTS_1/page/zjd1552591139310.html

  • Kernel 만 다시빌드 및 배포

$ bitbake linux-imx  -c compile -f    // -f force로 강제로 빌드 후 .config 설정확인 
$ bitbake linux-imx  -c deploy        // 이를 적용 

$ bitbake linux-imx  -c clean        // 전체삭제 
$ bitbake linux-imx          // 전체동작 (오동작) 
$ bitbake linux-imx  -c configure         // 전체동작 (오동작) 


  https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#var-KBUILD_DEFCONFIG
  https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#kernel-related-tasks

  • bitbake로 image 생성
$ bitbake core-image-base 


Yocto Profile manual
Zeus(3.0)
  https://yoctoproject.org/docs/3.0/profile-manual/profile-manual.html
Warrior(2.7)
  https://yoctoproject.org/docs/2.7/profile-manual/profile-manual.html
Fido(1.8)
  https://yoctoproject.org/docs/1.8/profile-manual/profile-manual.html


1.4  Yocto 설정 변경 시 문제사항 

  • 처음 발생하는 문제
Parition을 고정 크기를 했을 경우, Debug 정보가 들어가기 때문에 나의 경우는 약 4배 좀 더 용량이 더 커져서 문제발생
이 문제는 아래의 WIC 부분 참조

  • 두번째 발생하는 문제
빌드가 잘 된 후 아래와 같이 Image를 적용 후 Booting 하며 문제발생
아래문제도 역시 /var/log 와 kernel size 문제를 제거후 해결됨
.......
         Starting Flush Journal to Persistent Storage...
systemd-journald[164]: Received request to flush runtime journal from PID 1
[  OK  ] Started Flush Journal to Persistent Storage.
[    **] A start job is running for dev-mmcblk3p5.device (24s / 1min 30s)random: crng init done
random: 7 urandom warning(s) missed due to ratelimiting
[ TIME ] Timed out waiting for device dev-mmcblk3p5.device.

  https://www.linode.com/community/questions/17915/why-did-my-server-miss-urandom-warnings-due-to-rate-limiting


Yocto 의 WIC Partition (해결방법)
  1. Partition Size도 가변사이즈로 변경(고정사이즈일 경우) 
  2. Partition 도 삭제했다면 sources에서도 fstab도 같이 수정 
  3. /var/log 부분기능삭제
  https://ahyuo79.blogspot.com/2020/02/yocto-partition.html


2. Yocto의 Profile 및 Trace 확인 및 사용


  • 현재 설정된 기본기능확인 (EXTRA_IMAGE_FEATURES 확인)

$ cat /etc/fstab    // /sys/debug/kernel 별도로 없으며, 상위 debug-tweaks 참조  

$ ls /sys/kernel/debug  // 상위 (EXTRA_IMAGE_FEATURES ?= "debug-tweaks") 적용 부터 동작 
2100000.caam/       extfrag/            pm_genpd/
bdi/                fault_around_bytes  pm_qos/
block/              gpio                pwm
ci_hdrc.0/          hid/                regmap/
ci_hdrc.1/          iio/                regulator/
clear_warn_once     memblock/           sleep_time
clk/                mmc2/               suspend_stats
device_component/   mmc3/               ubi/
devices_deferred    mtd/                ubifs/
dma_buf/            opp/                usb/
dri/                pinctrl/            wakeup_sources

$ cat /sys/kernel/debug/gpio  // GPIO Debug   (sysfs도 이용하지만, device tree에서 직접 모듈로 연결가능) 
....
 gpio-112 (                    |peri_3v3            ) out hi  // sys file이 아닌 device tree에서 gpio 연결 
 ...
 gpio-114 (                    |sysfs               ) out lo         
 ...
 gpio-160 (                    |sysfs               ) out hi  // sys file에서 export 한 다음 direction 설정 후 값 설정
 gpio-161 (                    |sysfs               ) out hi
 gpio-170 (                    |spi_imx             ) out hi

// PinCtrl 관련설정값을 쉽게 확인 (device tree의 설정값과 비교) 
$ cat /sys/kernel/debug/pinctrl/pinctrl-handles 

// PinCtrl 관련설정값을 세부적으로 확인 (device tree의 설정값과 비교) 
$ cat /sys/kernel/debug/pinctrl/pinctrl-maps 

// USB 정보 lsusb 
$ cat /sys/kernel/debug/usb/devices

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 1
B:  Alloc=  0/800 us ( 0%), #Int=  1, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 4.19
S:  Manufacturer=Linux 4.19.35-1.1.0+g0f9917c ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=ci_hdrc.1
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms 
......

// PMIC Regulator 정보 
$ ls /sys/kernel/debug/regulator/   
0-0008-COIN
0-0008-SW1AB
0-0008-SW2
0-0008-SW3A
0-0008-SW3B
0-0008-SWBST
0-0008-VGEN1
0-0008-VGEN2
0-0008-VGEN3
0-0008-VGEN4
0-0008-VGEN5
0-0008-VGEN6
0-0008-VREFDDR
0-0008-VSNVS
.......


$ perf  // EXTRA_IMAGE_FEATURES 추가설정 후 존재확인

$ lttng           // lttng          확인
$ lttng-crash     // lttng-crash    확인
$ lttng-relayd    // lttng-relayd   확인
$ lttng-sessiond  // lttng-sessiond 확인

$ babeltrace      // babeltrace 확인
$ babeltrace-log  // babeltrace-log

$ blktrace  //blktrace  존재확인  (Block Device Trace) 
$ blkparse  //blkparse  존재확인   
$ iowatcher  //blktrace  visual tool   

$ dtrace  //dtrace  

$ ls /sys/kernel/debug/tracing  // 미존재하면 Kernel Config 수정 필요 
README                      set_ftrace_filter
available_events            set_ftrace_notrace
available_filter_functions  set_ftrace_pid
available_tracers           snapshot
buffer_size_kb              stack_max_size
buffer_total_size_kb        stack_trace
current_tracer              stack_trace_filter
dyn_ftrace_total_info       timestamp_mode
enabled_functions           trace
events                      trace_clock
free_buffer                 trace_marker
function_profile_enabled    trace_marker_raw
instances                   trace_options
options                     trace_pipe
per_cpu                     trace_stat
printk_formats              tracing_cpumask
saved_cmdlines              tracing_max_latency
saved_cmdlines_size         tracing_on
saved_tgids                 tracing_thresh
set_event                   uprobe_events
set_event_pid               uprobe_profile


2.1 Ftrace의 기본동작 확인 


$ mount -t debugfs nodev /sys/kernel/debug

$ echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
$ echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable
$ echo 1 > /sys/kernel/debug/tracing/events/syscalls/enable

## Start Recording 
$ echo 1 > /sys/kernel/debug/tracing/tracing_on

$ cat /sys/kernel/debug/tracing/trace > myFtraceFile.txt


$ cat myFtraceFile.txt  | head -n 20
# tracer: nop
#
# entries-in-buffer/entries-written: 6606/6606   #P:1
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
          <idle>-0     [000] dns4  2163.718052: sched_wakeup: comm=rcu_preempt pid=10 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.718080: sched_wakeup: comm=rcu_sched pid=11 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.728019: sched_wakeup: comm=rcu_preempt pid=10 prio=120 target_cpu=000
          <idle>-0     [000] dnH5  2163.728046: sched_wakeup: comm=kworker/0:0 pid=342 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.728068: sched_wakeup: comm=rcu_sched pid=11 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.738009: sched_wakeup: comm=rcu_preempt pid=10 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.738035: sched_wakeup: comm=rcu_sched pid=11 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.758001: sched_wakeup: comm=kworker/0:0 pid=342 prio=120 target_cpu=000
          <idle>-0     [000] dns4  2163.768017: sched_wakeup: comm=rcu_preempt pid=10 prio=120 target_cpu=000



  https://archive.eclipse.org/tracecompass.incubator/doc/org.eclipse.tracecompass.incubator.ftrace.doc.user/User-Guide.html
  https://archive.eclipse.org/tracecompass/doc/stable/org.eclipse.tracecompass.doc.user/Trace-Compass-Main-Features.html
  https://archive.eclipse.org/tracecompass.incubator/doc/org.eclipse.tracecompass.incubator.kernel.doc.user/User-Guide.html


2.2 LTTng 사용방법

아래와 같이 Ecplise를 이용하여 LTTng와 함께 쉽게 디버깅가능  

  • LTTng Command 사용법 및 Trace Compass or Ecplise에서 분석

$ lttng create mySession  // Trace Compass or Ecplise 의 LTTng의 Control의 SSH로 접속가능 

$ lttng enable-event sched_switch -k   // Trace Compass의 Control의 Provider의 Kernel에서도 설정가능 

$ lttng start // Trace Compass의 Control의 Session의 mySession에서 Start 가능 

$ lttng stop // Trace Compass의 Control의 Session의 mySession에서 Stop 가능 

$ lttng view // Consol에서 정보보기 

$ lttng destroy mySession  // 본인이 필요 없다면 삭제 , 분석을 한다면 미삭제 

$ tar cvzf lttngtest.tar.gz lttng-traces   // 이안에 상위에서 만든 각각의 Session들이 존재 



  • Ecplise 에서 LTTng 분석 
  1. LTTng->Control에서는 SSH로 Target에 연결하여 Control로 가능 
  2. lttng create Session만 진행 후 모든 것을 Remote로 진행가능 
  3. 상위에서 저장된 lttngtest.tar.gz 정보를 Trace Project에서 import하여 분석가능도 가능 


관련참조자료 
  https://www.nxp.com/docs/en/application-note/AN5172.pdf


3. EXTRA_IMAGE_FEATURE의 확장 설정 

User Config의 local config 부분에 확장추가 
$ cat conf/local.conf
## Yocto Profile Manual 부분의 참고 (미테스트)
## Profile Tool (perf, systemtap, and LTTng ) 설치  (Warrior 사용가능)
EXTRA_IMAGE_FEATURES += "perf"

## Debugging Tool 설치 ( strace and gdb)  (Warrior 사용가능)
EXTRA_IMAGE_FEATURES += "tools-debug"


  https://wiki.yoctoproject.org/wiki/Tracing_and_Profiling#General_Setup
  https://wiki.yoctoproject.org/wiki/Tracing_and_Profiling#Collecting_and_viewing_a_trace_in_Eclipse



  • IMAGE_FEATURE  기능의 변화
사용되는 Yocto의 Version에 따라 IMAGE FEATURE의 기능이 다르므로 주의

Zeus(3.0)
  https://www.yoctoproject.org/docs/3.0/ref-manual/ref-manual.html#ref-features-image
Warrior(2.7)
  https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#ref-features-image
Fido(1.8)
  https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#ref-features-image


Yocto SDK Manual
  https://www.yoctoproject.org/docs/2.7/sdk-manual/sdk-manual.html


Intel Vtune
  https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top/set-up-analysis-target/embedded-linux-targets/configure-yocto-project-with-linux-target-package.html
  https://software.intel.com/content/www/us/en/develop/documentation/vtune-help/top.html

4/05/2020

Yocto 에서 syslogd/logrotate 와 Package 중복사용

1. syslogd 와 logrotate 관련 사항 

syslogd 관련이해
Yocto에 추가하기 전에 syslog를 먼저 이해하도록하자 


Yocto Recipe 작성방법 


Yocto에서 syslogd를 사용할 경우 일반적으로 busybox에 포함된 package로 많이 사용할 것이며, 그 기준으로 설명한다.

기본적으로 syslogd 와 logrotate 는 busybox에서 제공해주지만, 완벽한 기능이 아니라서 별도로 각가 설치를 해주면 된다. 

  • logrotate package 지원
busybox에서도 logrotate를 지원해주지만, logrotate package를 설치하는 것이 더 좋다 

IMAGE_INSTALL += "logrotate" 

  • rsyslogd or syslog-ng package 지원 
busybox의 syslogd가 기본지원이지만 확장하고자 하면 설정하며, ubuntu가 rsyslogd 사용하여 나중에 이것으로 사용
IMAGE_INSTALL += "rsyslog" 

1.1. busybox의 사용할 경우 한계


busybox의 syslogd의 경우 좀 특별하게 설정이 되며, 설정에 따라 rotate의 기능이 기본제공이 되며 아래와 같이 동작된다.
예를들면, 200K 기준으로 2개의 Message들을 보관하고 2개로 Rotate를 진행하는데, 이 부분은 아래의 소스를 참조
  1. /var/log/messages    (latest)
  2. /var/log/messages.0  (200k까지 보관)

busybox 소스에서 200K로 1번의 rotate가 가능하며, 이부분은 소스에서 직접수정가능

이 busybox의 rotate 기능은  logrotate기능과는 너무 부족하므로 , logrotate를 별도로 사용할 경우 사용중지하는 것이 맞을 것 같다. 

/var/log/messages.0 관련내용 
  https://www.unix.com/unix-for-dummies-questions-and-answers/183205-why-there-var-adm-messages-0-messages-1-messages-2-messages-3-a.html


  • busybox-syslogd 와 rotate 기능 소스분석 
busybox의 syslogd 소스를 분석을 해보면 아래와 같이 200K 저장되는 Logrotate기능이 내부에 별도로 존재한다.
busybox 말고 별도의 Logrotate Package를 사용하고자 하면 CONFIG_FEATURE_ROTATE_LOGFILE 부분을 막자

.........
//config:config SYSLOGD
//config:	bool "syslogd (13 kb)"
//config:	default y
//config:	help
//config:	The syslogd utility is used to record logs of all the
//config:	significant events that occur on a system. Every
//config:	message that is logged records the date and time of the
//config:	event, and will generally also record the name of the
//config:	application that generated the message. When used in
//config:	conjunction with klogd, messages from the Linux kernel
//config:	can also be recorded. This is terribly useful,
//config:	especially for finding what happened when something goes
//config:	wrong. And something almost always will go wrong if
//config:	you wait long enough....
//config:config FEATURE_ROTATE_LOGFILE
//config:	bool "Rotate message files"
//config:	default y
//config:	depends on SYSLOGD
//config:	help
//config:	This enables syslogd to rotate the message files
//config:	on his own. No need to use an external rotate script.
.........
typedef struct logFile_t {
	const char *path;
	int fd;
	time_t last_log_time;
#if ENABLE_FEATURE_ROTATE_LOGFILE
	unsigned size;
	uint8_t isRegular;
#endif
} logFile_t;
.....

#if ENABLE_FEATURE_ROTATE_LOGFILE      // LOG 사이즈 200K 확인 
 .logFileSize = 200 * 1024,
 .logFileRotate = 1,
#endif

......

ENABLE_FEATURE_ROTATE_LOGFILE 관련소스확인
  https://git.busybox.net/busybox/tree/sysklogd/syslogd.c

  • Yocto 의 Busybox 관련 Recipe 분석

$ find . -name busybox*bb*  // Yocto의 busybox recipe 모두 확인하며, 중복되면 Version 높은것만 확인  
./meta-fsl-bsp-release/imx/meta-bsp/recipes-core/busybox/busybox_%.bbappend  // 3. 최종 bbappend 확인  
./poky/meta/recipes-core/busybox/busybox_1.30.1.bb        // 1. Main busybox recipe 
./poky/meta/recipes-core/busybox/busybox-inittab_1.30.1.bb       // SysVinit 일 경우 /etc/inittab 사용, 미사용
./poky/meta-skeleton/recipes-core/busybox/busybox_%.bbappend
./poky/meta-poky/recipes-core/busybox/busybox_%.bbappend  // 2. Main busybox recipe의 bbappend 반드시 확인  

// 1.Main busybox recipe 기반으로 분석 및 관련 cfg 와 patch 확인
$ cat ./poky/meta/recipes-core/busybox/busybox_1.30.1.bb  
require busybox.inc

SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
           file://busybox-udhcpc-no_deconfig.patch \
           file://find-touchscreen.sh \
           file://busybox-cron \
           file://busybox-httpd \
           file://busybox-udhcpd \
           file://default.script \
           file://simple.script \
           file://hwclock.sh \
           file://mount.busybox \
           file://syslog \
           file://syslog-startup.conf \
           file://syslog.conf \
           file://busybox-syslog.default \
           file://mdev \
           file://mdev.conf \
           file://mdev-mount.sh \
           file://umount.busybox \
           file://defconfig \
           file://busybox-syslog.service.in \
           file://busybox-klogd.service.in \
           file://fail_on_no_media.patch \
           file://run-ptest \
           file://inetd.conf \
           file://inetd \
           file://login-utilities.cfg \
           file://recognize_connmand.patch \
           file://busybox-cross-menuconfig.patch \
           file://0001-Use-CC-when-linking-instead-of-LD-and-use-CFLAGS-and.patch \
           file://mount-via-label.cfg \
           file://sha1sum.cfg \
           file://sha256sum.cfg \
           file://getopts.cfg \
           file://resize.cfg \
           ${@["", "file://init.cfg"][(d.getVar('VIRTUAL-RUNTIME_init_manager') == 'busybox')]} \
           ${@["", "file://mdev.cfg"][(d.getVar('VIRTUAL-RUNTIME_dev_manager') == 'busybox-mdev')]} \
           file://syslog.cfg \
           file://inittab \
           file://rcS \
           file://rcK \
           file://makefile-libbb-race.patch \
           file://0001-testsuite-check-uudecode-before-using-it.patch \
           file://0001-testsuite-use-www.example.org-for-wget-test-cases.patch \
           file://0001-du-l-works-fix-to-use-145-instead-of-144.patch \
           file://0001-dc.tests-fix-two-test-case-to-also-depend-on-DC_BIG.patch \
"
SRC_URI_append_libc-musl = " file://musl.cfg "

SRC_URI[tarball.md5sum] = "4f72fc6abd736d5f4741fc4a2485547a"
SRC_URI[tarball.sha256sum] = "3d1d04a4dbd34048f4794815a5c48ebb9eb53c5277e09ffffc060323b95dfbdc"

$ cat ./poky/meta-poky/recipes-core/busybox/busybox_%.bbappend // 2. Main busybox recipe의 bbappend 반드시 확인  
FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:"
///BPN 은 일반적으로 PN Package Name 의 Version 이라고 하는데 다만 prefix 와 suffix가 제거된상태 

$ ls ./poky/meta-poky/recipes-core/busybox/  // bbappend 에 적용되는 busybox directory 확인  
busybox  busybox_%.bbappend

// 3. 최종 bbappend 과 관련파일 반드시 확인  
$ cat ./meta-fsl-bsp-release/imx/meta-bsp/recipes-core/busybox/busybox_%.bbappend 

# look for files in the layer first
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://ftpget.cfg"

// Yocto의 경우 다른 *.cfg / *.patch 
$ ls ./poky/meta/recipes-core/busybox/busybox/


1.2. busybox의 logrotate 제거 

  • Busybox의 Config 설정변경 (Yocto)
기본 config에서 CONFIG_FEATURE_ROTATE_LOGFILE 설정제거(*.cfg 이용)
이미 IMAGE_INSTALL에 logrotate 추가했다면 상위 CONFIG를 제거

$ cat ./poky/meta-poky/recipes-core/busybox/busybox/poky-tiny/defconfig  // 기본 busybox Config
...
#
# System Logging Utilities
#
CONFIG_SYSLOGD=y
CONFIG_FEATURE_ROTATE_LOGFILE=y
CONFIG_FEATURE_REMOTE_LOG=y
CONFIG_FEATURE_SYSLOGD_DUP=y
CONFIG_FEATURE_SYSLOGD_CFG=y
CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
CONFIG_FEATURE_IPC_SYSLOG=y
CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
CONFIG_LOGREAD=y
CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
CONFIG_KLOGD=y
CONFIG_FEATURE_KLOGD_KLOGCTL=y
CONFIG_LOGGER=y

// Recipe의 *.cfg의 추가 config가 존재한다면, 이 값에 따라 변경 (주의)
$ cat ./poky/meta/recipes-core/busybox/busybox/syslog.cfg 
CONFIG_SYSLOGD=y
# CONFIG_FEATURE_ROTATE_LOGFILE is not set
CONFIG_FEATURE_REMOTE_LOG=y
CONFIG_FEATURE_SYSLOGD_DUP=y
CONFIG_FEATURE_SYSLOGD_CFG=y
CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256
CONFIG_FEATURE_IPC_SYSLOG=y
CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=64
CONFIG_LOGREAD=y
CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
CONFIG_FEATURE_KMSG_SYSLOG=y 

설정참고
  https://stackoverflow.com/questions/41868231/how-to-setup-syslog-in-yocto

  • syslog.conf 관련설정 부분 확인

$ find . -name syslog.conf
$ cat ./poky/meta/recipes-core/busybox/files/syslog.conf     // 이곳에서 /etc/syslog.conf 수정하면 적용됨
$ cat ./poky/meta/recipes-extended/sysklogd/files/syslog.conf  // /etc/syslog.conf 확장이라고 추정 

// sysVinit 일 경우, systemd만 사용할 경우는 제외(추후 확인)
$ cat ./poky/meta/recipes-core/busybox/files/syslog-startup.conf   
# This configuration file is used by the busybox syslog init script,
# /etc/init.d/syslog[.busybox] to set syslog configuration at start time.

DESTINATION=file  # log destinations (buffer file remote)
LOGFILE=/var/log/messages # where to log (file)
REMOTE=loghost:514  # where to log (syslog remote)
REDUCE=no   # reduce-size logging
DROPDUPLICATES=no  # whether to drop duplicate log entries
#ROTATESIZE=0   # rotate log if grown beyond X [kByte]
#ROTATEGENS=3   # keep X generations of rotated logs
BUFFERSIZE=64   # size of circular buffer [kByte]
FOREGROUND=no   # run in foreground (don't use!)
#LOGLEVEL=5   # local log level (between 1 and 8)


yocto 사용시 busybox syslogd 설정
  https://stackoverrun.com/ko/q/11519947


2. busybox 이외 Package 사용시 문제사항


Linux에서 필요한 기본 Util들을 다루며, Embedded에서는 대부분 BusyBox를 사용하지만, 좀 더 나은 binary를 사용하고자 하면, 
util-linux 와 각 Package들이 겹치고 다른 Package들과 겹치는 문제가 자주 생긴다. 


2.1 util-linux 와 busybox package 중복될 경우 

Yocto 내부에서 Package가 중복이 될 때 사용하는 class로 update-alternatives.class를 사용하며, 이 부분을 이해하자.

  • util-linux 의 Package List
Util Linux의 Package 관련사항 
  https://en.wikipedia.org/wiki/Util-linux


  • util-linux Package 추가 (중요)
대부분 Yocto에서 core-Image-base로 build 할 경우 util-linux를 미사용을 하는데, busybox대신 혹은 같이 사용할 경우 반드시 추가

IMAGE_INSTALL += "util-linux"


  • update-alternatives 관련사항
util-linux을 보면 동일한 프로그램이 여러 Package에서 중복 설치가 발생할 수 있으므로, 각각의 중복이 될 경우 대체(ALTERNATIVE)를 사용하여, 이를 해결하도록 한다.  

특히 busybox 와 binutils 와 util-linux 부분이 될 것 같으며, 이런 Package가 설치가 되어 중복이 되는 것을 피하기 위해서 이 class를 사용한다.
피하는 방법은 rename 방식으로 이를 link를 만들어 사용하는 것이므로 기본 사용법은 알아두자.
   
  ALTERNATIVE : 중복이 될 경우 대체가 될 command들을 기술 
  ALTERNATIVE_LINK_NAME: 중복이 되면 실제 위치들을 각 기술 
  ALTERNATIVE_PRIORITY: 중복이 되면, 이값을 각 기술하여 설치 우선순위 결정  
  ALTERNATIVE_TARGET: 기본으로 ALTERNATIVE_LINK_NAME값과 동일하며, 링크생성

Warrior(2.7)
Fido(1.8)



2.2 util-linux recipe 소스 분석 (intel)

먼저 IMAGE_INSTALL 에 util_linux가 추가되어있어야 동작가능하며,  busybox 설치되어있는 경우, 각 설정을 ALTERNATIVE로 설정  

  • util-linux 기본분석 (Intel Yocto)
  1. SRC_URI를 이용하여 util-linux 소스 download
  2. PACKAGES 에 사용하고자하는 util-linux-xxx PACKAGE들을 추가 
  3. FILE_util-linux-xxxx 사용할 PACKAGE들의 저장장소 설정 
  4. ALTERNATIVE_PRIORITY 전체 대체될 Package들 우선순위 busybox 조율 
  5. ALTERNATIVE_${PN} 안에 대체가 될 Package 들 기술
  6. ALTERNATIVE_util-linux-hwclock 상위와 동일하지만, PN 직접기술 
  7. ALTERNATIVE_LINK_NAME busybox 의 것들을 기술
  8. ALTERNATIVE_TARGET  default link를 생성하여 실제 사용결정   
Intel의 Yocto는 busybox 와 겹치는 경우 util-linux 실제 설정 


2.3 util-linux recipe 소스 분석 (poky)

먼저 IMAGE_INSTALL 에 util_linux가 추가되어있어야 동작하며, 기본소스를 보면 대체적으로, 이미 busybox 설치될 경우 util-linux로 대체됨 

  • Poky에서 util-linux 부분 분석
  1. SRC_URI를 이용하여 BP 즉 Base Recipe 이름과 동일하게 Download
  2. PACKAGES =+ "${PN}-swaponoff"  , 이 util-linux-swaponoff는 나중에 추가
  3. PACKAGES += "${@bb.utils.contains('PACKAGECONFIG', 'pylibmount', '${PN}-pylibmount', '', d)}"  는 util-linux-pylibmount  미리 추가 
  4. PACKAGE_PREPROCESS_FUNCS =+ "util_linux_binpackages "   python 함수 사용
  5. PACKAGESPLITFUNCS =+ "util_linux_libpackages"  python 함수 사용
  6. python 함수를 분석을 해봐도 PACKAGE는 두개만 사용함 

  • util_linux_binpackages 의 pkg_hook 함수 분석
  1. PACKAGE들을 읽어서 RRECOMMENDS_ 추가 (PACKAGE의 종속성문제)
  2. ALTERNATIVE_PN 가 존재하면 return 종료
  3. ALTERNATIVE_LINK_NAME 이 module 과 동일하면 ALTERNATIVE_PN 설정
    
  • util_linux_binpackages (말그대로 util-linux package 관리)
이상한 것은 PACKAGES do_split_packages로 구분관리하는것이 조금 이상하지만, 일단 이해만 하도록하자. 
.....
// 아래부터 시작되며, PACKAGES 대신 직접 함수로 Package 관리 
    bindirs = sorted(list(set(d.expand("${base_sbindir} ${base_bindir} ${sbindir} ${bindir}").split())))
    for dir in bindirs:
        do_split_packages(d, root=dir,
                          file_regex=r'(.*)', output_pattern='${PN}-%s',
                          description='${PN} %s',
                          hook=pkg_hook, extra_depends='')
    .......

  1. do_split_packages 함수 이용하여 PACKAGE관리하며, 매번 pkg_hook 호출 
  2. 중략
  3. 결론적으로 ALTERNATIVE를 비롯하여 FILE을 자동관리


추가시 busybox 대신 util-linux 용 package가 변경됨

3/08/2020

FTDI기반의 OpenOCD 설정 (FT2232)

1. FT2232H 의 기능 및 기본구성 

기본적으로 FT232x or CP2102x 관련 칩들은 USB To Serial 기능을 가지고 있다. 
하지만, FT22x의 경우 USB To Serial의 기능도 제공하지만, 부가적인 기능을 제공해준다. 
예를들면, FT2232H의 경우 FTDI의 MPSSE의 기능을 이용하여 SPI/I2C 비롯하여 JTAG기능까지 지원 가능하다.

우선 FT2232H Mini Module의 기본구조를 살펴보면, 2개의 Channel을 제공하며, 원하는대로 변경사용가능하다. 






상위 Connect PIN Map을 보면 Channel은 CN2 와 CN3로 구분되며, 각각의 Channel의 핀구성을 살펴보자. 

  • FTDI의 FT2232H Miniboard Manual (상위보드)
좀 더 상위 FT2232H Mini Board의 동작구성을 알고 싶다면, 아래의 Module Manual 참조 
  https://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf


  • FDDI Device Driver
  https://www.ftdichip.com/Drivers/D2XX.htm


1.1 FT2232H Board 설정 및 기본이해 



나의 경우는 상위보드를 구입 후 USB Host의 전원기반으로 사용할 것이므로 USB Bus Power로 설정로 설정하여 구성할 것이다. 
만약 전원이 부족하다면, 어쩔수 없이 USB Self-Powered부분을 참조해서 구성하자. 

상위 Board의 Connect Pin Map 보고 아래와 같이 연결해주자. 

1) Connect VBUS to VCC
  1. CN3-1 (VBUS USB) 와 CN3-3 (VCC 5V) 연결 
* USB VBUS -> 5V 전원공급하여 3.3V전원 공급가능 
2) Connect V3V3 to VIO
  1. CN2-1 (V3V3 OUT) 와 CN2-11 (VIO), CN2-21 (VIO) 연결  ( 3.3V )
  2. CN2-3 (V3V3 OUT) 와 CN3-12 (VIO) 연결 (3.3V)
  3. CN2-5 (V3V3 OUT) 와 CN3-22 (VIO) 연결 (3.3V)

상위 Board Manul 에서 Table 참조



1.2  FT2232 지원기능 및 동작 

기본적으로 USB의 Dual channel로 USB Device 2개로 연결이 되어 아래와 같이 다양하게 동작가능
UART일 경우 VCP( Virtual COM Port)설정이 가능
  1. Single chip USB to dual channel UART (RS232,RS422 or RS485).
  2. Single chip USB to dual channel FIFO.
  3. Single chip USB to dual channel JTAG.
  4. Single chip USB to dual channel SPI.
  5. Single chip USB to dual channel I2C.
  6. Single chip USB to dual channel Bit-Bang.
  7. Single chip USB to dual combination of any of above interfaces.
  8. Single chip USB to Fast Serial Optic Interface.
  9. Single chip USB to CPU target interface (as memory), double and independent.
  10. Single chip USB to Host Bus Emulation (as CPU).
  11. PDA to USB data transfer
  12. USB Smart Card Readers
  13. USB Instrumentation
  14. USB Industrial Control
  15. USB MP3 Player Interface
  16. USB FLASH Card Reader / Writers
  17. Set Top Box PC - USB interface
  18. USB Digital Camera Interface
  19. USB Bar Code Readers
아래의 DataSheet를 보면, 상당히 많은 기능을 제공을 해주는데, 이 많은 기능중에 몇개밖에 사용하지 않는다는게, 너무 안타깝다. 

FT2232H Datasheet 
  https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf




  • MPSSE Mode (JTAG/SPI/I2C)
JTAG을 사용하기위해서는 MPSSE Mode 설정 및 아래의 문서의 Example 반드시확인
  https://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf



  • MPSSE Mode (JTAG/SPI/I2C)의 설정 Flow 
사용법은 아래의 D2XX Programmer GUIDE참조



  • D2XX Programmer GUIDE (FD_xxx API)
상위 MPSSE Programing을 이해를 위해 각 FD_xxx API 관련이해
  https://www.ftdichip.com/Support/Documents/ProgramGuides/D2XX_Programmer's_Guide(FT_000071).pdf


  • JTAG을 Control 하기위해서 Opcode 관련부분
  https://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf


  • JTAG 관련문서
  https://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf
  https://www.ftdichip.com/Support/Documents/AppNotes/AN_110_Programmers_Guide_for_High_Speed_FTCJTAG_DLL.pdf


1.3 Window에서 FT2232 Device USB 연결 

상위 FT2232 Board를 Self Power로 설정 후 USB로 Window에 연결 후 각 설정을 살펴보자

  • 장치관리자->USB Controller
  1. USB Composite Device 
  2. USB Serial Converter A  (Vendor ID: 0x0403 Product ID: 0x6010)
  3. USB Serial Converter B
    
  • 장치관리자->Port
  1. Serial Port로 2개로 기본인식됨 (FTDI CDM Driver로 연결)



1.4 FT2232H Module의 최종 연결상태 

  1. USB Self Power로 연결 
  2. JTAG 연결 





2. Raspberry Pi3 의 JTAG PIN 구성 및 설정 


Raspberry Pi3 의 Pinmux ALT4/ALT5로 변경사용
** ALT4 와 ALT5의 JTAG의 설정차이는 TRST의 사용여부
** 기본적으로 JTAG은 TCLK/TDI/TDO/TMS는 반드시 필요하며, RTCK 옵션 

https://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/



Raspberry Pi3 B JTAG 관련정보 
  https://metebalci.com/blog/bare-metal-raspberry-pi-3b-jtag/
  https://www.suse.com/c/debugging-raspberry-pi-3-with-jtag/
  https://lb.raspberrypi.org/forums/viewtopic.php?t=143938
  https://medium.com/@burstaccessing/debugging-raspberry-pi-3-b-475452974f21
  https://wiki.aalto.fi/download/attachments/84747235/presentation.pdf?version=1&modificationDate=1386936615719&api=v2

Raspberry Pi3에서 JTAG사용 
  https://github.com/synthetos/PiOCD/wiki/Using-a-Raspberry-Pi-as-a-JTAG-Dongle



  • Raspberry Pi3 B 의 ALT4 사용 (GPIO22/23 미사용)

Pin #Function
GPIO22ARM_TRST
GPIO23ARM_RTCK
GPIO24ARM_TDO
GPIO25ARM_TCK
GPIO26ARM_TDI
GPIO27ARM_TMS

RTCLK을 필요없으며, 이 부분은 JTAG관련부분 참조
  1. Output Pin : TDI/TMS/TCK/TRST 
  2. Input Pin: TDO 

  • Raspberry Pi3 B  와 FT2232 Channel A or B 연결  
  1. Pin 15: GPIO 22 : TRST        AD4/BD4
  2. Pin 18: GPIO 24 : TDO         AD2/BD2
  3. Pin 22: GPIO 25 : TCLK        AD0/BD0  
  4. Pin 37: GPIO 26 : TDI          AD1/BD1
  5. Pin 13: GPIO 27 : TMS         AD3/BD3
  6. Pin 06: GROUND               CN2-2/GND

Raspberry Pi JTAG
TRST은 옵션이지만, Raspberry Pi에서 없으면 동작이 안됨 주의



Raspberry Pi JTAG Pin 및 ALT4/5 확인 
  https://www.raspberrypi.org/documentation/hardware/computemodule/datasheets/rpi_DATA_CM_1p0.pdf


Raspberry Pi3 의 PIN 구성
https://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/

https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/the-gpio-connector



  • Raspberry Pi3 B 의 JTAG ALT4 설정방법 
ALT4로 설정시 TRST도 같이 설정됨
pi@raspberrypi:~ $ cat /boot/config.txt  // enable_jtag_gpio 추가 (ALT4 자동설정) sudo vi 이용 
....
enable_jtag_gpio=1
.....

pi@raspberrypi:~ $ vcgencmd get_config arm_freq
arm_freq=1200

pi@raspberrypi:~ $ vcgencmd get_config enable_jtag_gpio   // 설정된 값 확인
enable_jtag_gpio=1

pi@raspberrypi:~ $ raspi-gpio get 22         // PIN 확인 
GPIO 22: level=0 fsel=3 alt=4 func=ARM_TRST
pi@raspberrypi:~ $ raspi-gpio get 23
GPIO 23: level=0 fsel=3 alt=4 func=ARM_RTCK
pi@raspberrypi:~ $ raspi-gpio get 24
GPIO 24: level=1 fsel=3 alt=4 func=ARM_TDO
pi@raspberrypi:~ $ raspi-gpio get 25
GPIO 25: level=0 fsel=3 alt=4 func=ARM_TCK
pi@raspberrypi:~ $ raspi-gpio get 26
GPIO 26: level=0 fsel=3 alt=4 func=ARM_TDI
pi@raspberrypi:~ $ raspi-gpio get 27
GPIO 27: level=0 fsel=3 alt=4 func=ARM_TMS

 //만약 PIN을 직접 변경하고 싶다면 gpio=0-27=a2 (ALT2) 이런식으로 설정하면됨 세부내용은 Manual 참조 

pi@raspberrypi:~ $ ls /lib/firmware


  • Raspberry Pi3 B 의 JTAG ALT5 설정방법 
pi@raspberrypi:~ $ cat /boot/config.txt  // JTAG ALT5 수동설정 
....
gpio=4-6=a5
gpio=12,13=a5
.....

pi@raspberrypi:~ $ raspi-gpio get 4
GPIO 4: level=1 fsel=2 alt=5 func=ARM_TDI
pi@raspberrypi:~ $ raspi-gpio get 5
GPIO 5: level=0 fsel=2 alt=5 func=ARM_TDO
pi@raspberrypi:~ $ raspi-gpio get 6
GPIO 6: level=0 fsel=2 alt=5 func=ARM_RTCK
pi@raspberrypi:~ $ raspi-gpio get 12
GPIO 12: level=0 fsel=2 alt=5 func=ARM_TMS
pi@raspberrypi:~ $ raspi-gpio get 13
GPIO 13: level=0 fsel=2 alt=5 func=ARM_TCK


/boot/config 관련내용
      https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md
      https://www.raspberrypi.org/documentation/configuration/config-txt/


    2.1 Raspberry Pi의 DTS 설정변경 

    JTAG 설정확인 및 이외에 다른 기능을 직접수정하여, 테스트하고 싶다면, 아래와 같이 Device Tree 부분을 직접 수정하여 진행

    • Device Tree 확인 및 수정방법
    pi@raspberrypi:~ $ cat /proc/device-tree/soc/gpio@7e200000/jtag_gpio22/name   //Device Tree 확인 (ALT4)
    jtag_gpio22
    
    pi@raspberrypi:~ $ cat /proc/device-tree/soc/gpio@7e200000/jtag_gpio4/name   //Device Tree 확인 (ALT5)
    jtag_gpio4
    
    pi@raspberrypi:~ $ dtc -I fs /proc/device-tree  //Device Tree Syntax 확인
    or
    pi@raspberrypi:~ $ dtc -I fs /proc/device-tree > current.dts   //Device Tree Syntax 저장
    
    //DTB 직접 수정 후 Merge 한 후 diff 하는방법 
    
    pi@raspberrypi:~ $ dtc -I fs -O dtb -o base.dtb /proc/device-tree   // /proc/device-tree DTB 저장
    
    pi@raspberrypi:~ $ dtmerge base.dtb merged.dtb - sd_overclock=62   // base.dtb 와 overlay 변경사항 합쳐서 merged.dtb 저장 
    
    pi@raspberrypi:~ $ dtdiff base.dtb merged.dtb // base.dtb 와 merged.dtb 차이비교 
    --- /dev/fd/63  2020-08-24 16:55:41.175892749 +0900
    +++ /dev/fd/62  2020-08-24 16:55:41.175892749 +0900
    @@ -910,7 +910,7 @@
                    };
    
                    mmc@7e202000 {
    -                       brcm,overclock-50 = <0x0>;
    +                       brcm,overclock-50 = <0x3e>;
                            brcm,pio-limit = <0x1>;
                            bus-width = <0x4>;
                            clocks = <0x8 0x14="">;
    
    

    Raspberry Pi3 Device Tree
    Device Tree기반으로 Pin Configuration 구성확인
      https://www.raspberrypi.org/documentation/configuration/pin-configuration.md
      https://www.raspberrypi.org/documentation/configuration/device-tree.md


    3. OpenOCD 기본동작과 이해 

    Window 혹은 Linux에서 GDB에서 OpenOCD Server로 연결되어 JTAG을 Control하기 위해서 libusb or libWinUSB를 이용하여
    직접 User Interface에서 USB에서 Control하여 JTAG을 제어를 한다.

    https://www.allaboutcircuits.com/technical-articles/getting-started-with-openocd-using-ft2232h-adapter-for-swd-debugging/

    OpenOCD 와 FT2232
      https://www.allaboutcircuits.com/technical-articles/getting-started-with-openocd-using-ft2232h-adapter-for-swd-debugging/
      https://dzone.com/articles/jtag-debugging-the-esp32-with-ft2232-and-openocd
      http://openocd.org/doc/html/Debug-Adapter-Hardware.html

    GDB 연결
      http://openocd.org/doc/html/GDB-and-OpenOCD.html

    Telnet Server Port 설정
    GDB Server Port 설정
    TCL Server Port 설정
      http://openocd.org/doc/html/General-Commands.html

    Raspberry PI 기반의 OpenOCD전체사용법
      https://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/

    FT2232H 관련사항
      http://openocd.org/doc/html/Debug-Adapter-Hardware.html


    3.1 Window 용 OpenOCD Download

    • Download Window for OpenOCD (필수)
    Window용 Pre-built OpenOCD file
      https://gnutoolchains.com/arm-eabi/openocd/

    • Ecplise OpenOCD for Window (옵션)
      https://gnu-mcu-eclipse.github.io/openocd/install/


    3.2 FTDI (FT2232) Libusb 설정 

    Window에서 Libusb관련부분 설정을 변경하기 위해서 장치관리자에서 USB Driver를 변경해야하는데 관련 Tool을 Download하여 쉽게 변경하자 

    • Libusb/WinUSB (USBDriverTool) 설정 Tool Download 
    이미 상위 Window OpenOCD 내부에 존재하므로 별도의 설치를 할 필요 없지만 없다면 별도 download
    libusb에러가 발생시 FTDI의 CDM의 Driver가 설치되어있는데, libusb설치진행
      https://visualgdb.com/UsbDriverTool/

    • Libusb/WinUSB (Zadig) 설정 Tool Download
    USBDriverTool 과 동일한 기능으로 Window에서 libusb를 사용하기위해서 사용하는 Tool
    아래의 OpenOCD 내부의  drivers/USBdriverTool.exe 와 동일기능 
    만약 Device 가 나오지 않는다면, Option->List All Devices 를 체크 검색가능 
      https://zadig.akeo.ie/


    상위 두 개의 Tools 중 하나를 Download하여 아래와 같이 Window USB Driver를 변경진행


    FT2232 Board의 Channel A만 설정하여 진행할 것이며,
    상위 Window용 OpenOCD 내부에 drivers/USBdriverTool.exe 가 존재하며 이를 실행

    • Install Libusb -WinUSB 설정 (USB Serial Converter A)
    libusb의 제어를 위해서 상위에서 Download 한 USBdriverTool을 사용하여 libusb 설치진행
    장치관리자에서 범용직렬버스 컨트롤러 에서 libusb 로 USB Serial Converter A 이동
    기존의 Serial에서 libusb기반 Driver로변경 (아래 둘 중하나 선택)
    1. libus -WinUSB
    2. WinUSB 




    FT2232 OpenOCD Example
      https://mcuoneclipse.com/2019/10/20/jtag-debugging-the-esp32-with-ft2232-and-openocd/

    • 장치관리자
    libusb(WinUSB) devices ->USB Serial Converter A (Libusb -WinUSB) 변경확인



    • FTDI CDM
    Window의 경우 FTDI의 경우 처음 CDM Serial Driver로 설치가 되어있는데, 이부분을 libusb를 통하여 JTAG으로 변경해야함
      https://www.ftdichip.com/Support/Documents/InstallGuides/AN_396%20FTDI%20Drivers%20Installation%20Guide%20for%20Windows%2010.pdf
      https://www.ftdichip.com/Support/Utilities/CDM_Uninst_GUI_Readme.html


    3.3 OpenOCD 실행

    OpenOCD의 Interface의 설정은 기본적으로 JTAG Pin의 초기화로 libusb를 통해 모든 Pin을 설정이 가능하며, 각 Interface 와 Version에 따라 사용법이 다르다.
    Linux 와 Window도 다르기 때문에 주의를 해야함

    Config 파일은 하나로 만들어도 상관없지만,보통 두개로 나누어 사용한다 (3개도 가능)
    1. Interface Config :  JTAG 에 관련된 설정 
    2. Target config : Target Board에 관련된 설정 

    • Window에서 Bat 파일 (OpenOCD.bat)
    아래와 같이 Simple하게 실행하도록 본인이 각각 Batch 파일을 만들어서 실행하자

    @ECHO OFF
    TITLE OpenOCD TEST
    rem Author: Jeonghun Lee
    rem TEST OpenOCD
    ECHO ------------------------------------------------------------------------------------------------------
    ECHO Start to exec OpenOCD 
    ECHO.
    ECHO.
    bin\openocd.exe -f share\openocd\scripts\interface\ftdi\test.cfg  -f share\openocd\scripts\target\raspberrypi3.cfg
    ECHO.  
    ECHO.   
    ECHO ------------------------------------------------------------------------------------------------------
    PAUSE
    


    @ECHO OFF
    TITLE OpenOCD TEST
    rem Author: Jeonghun Lee
    rem TEST OpenOCD
    ECHO ------------------------------------------------------------------------------------------------------
    ECHO Start to exec OpenOCD 
    ECHO.
    ECHO.
    bin\openocd.exe -f test.cfg  -f raspberrypi3.cfg
    ECHO.  
    ECHO.   
    ECHO ------------------------------------------------------------------------------------------------------
    PAUSE
    


    3.4 OpenOCD Interface/target 설정

    위에서 설명했듯이 보통 Interface 와 Target으로 구분하여 설정하지만, 귀찮다면 하나로 설정을 해도 상관없다

    • USB Vendor ID: FTDI 0x0403
    1. Product ID (2232C/D/H):  0x6010
    2. Product ID (4232H) : 0x6011

    FT2232D USB to JTAG Hardware (Sample Config)
      http://www.baresystemdesign.com/index.php?section=hardware&hw=jtag

    • Interface 기본설정 (Raspberry Pi3)
    share\openocd\scripts\interface\ftdi\test.cfg
    ### ftdi/test.cfg 
    ###
    
    #
    # GDB/Telnet Port 설정
    #
    telnet_port 4444
    gdb_port 3333
    
    #adapter_khz     1000
    
    #
    # MPSSE (Multi-Protocol Synchronous Serial Engine) 
    # src/jtag/drivers/mpsse.c 
    # support TYPE_FT2232C/TYPE_FT2232H/TYPE_FT4232H/TYPE_FT232H
    # 
    #interface ftdi
    adapter driver ftdi
    adapter speed 500
    
    #
    # select JTAG mode (JTAG/SWD) 중 선택 
    #
    # transport select swd
    
    transport select jtag
    
    #
    # FT2232H USB VID PID
    # lsusb 로 확인가능 
    ftdi_vid_pid 0x0403 0x6010  
    
    #
    # FT2232H Channel A or B (상위 Board 참조)
    # ftdi_channel 0
    # ftdi_channel 1
    #
    ftdi_channel 0
    
    #
    # FT2232H Channel A or B not used
    #
    #ftdi_device_desc "FT2232H_CH_A"
    
    #
    # GPIO Init Setting 
    # ftdi_layout_init data (high:1, low:0)  direction (out:1,in:0)
    #
    # TRST 0x0010 0x0010   Output Pull up 설정
    # TRST은 반드시 연결하며, Pin 정의는 별도 필요없으며, 사용안함  
    #  
    #
    ftdi_layout_init 0x0018 0x001b
    
    ## 상위 설정값 확인 (나의경우 아래와 같이 사용)
    ##                          0x001b    0x0018
    ## Channe A/B   Pin      In/Out  High/Low (상위 16bit/2Byte 구성)
    # ADBUS0  Bit0  JTAG_TCK     Out 
    # ADBUS1  Bit1  JTAG_TDI     Out 
    # ADBUS2  Bit2  JTAG_TDO     In       
    # ADBUS3  Bit3  JTAG_TMS     Out     (Pull Up)
    # ADBUS4  Bit4  JTAG_TRST_L  Out     (Pull Up)
    # ADBUS5  Bit5  NC
    # ADBUS6  Bit6  NC
    # ADBUS7  Bit7  NC
    
    # ACBUS0  Bit8  NC
    # ACBUS1  Bit9  NC  
    # ACBUS2  Bit10 NC
    # ACBUS3  Bit11 NC
    # ACBUS4  Bit12 NC
    # ACBUS5  Bit13 NC
    # ACBUS6  Bit14 NC
    # ACBUS7  Bit15 NC
    #


    • Interface의 Pin 설정이해 와 Pin 정의  
    상위 ftdi_channel 0 or 1 로 channel A or B로 설정 후 각 Pin의 Direction 및 Pull up/down 설정을 하자

    #
    #
    # FT2232H Channel A (현재 Channel A)
    # ftdi_channel 0  
    # FT2232H Channel B
    # ftdi_channel 1
    #
    ftdi_channel 0
    
    # Channel A or B
    # GPIO Init Setting 
    # ftdi_layout_init data (high:1, low:0)  direction (out:1,in:0)
    #
    #                0x8= 0b1000  0xB = 0b1011
    #ftdi_layout_init 0x0008 0x000b
    
    ftdi_layout_init 0x0018 0x001b
    ftdi_layout_signal nTRST -data 0x0010 -oe 0x0010
    
    
    # various examples (다양한 예제를 위해 참고)
    # ftdi_layout_signal GIO1 -data 0x0100
    # ftdi_layout_signal GIO2 -data 0x0200
    # ftdi_layout_signal GIO3 -data 0x0400
    # ftdi_layout_signal GIO4 -data 0x0400
    
    ###### Channel A/B
    # ADBUS0  Bit0  JTAG_TCK     Out 
    # ADBUS1  Bit1  JTAG_TDI     Out 
    # ADBUS2  Bit2  JTAG_TDO     In
    # ADBUS3  Bit3  JTAG_TMS     Out  (Pull Up)
    # ADBUS4  Bit4  JTAG_TRST_L  Out  (Pull Up)
    # ADBUS5  Bit5  NC
    # ADBUS6  Bit6  NC
    # ADBUS7  Bit7  NC
    
    # ACBUS0  Bit8  NC
    # ACBUS1  Bit9  NC  
    # ACBUS2  Bit10 NC
    # ACBUS3  Bit11 NC
    # ACBUS4  Bit12 NC
    # ACBUS5  Bit13 NC
    # ACBUS6  Bit14 NC
    # ACBUS7  Bit15 NC

    • Interface의 TRST/SRST Pin 정의
    TRST/SRST은 옵션이며, 필수사항이 아니며 필요할 경우 사용하자
    1. TRST은 TRST에 연결하여 사용하며, GPIO Control
    2. SRST의 TARGET Board의 HW RESET 부분에 연결설정 GPIO Control
    #
    #
    # General JTAG Setting 
    # ftdi_layout_init 0x0008 0x000b
    #
    # General JTAG + nTRST/nSRST 추가 
    ftdi_layout_init 0x0288 0x028b
    
    #
    # Creat a signal with the name 
    # ftdi_layout_signal name [-data|-ndata data_mask] [-input|-ninput input_mask] [-oe|-noe oe_mask] [-alias|-nalias name]
    # 이름과 같이 Signal을 정의
    #
    # 내부적으로 input 과 output 을 연결하는 방식을 설정가능 
    #
    # Data가 나가는 방식결정 (Output) 
    # -ndata: inverting data inputs
    # -data:  non-inverting inputs. 
    #  data_mask 
    #
    # 상위에서 결정된 Data input이 어디에 있는 output으로 연결할 것인지 결정하며, output/ not output 
    # -oe : output enable input to output butter 연결        
    # -noe: not output enable input to output butter 연결
    #  oe_mask
    #
    #  The options -input and -ninput specify the bitmask for pins to be read with the method ftdi_get_signal.
    
    ftdi_layout_signal nTRST -data 0x0200 -oe 0x0200
    ftdi_layout_signal nSRST -data 0x0080 -oe 0x0080
    

    아직 -noe 과 -ndata를 실험해보지 못했음
    #
    # -noe 0x0040 : JTAG_TDO Input 설정 
    #
    #ftdi_layout_signal nTRST -ndata 0x0200 -noe 0x0040
    #ftdi_layout_signal nSRST -ndata 0x0080 -noe 0x0040
    


    Interface config 관련설정 Adapter관련부분 

    상위 설정을 이해하려면 아래의 Manual을 이해해야 하지만, Version 과 OS를 주의
      http://openocd.org/doc/html/Debug-Adapter-Configuration.html

    OpenOCD는 다양한 JTAG 및 다양한 Device를 JTAG기능으로 사용가능하므로 체크
      http://openocd.org/doc/html/Debug-Adapter-Hardware.html

    • Target config
    기본이해
    1. reset_config:  none or trst_and_srst // 나의 경우 미사용 none
    2. adapter_khz:  상위 adapter speed 와 동일한 기능이며 속도
    3. jtag_ntrst_delay:  TRST을 사용할 경우
    세부설정 
    1. _CHIPNAME: CPU Name (본인이 정의)
    2. _DAP_TAPID: Test Access Ports ID로 이미 정해져 있으며, 이 값으로 생각하고 찾음 
    3. jtag newtap : 상위 Test Access Ports의 ID와 찾아서 비교하고 생성 
    4. dap create  : Debug Access Port 정의 

    세부사용법은 아래사이트 참조
      http://openocd.org/doc/html/TAP-Declaration.html

    ARM CORE 4개의 CTI 와 DEBUG 주소설정
      https://developer.arm.com/documentation/ddi0464/f/debug/external-debug-interface/memory-map

    share\openocd\scripts\target\rpi3.cfg (참고 version)

    # Credits to Petr Tesarik from SUSE who provided this updated configuration,
    # source: https://www.suse.com/c/debugging-raspberry-pi-3-with-jtag/
    transport select jtag
    # we need to enable srst even though we don't connect it
    reset_config trst_and_srst
    #adapter_khz 1000  
    jtag_ntrst_delay 500
    if { [info exists CHIPNAME] } {
      set _CHIPNAME $CHIPNAME
    } else {
      set _CHIPNAME rpi3
    }
    
    #
    # Main DAP
    #
    if { [info exists DAP_TAPID] } {
       set _DAP_TAPID $DAP_TAPID
    } else {
       set _DAP_TAPID 0x4ba00477
    }
    
    jtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -enable
    dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap
    
    set _TARGETNAME $_CHIPNAME.a53
    set _CTINAME $_CHIPNAME.cti
    set DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}
    set CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}
    set _cores 4
    for { set _core 0 } { $_core < $_cores } { incr _core } {
    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 0 \
            -ctibase [lindex $CTIBASE $_core]
    target create $_TARGETNAME.$_core aarch64 \
            -dap $_CHIPNAME.dap -coreid $_core \
            -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core
    $_TARGETNAME.$_core configure -event reset-assert-post "aarch64 dbginit"
        $_TARGETNAME.$_core configure -event gdb-attach { halt }
    } 
    

    본인이 원하는 곳을 상위 것을 참조하여, 아래와 같이 수정하여 사용하도록 하자
    share\openocd\scripts\target\raspberrypi3.cfg

    # ref: http://www.raspberrypi.org/forums/viewtopic.php?f=72&t=100268
    #    : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0464f/ch10s06s01.html
    
    #adapter speed 1000
    #adapter srst delay 400
    ## 현재 trst 과 srst를 사용하지 않으며, TRST은 Pull up 만 직접설정 
    reset_config none
    
    if { [info exists CHIPNAME] } {
    set _CHIPNAME $CHIPNAME
    } else {
    set _CHIPNAME bcm2837
    }
    
    #
    # Main DAP(Debug  Access Port), TAP(Test Access Port)
    #
    if { [info exists DAP_TAPID] } {
       set _DAP_TAPID $DAP_TAPID
    } else {
       set _DAP_TAPID 0x4ba00477
    }
    
    #
    # TAP의 Scan Chain/Autoprobing 작업으로 IR capture 와 TAPID를 확인가능 
    #
    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -enable
    
    #
    # DAP는 ARM에서 사용되는 Debug Access Point로 관련부분을 설정 
    #
    dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
    
    proc bcm2837_create_core {_CHIPNAME corenum corebase ctibase} {
     set _TARGETNAME $_CHIPNAME.cpu.$corenum
     cti create $_CHIPNAME.cti.$corenum -dap $_CHIPNAME.dap -ctibase $ctibase
     target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -coreid $corenum -dbgbase $corebase -rtos hwthread -cti $_CHIPNAME.cti.$corenum
    
     $_TARGETNAME configure -event reset-assert-post "aarch64 dbginit"
     $_TARGETNAME configure -event gdb-attach { halt }
    }
    
    bcm2837_create_core $_CHIPNAME 0 0x80010000 0x80018000
    bcm2837_create_core $_CHIPNAME 1 0x80012000 0x80019000
    bcm2837_create_core $_CHIPNAME 2 0x80014000 0x8001A000
    bcm2837_create_core $_CHIPNAME 3 0x80016000 0x8001B000
    target smp $_CHIPNAME.cpu.0 $_CHIPNAME.cpu.1 $_CHIPNAME.cpu.2 $_CHIPNAME.cpu.3
    

    상위 동작을 이해하고 싶다면, 우선 JTAG의 동작에 대해서 알아두도록하자.

    Scan Chain/Autoprobing 과 DAP 정의 
      http://openocd.org/doc/html/TAP-Declaration.html

    JTAG Reset
      http://openocd.org/doc/html/Reset-Configuration.html

    Open OCD Config example
      https://www.allaboutcircuits.com/technical-articles/getting-started-with-openocd-using-ft2232h-adapter-for-swd-debugging/
      https://rtime.felk.cvut.cz/hw/index.php/FTDI2232_JTAG
      https://gnu-mcu-eclipse.github.io/


    3.5 OpenOCD 실행시 점검사항


    • HW 관련사항 점검사항 
    TMS/TCLK/TDI 는 FT2232에서 나가는 OUTPUT이므로 3.3V로 정확하게 나오며, 각 Clock이 존재하는 지 확인
    TDO 는 Target Board에서 오는 결과 값이므로 이것이 제대로 동작이 안되면, Target Board의 Pin 연결 및 설정을 비롯하여 Board 손상까지 생각해야한다


    • FT2232 HW 문제사항 
    나의 경우 Channel A가 망가져서 TCLK의 전압이 3.3V가 나오지 않고 2.3V로 나와서 오동작하는 경우가 생겼으며, 이유는 Pin을 잘못 꽂은 후 사용하여 손상된것 같다.
    그래서 Channel B로 다시 연결하여 진행하였더니, 잘 동작함


    • OpenOCD 실행시 문제사항 (문제없음)
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED  //처음 VCP Open하기 때문에 생기는 에러라고 하며 이후부터 문제없음 
    ....
    


    open_matching_device 함수참조
      http://openocd.zylin.com/gitweb?p=openocd.git;a=blob;f=src/jtag/drivers/mpsse.c;h=7488d9dd877c65a97a8b88057a3299d25001e3de;hb=d214cadfef7ba75c7c52849c7946d32f0ad8b668
      https://mcuoneclipse.com/2019/10/20/jtag-debugging-the-esp32-with-ft2232-and-openocd/

    • OpenOCD 실행시 문제사항-B (Raspberry Pi3 Board 손상) 
    Raspberry Pi의 JTAG 부분의 문제로 생각했으나, Raspberry Pi3 의 손상까지도 추측했으나,
    TRST과 GND 연결 후 아래 문제가해결됨

    //HW의 증상은 TDI/TMS/TCLK을 보면 다 동작을 하지만, TDO의 값은 Level 1만 유지하며 변화가 없음
    Open On-Chip Debugger 0.10.0 (2020-03-10) [https://github.com/sysprogs/openocd]
    Licensed under GNU GPL v2
    libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
    Info : clock speed 500 kHz
    Error: JTAG scan chain interrogation failed: all ones    //Scan chain/Autoprobing 진행하며, TDO가 항상 1인 상태 
    Error: Check JTAG interface, timings, target power, etc.
    Error: Trying to use configured scan chain anyway...
    Error: bcm2837.cpu: IR capture error; saw 0x0f not 0x01   //상위 configu의 jtag newtap의 -ircapture 0x1 와 irmask 참조 
    Warn : Bypassing JTAG setup events due to errors
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    Error: Invalid ACK (7) in DAP response
    Error: JTAG-DP STICKY ERROR
    .......
    

    동일한 증상
    TDO Pin을 GND로 연결하면 all zero 변경되어 나의 JTAG의 올바르게 동작됨을 확인
    1. Error: JTAG scan chain interrogation failed: all ones
    2. Error: JTAG scan chain interrogation failed: all zeros
    다른 PIN들도 동작확인 완료 
      https://github.com/syncsrc/jtagsploitation/issues/3


    • OpenOCD가 Raspberry Pi 연결하여 동작할 경우 
    TRST/TCLK/TMS/TDI/TDO/GND 를 모두 연결 후 동작하면 GDB에서 멈춤

    Open On-Chip Debugger 0.10.0 (2020-03-10) [https://github.com/sysprogs/openocd]
    Licensed under GNU GPL v2
    libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Hardware thread awareness created
    Info : Listening on port 6666 for tcl connections
    Info : Listening on port 4444 for telnet connections
    Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
    Info : clock speed 500 kHz
    Info : JTAG tap: bcm2837.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
    Info : bcm2837.cpu.0: hardware has 6 breakpoints, 4 watchpoints
    Info : bcm2837.cpu.1: hardware has 6 breakpoints, 4 watchpoints
    Info : bcm2837.cpu.2: hardware has 6 breakpoints, 4 watchpoints
    Info : bcm2837.cpu.3: hardware has 6 breakpoints, 4 watchpoints
    Info : Listening on port 3333 for gdb connections  
    

    설치된 VS의 arm-none-eabi-gdb 실행 target remote localhost:3333 테스트가능
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Linux\gcc_arm\bin


    3.6 FT232 계의 OpenOCD 사용 

    FT232H도 지원하고 있으며, 더 싼 가격으로 이용하자
      https://www.raspberrypi.org/forums/viewtopic.php?t=243625
      https://github.com/metebalci/baremetal-rpi/blob/master/rpi3.cfg
      https://mobaxterm.mobatek.net/download-home-edition.html

    현재 생각으로 Raspberry Pi3에 FT2232H를이용하여 JTAG으로 연결하고, OpenOCD를 이용할 방법을 찾아봐야겠다.


    4. Visual Studio 와 GDB 연결방법 

    FH2232의 JTAG을 이용하여 OpenOCD와 GDB를 연결 한 후, 최종적으로 GDB기반으로 JTAG을 이용 Debugging 하고 싶어서,아래와 같이 설치를 진행을 해본다.

    • Download Visual Studio Community Version (for Free)
    Visual Studio Community Version(무료 Version) 설치진행
      https://visualstudio.microsoft.com/ko/vs/community/?rr=https%3A%2F%2Fvisualgdb.com%2Fdownload%2F

    상위  Visual Studio Community를 설치를 진행을 하면, 손쉽게 Raspberry Pi를 SSH를 통해 연결이 가능하며,
    내부 Compiler로 빌드 후 gdbserver를 이용하여 손쉽게 debug 실행화면을 볼 수 있다.


    Visual Studio에서 SSH 설정 및 Project Property에서 gdbserver로 변경




    $ sudo apt install gdbserver 
    
    $ ps -aux | grep gdb   //gdbserver 동작확인 
    pi       25709  0.1  0.1   2824  1708 pts/0    S    09:28   0:00 gdbserver :62249 /home/pi/projects/Blink1/bin/ARM/Debug/Blink1.out
    pi       25714  0.0  0.0   4120   568 pts/2    S+   09:30   0:00 grep --color=auto gdb
    


    4.1 Visual Studio 기반의 GDB의 확장기능 


    Window10에서 Visual Studio

    • Download VisualGDB 
    Visual Studio기반으로 GDB확장으로 유료 Package (30일만 무료)
      https://visualgdb.com/
      https://visualgdb.com/tutorials/arm/openocd/build/
      https://visualgdb.com/tutorials/arm/stm32/
      https://visualgdb.com/tutorials/arm/openocd/



    • VisualKernel 사용
      https://sysprogs.com/VisualKernel/tutorials/raspberry/basicmodule/
      https://sysprogs.com/VisualKernel/download/


    5. VS Code 와 OpenOCD

    VS Code는 Visual Studio Code로 크로스 개발환경에서 많이 이용되어지며, 본인도 최근에서 사용하게된 Tool 이다.
    Visual Studio 와 마찬가지로 Microsoft사가 개발했으며, Window or Linux or MacOS 에서 다양 OS를  지원을 해주며, 다양한 확장프로그램을 지원을 해준다.
    미리 설치된 ToolChain 이 존재한다면, Run에 연결하여 하는 OpenOCD와 같이 사용을 하는 것으로 보인다.

    • Window의 VS Code 설치 진행전 해야할 것 
    1. STM의 ToolChain진행 
    2. STM의 LinkV2 Utiliyt 진행 
    3. Window OpenOCD 진행

    • VS Code의 Run의 launch.json 작성 

    launch.json // RUN 실행  아래의 workspaceRoot변경될 것이며, 아래의 Port 3333 OpenOCD연결 
    {
        "name": "GDB",
        "type": "gdb",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "target": "${workspaceRoot}/.pioenvs/nucleo_f303k8/firmware.elf",
        "gdbpath" : "C:/STM32Toolchain/gcc-arm/5.4 2016q3/bin/arm-none-eabi-gdb.exe",
        "autorun": [
            "target remote localhost:3333",
            "symbol-file ./.pioenvs/nucleo_f303k8/firmware.elf",
            "monitor reset"
            ]
    }





    • VS Code 와 OpenOCD+GDB
     https://www.justinmklam.com/posts/2017/10/vscode-debugger-setup/


    • VS launch.json example
      https://code.visualstudio.com/docs/cpp/launch-json-reference
      https://code.visualstudio.com/docs/editor/debugging