[[TableOfContents]] === 2009.6 Linux 시스템 모니터 === attachment:ps_p-1.PNG?width=600 {{{ ● 프로그램 요약 I. Myps System Manager 란? ▶ 리눅스 GUI(X-Window) 환경에서 프로세서 관리를 위한 모니터링 프로그램. 윈도우의 작업 관리자와 비슷한 기능을 한다. 메모리 사용량과 CPU 사용량, 모든 프로세스의 실시간 정보 등를 보여주며 GUI로 프로세스의 작업을 관리할 수 있다. II. 프로그램 개발 언어(SDK) 및 환경 ▶ 개발 언어(SDK) : C++(WxWidget) ▶ 개발 환경 : Code::Blocks, Fedora 9 III. 사용 환경 ▶ GNU/Linux (kernel 2.6.X) IV. 주요 기능 ① 현재 시스템의 모든 프로세스 출력 ▶ 포어그라운드, 백그라운드 프로세스 등 시스템의 모든 프로세스를 출력해 보여주는 기능. ② CPU/메모리 사용률 출력 ▶ 프로세스 종류별로 일정 시간 동안 사용된 CPU 사용률과 메모리와 사용량을 실시간으로 보여주는 기능. ③ 프로세스 작업 수행의 전환 ▶ GUI 조작을 통해 프로세스를 선택하고 명령을 내릴 수 있다. }}} {{{#!folding 코드 샘플 #1 메인 갱신 루프 {{{#!vim cpp void mypsFrame::OnTimer1Trigger1(wxTimerEvent& event) { cpus = cpus_read(cpus); wxString text = wxString::Format(_T("CPU Usage(Total) : %.2f%%\nCPU Usage(User) : %.2f%%\nCPU Usage(Kernel) : %.2f%%\n"), cpus->usage_tot, cpus->usage_usr, cpus->usage_krn); StaticText1->SetLabel(text); mems = mems_read(mems); text = wxString::Format(_T("MemTotal : %d KB\nMemUsed : %d KB\nMemFree : %d KB\n\nSwapTotal : %d KB\nSwapUsed : %d KB\nSwapFree : %d KB\n\nBuffers : %d KB\nCached : %dKB"), mems->memtotal, mems->memtotal - mems->memfree, mems->memfree, mems->swaptotal, mems->swaptotal - mems->swapfree, mems->swapfree, mems->buffers, mems->cached); StaticText2->SetLabel(text); int sinceboot = 0; int running = 0; int tickspersec = 0; int sec = 0; int diff[2]; float scale = 0.0; double itemIndex = 0.0; int numproc = 0; int idx = 0; procVectItor itor; PROC_t tempps; struct dirent *item; DIR *dp = NULL; if (dp = opendir("/proc/")) { while (1) { item = readdir(dp); if (item == NULL) break; if (atoi(item->d_name)) { // read on pid stat ++numproc; // PID COMMAND USER %CPU %MEM %TIME procs = procstat(item->d_name, procs); procs->flag = 1; if (ps.empty()) { ps.push_back(*procs); } else if ((itor = (find(ps.begin(), ps.end(), procs->pid))) != ps.end()) { procs->utime_sav = itor->utime_sav; procs->stimev_sav = itor->stimev_sav; ps.erase(itor); ps.insert(itor, *procs); } else { ps.push_back(*procs); } } } closedir(dp); sort(ps.begin(), ps.end()); } if (ListCtrl1->GetItemCount() == 0) { for (itor = ps.begin(); itor != ps.end(); ++itor) { sinceboot = gettimesinceboot(); running = sinceboot - itor->start_time; tickspersec = sysconf(_SC_CLK_TCK); sec = (int)running / tickspersec; diff[0] = itor->utime - itor->utime_sav; diff[1] = itor->stimev - itor->stimev_sav; scale = (diff[0] + diff[1]) * 100 / (float)cpus->total_sav; itor->utime_sav = itor->utime; itor->stimev_sav = itor->stimev; itor->cpu_usage = scale; itor->flag = 0; text = wxString::Format(_T("%d"), (int)itor->pid); itemIndex = ListCtrl1->InsertItem(idPID, text); text = wxString::FromAscii(itor->tcomm); ListCtrl1->SetItem(itemIndex, idCMD, text); text = wxString::FromAscii(itor->username); ListCtrl1->SetItem(itemIndex, idUSR, text); text = wxString::Format(_T("%.1f"), scale); ListCtrl1->SetItem(itemIndex, idCPU, text); text = wxString::Format(_T("%dKB"), (int)itor->rss); ListCtrl1->SetItem(itemIndex, idMEM, text); text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60); ListCtrl1->SetItem(itemIndex, idTME, text); } } else { for (itor = ps.begin(); itor != ps.end(); ++itor) { text = wxString::Format(_T("%d"), (int)itor->pid); itemIndex = ListCtrl1->FindItem(idPID, text); if(itor->flag == 0) { ListCtrl1->DeleteItem(itemIndex); continue; } sinceboot = gettimesinceboot(); running = sinceboot - itor->start_time; tickspersec = sysconf(_SC_CLK_TCK); sec = (int)running / tickspersec; diff[0] = itor->utime - itor->utime_sav; diff[1] = itor->stimev - itor->stimev_sav; scale = (diff[0] + diff[1]) * 100 / (float)cpus->total_sav; itor->utime_sav = itor->utime; itor->stimev_sav = itor->stimev; itor->cpu_usage = scale; itor->flag = 0; if(itemIndex < 0) { text = wxString::Format(_T("%d"), (int)itor->pid); itemIndex = ListCtrl1->InsertItem(idPID, text); text = wxString::FromAscii(itor->tcomm); ListCtrl1->SetItem(itemIndex, idCMD, text); text = wxString::FromAscii(itor->username); ListCtrl1->SetItem(itemIndex, idUSR, text); text = wxString::Format(_T("%.1f"), scale); ListCtrl1->SetItem(itemIndex, idCPU, text); text = wxString::Format(_T("%dKB"), (int)itor->rss); ListCtrl1->SetItem(itemIndex, idMEM, text); text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60); ListCtrl1->SetItem(itemIndex, idTME, text); continue; } text = wxString::Format(_T("%d"), (int)itor->pid); ListCtrl1->SetItem(itemIndex, idPID, text); text = wxString::FromAscii(itor->tcomm); ListCtrl1->SetItem(itemIndex, idCMD, text); text = wxString::FromAscii(itor->username); ListCtrl1->SetItem(itemIndex, idUSR, text); text = wxString::Format(_T("%.1f"), scale); ListCtrl1->SetItem(itemIndex, idCPU, text); text = wxString::Format(_T("%dKB"), (int)itor->rss); ListCtrl1->SetItem(itemIndex, idMEM, text); text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60); ListCtrl1->SetItem(itemIndex, idTME, text); } } //Note: 이 부분에 리스트 컨트롤 정렬을 넣고 싶으나 레퍼런스가 부족하다. // ::SetColumnsOrder() 함수를 제공하나 윈도우만 가능하다. text = wxString::Format(_T("프로세스: %d\t CPU 사용: %3d%%\t실제 메모리: %3d%%"), numproc, (int)cpus->usage_tot, ((mems->memtotal - mems->memfree) * 100)/mems->memtotal); StatusBar1->PushStatusText(text); } void mypsFrame::OnListCtrl1ItemRClick(wxListEvent& event) { wxMessageDialog *Dlg = new wxMessageDialog(NULL, _T("이 프로세스를 끝내시겠습니까?\n\n비정상적인 종료는 시스템이 불안정해질 수 있습니다. 계속하시겠습니까?"), _T("kill"), wxOK | wxCANCEL | wxICON_QUESTION); if(Dlg->ShowModal() == wxID_CANCEL) return; wxString text = event.GetText(); int pid = atoi((const char*)text.mb_str(wxConvUTF8)); kill(pid, SIGTERM); } }}} }}} === 2009.10 IIR 필터 구현 === {{{ 개발기간 7일 (2009년 9월 2 6일 ~ 2009년 10월 3일) Stable, Non-causal한 시스템 특성을 갖는 IIR 필터 설계 및 구현. 그리고 성능평가. 음향 원본에 필터를 적용하면 리버브 필터가 된다. }}} attachment:P3.jpg?width=400 attachment:P4.jpg?width=400 attachment:P5.jpg?width=400 === 2009.12 네트워크 MP3 플레이어 === attachment:mp_p-2.PNG {{{ 개발기간 50일 (2009년 11월 2일 ~ 2009년 12월 2 2일) ● 프로그램 요약 I. Network MP3 Player 란? ▶ ARM 계열 프로세서와 4 Line LCD, 키패드, 네트워크 접근이 가능한 장비에서 임베디드 리눅스 기반으로 MP3 플레이어를 구현한다. 기존의 MP3 플레이어의 기능에 무선랜카드를 연동하여 밖에 있을 때도 홈 PC에 있는 듣고 싶은 MP3 음악을 들을 수 있다는 것이 가장 큰 장점이다. II. 프로그램 개발 언어 및 환경 ▶ 개발 언어 : C ▶ 개발 환경 : vi editor III. 사용 환경 ▶ Embedded Linux IV. 주요 기능 ① 음악 목록 출력 & 디렉토리 탐색 ▶ 임베디드 장비의 로컬 영역에 있는 음악 파일 목록을 4 Line LCD에 출력한다. ② 볼륨 조절, 곡 재생 ▶ 임베디드 리눅스의 장치 레지스터에 의해 컨트롤 되는 키패드를 조작하여 MP3 플레이어 재생 조작을 한다. ③ 멀티태스킹 지원 ▶ 음악을 들으면서 음악 목록 검색과 환경 설정 등이 가능하다. ④ 윈도우 공유 폴더 네트워크 접속 ▶ 윈도우 공유 폴더를 CIFS (Common Internet File System;마이크로소프트에서 개발하고 사용중인 프로토콜) 형태로 마운트 한다. 리눅스 상에서 마운트 되었으므로 네트워크 디렉토리 역시 로컬 디렉토리와 같이 탐색과 실행이 가능하다. }}} attachment:mp_p-1.PNG 그림 1. 임베디드 장비 - 윈도우 공유폴더 접근 attachment:mp_p-3.PNG 그림 2. 음악 파일 리스트를 응용하여 옵션 메뉴 리스트를 파일(디렉토리) 형태로 관리한다. attachment:mp_p-4.PNG 그림 3. 초기 화면. 음악 재생(MUSIC), 네트워크 연결(NETWORK), 옵션(OPTION) 중 원하는 메뉴를 키패드를 이용하여 선택한다. attachment:mp_p-5.PNG 그림 4. 로컬 디렉토리 시스템 아키텍쳐는 크게 재생 모드와 탐색 모드로 나누어진다. 탐색 모드에서는 로컬 영역과 네트워크 영역의 음악 파일을 디렉토리 구조로 탐색할 수 있다. attachment:mp_p-6.PNG 그림 5. 음악 재생 모드 키패드 입력을 통해 볼륨 조절, 이전 곡, 다음 곡 선택이 가능하다. === 2009.12 4비트 unsigned multiplier 설계 및 구현 === {{{ 개발기간 9일 (2009년 12월 1 0일 ~ 2009년 12월 1 9일) 누산기 구현. -_- 사실 제대로 하려면 ALU를 만들었어야 했는데…. 처음에 플립 플랍들 조작하는 개념이 안 잡히면 삽질의 연속이 된다. 이거 한 번 구현해 보면 CPU 클럭 사이클과 명령어 관계가 바로 이해가 간다. }}} attachment:P11.jpg?width=400 attachment:P12.jpg?width=400 attachment:P13.jpg?width=400