필자가 관리하는 장치중에 특정장치의 부품이 변경되면서 문제를 일으키기 시작했다.
우선 하드웨어팀에서 대응을 해주지 않으니 테스트를 다방면으로 진행했는데, 평가보드를 이용한 테스트 진행결과 확실히 필자의 회사 보드에서 더 많은 오류가 발생된다.
원인을 여기에 이야기 하는건 좀 그렇고 어쨋든 결론적으로 전원 초기화 또는 전원 노이즈 관련 문제라고 생각해서 이런저런 테스트를 진행하였다.
필자의 이전 포스팅에 보면 테라텀 매크로를 이용하여 테스트 자동화 하는 방법을 언급한 적이 있는데, 이는 디버깅을 하는 경우에만 해당되고 실제 구동되는 도중 테스트 결과를 수집하기 위해서는 결국 쉘프로그램을 이용하여 반복 테스트 할 수 있도록 해야된다.
https://makeutil.tistory.com/65 - 테라텀 스크립트를 이용한 테스트 자동화
예전에 종종 썼었는데, 자꾸 잊어버리게 되어 그냥 포스팅 해놓고 이후에라도 참조할 양으로 기록을 남겨둔다.
필자는 임베디드 보드에 우분투를 퓨징하여 사용하고 있어서, 대부분의 명령은 리눅스 또는 리눅스에서도 우분투를 이용한 설정등이 주로 이용된다.
1. 반복할 스크립트
반복할 스크립트는 아래와 같이 작성해서 root 사용자 폴더에 이뿌게 준비한다.
[ test.sh ]-------------------------------------------------------------------------------------
#!/bin/bash
TEST_CNT=5; # 반복회수
CNT_FILE="/root/count.txt" # 반복회수 저장용 파일
LOG_FILE="/root/log.txt" # 결과 저장파일
value=`fw_printenv uboot_flag` # 부트로더의 환경 변수에서 uboot_flag 변수를 읽어와 문자열로 저장
date=`date "+%Y%m%d-%H:%M:%S"` # 현재 시간을 문자열로 저장
state=0 # 테스트 결과 저장용 변수
if [ -z "$value" ]; then # 부트로더 변수 존재여부 확인 - value 값이 있는 경우 오류발생상태임.
echo "Normal - OK" # 없는경우
state=0; # 상태값을 0으로 설정, 상태값으로 조건 처리하려니 라인이길어져
state_string="OK"; # 저장용 문자열을 하나 더 선언
else
get_variable="${value%%=*}" # 오류가 잇는경우 변수명을 = 기준으로 따내고
get_value="${value#*=}" # 변수의 설정값을 = 기준으로 따냄.
if [[ $get_value == "1" ]]; then # 변수값이 1이면 오류발생 흔적이 있었던 것이므로
echo "Recovery - OK"
/usr/bin/fw_setenv uboot_flag ## 부트로더 환경값의 변수를 삭제
state=1; ## 상태를 1로 설정하면서, 귀찮으니 문자열하나 설정하고
state_string="Recovered!"; # 그이외의 숫자이면
else ## 다른오류 발생 을 표시
echo "Check - another state" ## 그리고 부트로더 환경값의 변수를 삭제
/usr/bin/fw_setenv uboot_flag
fi
fi
if [ ! -e $CNT_FILE ]; then # 몇번 테스트를 했는지 저장해놓는 count.txt 파일이 없는경우
echo "Echo Create Counter.."
echo "0" > $CNT_FILE # 파일을 생성하면서 카운트를 0으로 설정
fi
get_cnt=`cat $CNT_FILE` # 카운트 파일을 읽어 결과를 저장
set_cnt=$(expr ${get_cnt} + 1); # 받아온 문자열 값을 숫자로 변환 후 1을 누적
echo "$set_cnt" > $CNT_FILE # 누적된 카운트를 count.txt 파일에 저장
echo "-------------"
echo "$date ($set_cnt) $state_string" >> $LOG_FILE # 로그파일에 누적(>>) 저장, 온도도 추가하면 굿!
if [ $set_cnt -ge $TEST_CNT ]; then # 지정된 테스트 카운트에 도달하면
echo "Finished! ($set_cnt/$TEST_CNT)" # 테스트 카운트를 출력하고 끝.
else
echo "Rebooting....($set_cnt/$TEST_CNT).. please wait 15 sec." # 지정카운트 미도달시 메시지표시후
sleep 15 # 15초 대기
systemctl start reboot.target # 시스템 리부팅.
fi
-----------------------------------------------------------------------------------------------------
다음은 로그인 되던 안되던 부팅시 자동으로 시작될 수 있도록 해야되므로, 서비스를 하나 설정한다.
2. 서비스 등록
서비스는 시스템 시작과 동시에 또는 사용자 호출에 의해서 시스템의 백그라운드에서 실행되는 프로그램을 의미하며, 데몬이라 부르기도 한다.
2.1. 서비스 스크립트 수정
# vim /etc/rc.local 파일을 열어서 다음과 같이 수정한다.
------------------------------------------------------------------------------------------------------
#!/bin/bash
sh /root/test.sh & # 추가된 문자열 쉘을 이용하여 부팅시 test.sh를 백그라운드로 동작시킴
exit 0
-------------------------------------------------------------------------------------------------------
2.2. 데몬 다시 읽기
현재 실행되는 데몬을 다시 읽어서 갱신한다.
# sudo systemctl daemon-reload
2.3. rc-local 서비스 활성화
# sudo systemctl enable rc-local
2.4. rc-local 서비스를 시작
$ sudo systemctl start rc-local
2.4. rc-local 서비스 상태를 표시
user$ sudo systemctl status rc-local
만약 표시 했는데 Active로 표시되지 않고 아래와 같이 inactive(dead)로 표시되면, /etc/rc.local의 소유권등의문제일 수 있다.
"/etc/rc.local" 3L, 37C written
[root@imx ~]$ sudo systemctl daemon-reload
[root@imx ~]$ sudo systemctl enable rc-local
Removed /etc/systemd/system/multi-user.target.wants/rc-local.service.
Created symlink /etc/systemd/system/multi-user.target.wants/rc-local.service → /lib/systemd/system/rc-local.service.
[root@imx ~]$ systemctl start rc-local
[root@imx ~]$ sudo systemctl status rc-local
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; enabled; vendor pres>
Drop-In: /usr/lib/systemd/system/rc-local.service.d
mqdebian.conf
Active: inactive (dead)
Condition: start condition failed at Thu 2022-02-10 14:13:25 KST; 6s ago
mq ConditionFileIsExecutable=/etc/rc.local was not met
Docs: man:systemd-rc-local-generator(8)
그런경우 아래와 같이 rc.local의 소유권을 755나 777정도로 본인의 상황에 맞게 설정을 해주도록 하자.
# chmod 777 /etc/rc.local
3. 실행 결과
정상적으로 설정되었다면...
1) 재부팅시마다 /etc/rc.local에 의해 /root/test.sh가 실행
터미널을 안쓰고 테스트 하기 위해 만들었지만, 잘돌아가는지는 터미널을 통해 확인해야 됨.
---------------------------------------------------------------------------------
rc.local[420]: ## Error: "uboot_flag" not defined <= 정상적인경우 부트로더의 환경값이 없으므로, state=0
Starting Permit User Sessions...
rc.local[420]: Normal - OK <= 정상부팅임을 표시
Starting OpenBSD Secure Shell server...
rc.local[420]: -------------
[ OK ] Started /etc/rc.local Compatibility.
rc.local[420]: Finished! (1000/1000) <= 테스트 1000회 종료 확인
---------------------------------------------------------------------------------
2) test.sh는 count.txt의 테스트 회수를 읽어 증가시킨후 count.txt파일을 갱신.
3) 테스트 회수와 테스트과등 설정한 데이터를 log.txt를 누적하며 저장
4) log.txt에는 테스트 회수만큼의 데이터가 저장되었으므로 그걸보고 판단.
5) 재 테스트를 하려면 터미널, ssh, ftp등으로 연결후 count.txt 삭제, log파일 백업후 삭제
그리고 다시 끄면 다시 테스트 시작됨.
온도값을 포함시키면 좀더 있어보인다. 아래는 온도를 넣으려고 count.txt를 수정해서 두번씩 테스트한 결과 파일 내용이다. 온도도 표시되고 Result의 상수값도 괄호에 포함시켜 출력하였다.
4. 테스트 중 정지를 하려면...
u-boot 환경변수를 하나 더 추가해서 스크립트에서 if문을 걸던지 아니면 리부팅 이전 대기시간 15초내에 로그인하여 다음과 같이 count.txt 값을 증가시키면 된다.
만약, 스크립트의 TEST_CNT가 1000으로 설정된 경우라면, 터미널에서 ehco "1000" > /root/count.txt 를 입력하면, count.txt 파일이 1000이 되므로 재부팅 한번 뒤에 멈추게 된다.
필요한 분이 요긴하게 사용했으면 한다.
5. 만약 EMMC에 uboot 환경값을 기록할 수 없는 경우...
이전 필자의 블로그에 부트로더의 환경변수를 커널로 bootargs를 통해 넘길 수 있다고 했다. 그러면 그에 맞추어서 반복 스크립트를 수정하면 해결될 거라 생각한다.
https://makeutil.tistory.com/131 - 커널에서 부트로더 환경값 읽어오기.
최근댓글