서론 #
시스템 동작시 CPU와 메모리 자원을 얼마만큼 소모하고 있는 가를 파악하는 일은 소프트웨어를 개발하는 것 만큼 중요한 일이다. 만약 CPU가 항상 100%을 동작하고 있다면, 이는 고객들의 새로운 요구 조건을 처리할 여력이 CPU에는 없음을 의미한다. 이를 위해서 개발자들은 소프트웨어를 보다 최적화시키거나, 더 성능이 좋은 CPU를 사용해야 할 것이다. 메모리도 동일하게 적용된다. 메모리 사용량을 확인하여, 적정 수준의 메모리를 시스템에 적용시켜야 할 것이다. 제한된 자원 속에서 동작하는 임베디드 시스템 소프트웨어 개발 시에는 이러한 제약이 더욱 심하게 적용된다. 프로젝트에 고객의 요구사항들 중 CPU 및 메모리 사용율에 대한 제약조건을 제시한 것도 이와 같은 맥락이다. VxWorks 5.5 및 IDE 툴인 Tornado에서는 이를 위하여 CPU와 메모리 사용량을 모니터링하기 위한 다양한 방법을 개발자들에게 제공하며, 이미 그 방법들은 기존 기술 문서에서 언급(TM8-07-011)을 하였다.
본 문서에서는, Tornado에서 제공하는 Browser 윈도우에 CPU 및 메모리 최대 사용량을 임베딩시키는 방법을 다루는데 목적이 있다. 이 방법을 사용한다면, RTI 툴을 사용하기 위한 라이센스 문제가 없을 뿐만 아니라, 별도의 프로그램을 타켓에 업로드 시키지 않더라도, 원하는 정보를 확보할 수 있는데 그 장점이 있다.
본론 #
배경지식 #
Tornado의 Browser 윈도우를 수정하기 위해서 필요한 사항들을 알아본다.
Browser#
Tornado IDE에서 제공하고 있으며, 윈도우로 연결된 타켓의 상태를 확인할 수 있는 유용한 윈도우이다. 느낌표(!) 버튼을 누르면, 즉시 타켓의 현재상태를 갱신을 하며, 주기적으로 모니터링하고 싶다면, 시계 모양의 버튼을 누르면 된다. 환경 설정은 도구 모양의 버튼을 누르면된다. 본 문서에서는 이 Browser 윈도우를 수정하여, 메모리 최대 사용량과 CPU 최대 사용량 정보를 전시할 수 있도록 한다.
WTX Protocol #
VxWorks를 사용하면, VxWorks가 올라간 타켓 머신과 호스트 컴퓨터는 WTX 라는 프로토콜로 연결이 된다. WTX 프로토콜을 사용하여, 호스트 상에서 동작하는 여러 프로그램들이, 타켓에서 돌아가는 VxWorks와 통신을 할 수 있게된다. WTX 프로토콜 처리를 위해, Tornado는 WTX C API와 WTX TCL API를 제공하고 있으며, 본 문서에서는 WTX TCL API를 사용하여, Browser에 수정을 가할 것이다.
모든 TCL 기반의 Tornado 툴들은 다음과 같은 디렉토리에 위치하게 된다.
installDir/host/resource/tcl/app-config/toolName
그러므로, Browser과 관련된 TCL 툴들은 아래의 디렉토리에 위치한다.
installDir/host/resource/tcl/app-config/Browser
Tornado Tool 확장 하기 #
Browser에 새로운 페이지를 추가하는 절차는 다음과 같다.
- installDir/host/resource/tcl/app-config/Browser 에 추가를 원하는 페이지의 내용을 정의한 tcl 파일을 위치한다. 파일의 이름은 "filename.win32.tcl" 과 같이 작성한다.
-
Browser의 페이지 리스트를 추가하기 위해 다음의 명령을 수행한다.
- lappend pageList "Page Name"
-
Browser의 해당 페이지가 선택되어졌을때 실행이 될 Hook routine을 작성한다. invokeSpyPage 의 형식으로 작성한다.
- invokeDescriptionStringW/oSpaces 의 형식을 가지면 된다.
- 새로 추가된 페이지에서 수행할 초기화 과정을 갖는 함수를 만든다. 이 과정에서 Tree Control과 자료구조를 초기화하며, 필요한 정보를 획득하는 과정이 포함된다. setupSpyPage 의 형식으로 작성한다.
- 사용자의 조작으로 인해 윈도우 Controle들을 다시 그려줘야 할 때 호출되는 함수를 작성한다. adjustSpyChartPage 의 형식으로 작성한다.
하지만, 본 문서에서는 Browser에 새로운 화면을 추가하는 것이 아니라, 기존의 윈도우를 수정하는 것이기 때문에 그냥 참고로만 알아두면 된다.
Tornado Tcl API#
윈도우 객체를 컨트롤하기 위해서 다음의 함수들을 사용할 수 있다.
-
controlCreate
- 인자로 받은 형식의 윈도우 컨드롤을 생성하는 함수
-
사용법 : controlCreate windowName controlSpec itemType [options]
- windowName : 부모 윈도우
- controlSpec : 생성하기를 원하는 윈도우 컨트롤
-
itemType 종류는 상당히 많으며, 본 문서에서 쓰이는 것만 소개를 하겠다.
- label : 텍스트를 전시하는 윈도우 컨트롤
- progressmeter : 진행상태를 보여줄 수 있는 윈도우 컨트롤
- meter : progressmeter와 유사하며, min/max 현재값을 세팅하여 현재 상태를 보여줄 수 있는 윈도우 컨트롤
-
controlValuesSet
- 해당 컨트롤의 데이터 및 텍스트 정보를 설정하는 함수
- 사용법 : controlValuesSet windowName.controlName [options] data
-
controlPropertySet
- 해당 컨트롤의 설정을 바꿀수 있도록 하는 함수
- 사용법 : controlPropertySet windowName.controlName [options] data
-
controlDestroy
- 해당 컨트롤 또는 윈도우를 제거하는 함수
- 사용법 : controlDestroy.windowName.controlName
Memory Usage Browser 수정 #
최대 메모리 값을 Browser에 유지하기 위해선, 크게 수정되어야 하는 부분은 없다.
01MemoryUsage.win32.tcl를 수정 해야하며, 아래의 순서로 진행하였다.
- 메모리 최대값 유지를 위한 글로벌 변수 선언
- setupMemoryUsagePage 함수에서 Browser의 Memory Usage 윈도우에서 해당 윈도우 컨트롤의 Label 값을 변경
- memoryChartUpdate 함수에 메모리 최대값 유지를 위한 로직 추가
- memoryChartUpdate 함수에 meter 윈도우 컨트롤 Browser.vxWorksMem에 해당 자료 출력
아래는 원본 01MemoryUsage.win32.tcl화일과 수정된 tcl 파일과의 차이점을 나타낸 패치화일이므로, 직접 수정을 하거나 또는 주어진 패치를 적용시켜도 된다.
- --- Y:/XXX/01MemoryUsage.win32.tcl_원본 Wed Aug 18 12:57:21 1999
+++ Y:/XXX/01MemoryUsage.win32.tcl_수정본 Mon Dec 22 14:09:13 2008
@@ -52,7 +52,7 @@
-name userMem -xpos [expr 7 + $brwsGlobal(labelWidth)] -ypos 7 \
-width [expr $maxXExtent - $brwsGlobal(labelWidth)] -height 24]
- controlCreate Browser [list label -title "Application:" -name vxWorksMemLbl \
+ controlCreate Browser [list label -title "System(MAX):" -name vxWorksMemLbl \
-xpos 7 -ypos 38 -width $brwsGlobal(labelWidth) -height 9]
controlCreate Browser [list meter -initial [list 0 1000000 0] \
@@ -124,10 +124,12 @@
set maxPoolMem 0
set maxVxMem 0
+set maxVxTotalMem 0
proc memoryChartUpdate {} {
global maxPoolMem
global maxVxMem
+ global maxVxTotalMem
global autoResize
set agentMem [wtxMemInfoGet]
@@ -147,6 +149,8 @@
if {$aCurAlloc >= $maxPoolMem} {set maxPoolMem $aCurAlloc}
if {$tCurAlloc >= $maxVxMem} {set maxVxMem $tCurAlloc}
+ if {$maxVxTotalMem <= $tCurAlloc} {set maxVxTotalMem $tCurAlloc}
+
set clientSz [windowClientSizeGet Browser]
set vUserMemList {}
@@ -155,7 +159,8 @@
# set vUserMemList [list $aCurAlloc 0 [expr $aCurAlloc+$aCurFree] $maxPoolMem]
# set vVxMemList [list $tCurAlloc 0 $tMem $maxVxMem]
set vUserMemList [list 0 [expr $aCurAlloc+$aCurFree] $aCurAlloc $maxPoolMem]
- set vVxMemList [list 0 $tMem $tCurAlloc $maxVxMem]
+# set vVxMemList [list 0 $tMem $tCurAlloc $maxVxMem]
+ set vVxMemList [list 0 $tMem $maxVxTotalMem $maxVxMem]
controlValuesSet Browser.userMem $vUserMemList
controlValuesSet Browser.vxWorksMem $vVxMemList
실행화면은 다음과 같다. Tools에 명시된 메모리는 호스트쪽에 할당된 cache 메모리를 의미한다. 새로운 라벨 System(MAX)가 보이며, meter 윈도우 컨트롤에 표현되는 메모리량은 현재 사용중인 메모리량이 아니라, Browser가 실행된 이후의 최대 메모리 사용량을 표현한다. 오른쪽 하단의 숫자는 해당 타켓 시스템의 메모리 최대량을 의미한다.
Spy Browser 수정 #
CPU 사용량 추적은 vxworks의 spyLib를 사용한다. 커널 설정에 반드시 아래의 커널 세팅 처럼 spyLib를 포함하여 컴파일하도록 한다.
Browser 윈도우에서 해당 항목을 활성화할 때만 spyLib가 동작하므로, 측정하지 않을때의 장비에 미치는 로드는 없다고 봐도 무방하다.(하지만, 커널 크기가 커진다.)
01Spy.win32.tcl 파일을 수정해야하며, 아래의 순서로 진행하였다.
- CPU 최대 사용량을 위한 글로벌 변수(minIdle)와 처음 로드된것을 알리는 글로벌 변수(isFirst)를 생성한다.
- spyTaskReport() 함수를 수정하여, idle(MAX)가 출력되도록 로직을 수정한다.
- spyStart() 함수를 수정하여, Browser 윈도우가 뜰때마다 내부 변수 초기화를 한다.
아래는 원본 01MemoryUsage.win32.tcl화일과 수정된 tcl 파일과의 차이점을 나타낸 패치화일이므로, 직접 수정을 하거나 또는 주어진 패치를 적용시켜도 된다.
- --- Y:/XXX/01Spy.win32.tcl_원본 Fri Dec 07 08:04:08 2001
+++ Y:/XXX/01Spy.win32.tcl_수정본 Mon Dec 22 17:17:53 2008
@@ -41,6 +41,8 @@
set spyCtrlSize 0
set spyCtrlVerticalSpacing 0
set spyCtrlNo 0
+set isFirst 1
+set minIdle 100
#|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#
@@ -201,6 +203,8 @@
global spyRunning
global spyOnScreen
global brwsGlobal
+ global minIdle
+ global isFirst
if {! $spyRunning} return
@@ -377,6 +381,8 @@
for {set i $spyCtrlNo} {$i < $nElems} {incr i} {
set lblName ""
append lblName item$i Label
+
+ # if a task is IDLE
controlCreate Browser [list label \
-title [lindex [lindex $taskNameList2 $i] 0] \
-name $lblName \
@@ -398,18 +404,35 @@
}
set spyCtrlNo $nElems
-
set clientSz [windowClientSizeGet Browser]
for {set i 0} {$i < $nElems} {incr i} {
if {[lindex $vList $i] != ""} {
set lblName ""
append lblName item$i Label
- controlValuesSet Browser.$lblName [lindex [lindex $taskNameList2 $i] 0]
- controlValuesSet Browser.item$i [lindex $vList $i]
+
+ if { $i == [expr $nElems - 2] } {
+ controlValuesSet Browser.$lblName "IDLE(Current)"
+ set tmpValue [lindex [lindex $vList $i] 0]
+ if { $isFirst == 1 && $tmpValue == 0 } {
+ set tmpValue 100
+ }
+
+ if { $tmpValue <= $minIdle } {
+ set minIdle $tmpValue
+ }
+ controlValuesSet Browser.item$i [lindex $vList $i]
+ } elseif { $i == [expr $nElems -1] } {
+ controlValuesSet Browser.$lblName "IDLE(Min)"
+ controlValuesSet Browser.item$i [list $minIdle]
+ } else {
+ controlValuesSet Browser.$lblName [lindex [lindex $taskNameList2 $i] 0]
+ controlValuesSet Browser.item$i [lindex $vList $i]
+ }
}
}
adjustSpyChartPage
+ set isFirst 0
# post the spy window
if {! $spyOnScreen} {
@@ -499,6 +522,7 @@
global spyFrequency
global browserUpdate
global autoRefresh
+ global isFirst
# load spyLib.o if necessary
if {[spyTaskSetup] == -1} {
@@ -525,6 +549,7 @@
# Turn on the update mechanism. Note that we don't want to interfere with
# the browser's auto update which already turned on the update mechanism.
set spyRunning 1
+ set isFirst 1
spyTaskReport
}
실행화면은 다음과 같다. Spy Chart는 현재 타켓에서 동작중인 모든 태스크들의 CPU 사용량을 전시한다. 위에서 수정한 IDLE(Min) 라벨이 보일 것이다. 이 부분의 값이 IDLE 태스크의 최소값이며, 이는 CPU 최대 사용량을 의미한다. IDLE(Current)는 현재 CPU 사용량을 의미한다.
결론 #
본 문서에서는, Tornado에서 제공하는 Browser 툴을 수정하여 개발자가 원하는 정보를 출력할 수 있는 기본적인 지식을 다루었으며, 타켓의 메모리 최대 사용량과 CPU 최대 사용량을 추적할 수 있는 기능 구현을 목표로 하였다. 서론에서 언급했듯이 해당 정보들을 얻기위한 다양한 방법이 존재하며, 또한 구현 방법도 다양하다. 하지만, Tornado에서 제공하는 Browser 윈도우를 수정하는 방법이 현재로써는 고객에게 이해시키기가 가장 빠르며, 라이센스 문제로부터 자유롭다는 점에서 큰 의미가 있다. 본 문서에서 언급한 기술을 습득한다면, 추후 비슷한 종류의 요구사항이 존재할 경우 Tornado IDE 툴 자체를 하나의 표현 도구로써 활용가능할 것이다.
참고문헌 #
- Tornado User Guide 9.7 장
- Tornado API Programmer's Guide 5장
- TCL 메뉴얼
파일#
이 글은 스프링노트에서 작성되었습니다.