RT_Thread 의 테스트 프레임 워 크 사용 및 분석

RT_Thread 의 테스트 프레임 워 크 사용 및 분석
행 문의 간단 함 을 위해 RTThread 는 RTT 라 고 약칭 합 니 다.
가장 간단 한 테스트 용례 (TestCase 프레임 워 크 사용 하지 않 음)
RTT 의 finsh 구성 요 소 는 매우 강력 한 디 버 깅 기능 을 제공 합 니 다. 우 리 는 함 수 를 finsh 에 출력 한 다음 에 finsh 에서 수 동 으로 이 함 수 를 호출 할 수 있다 는 점 이 매우 강력 합 니 다.finsh 는 RTT 의 디 버 깅 이기 로 finsh 를 잘 사용 하면 개발 의 효율 을 크게 향상 시 킬 수 있다 고 할 수 있다.
finsh 에 대한 상세 한 소 개 는 'RT Thread 실시 간 운영 체제 프로 그래 밍 가이드' 의 Finsh Shell 시스템 1 장 을 참고 할 수 있 습 니 다. 여 기 는 간단 한 예 일 뿐 입 니 다.
application. c 의 마지막 에 다음 코드 를 추가 합 니 다.

int testfunc(void)
{
	rt_kprintf("hello, rt-thread!
"); } #include <finsh.h> FINSH_FUNCTION_EXPORT(testfunc, just a test function);

rtconfig. h 에서 RT 를 사용 하 는 것 을 잊 지 마 세 요.USING_FINSH 매크로. testfunc 라 는 함 수 를 만 들 었 습 니 다. 그리고 finsh 에서 고 르 기 를 원 합 니 다. 그러면 FINSH 를 사용 해 야 합 니 다.FUNCTION_EXPORT 매크로 는 두 개의 인 자 를 가지 고 있 습 니 다. 첫 번 째 인 자 는 함수 이름 입 니 다. 두 번 째 인 자 는 함수 에 대한 설명 입 니 다. 임의의 문자열 일 수 있 습 니 다. 사용 자 는 자신의 취향 에 따라 작성 할 수 있 지만 함수 에 대해 객관 적 인 설명 이나 소 개 를 하 는 것 을 권장 합 니 다.FINSH_FUNCTION_EXPORT 는 함수 testfuc 를 finsh 에 출력 합 니 다. 그러면 finsh 는 testfuc 라 는 함수 가 있 습 니 다.
그 다음 에 프로젝트 를 재 컴 파일 하고 직렬 도 구 를 시작 합 니 다. 예 를 들 어 putty, windows 시스템 이 자체 적 으로 가지 고 있 는 슈퍼 터미널 이나 SecureCRT 등 입 니 다.리 셋 개발 판 에서 다음 과 같은 정 보 를 볼 수 있 습 니 다.
 \ | /
- RT -     Thread Operating System
 / | \     1.1.0 build Apr 15 2012
 2006 - 2012 Copyright by rt-thread team

finsh />

이때 Tab 키 를 누 르 면 다음 문장 을 볼 수 있 습 니 다.
--function:
testfunc         -- just a test function
list_mem         -- list memory usage information
list_date        -- list date
hello            -- say hello world
version          -- show RT-Thread version information
list_thread      -- list thread
list_sem         -- list semaphone in system
list_event       -- list event in system
list_mutex       -- list mutex in system
list_mailbox     -- list mail box in system
list_msgqueue    -- list message queue in system
list_mempool     -- list memory pool in system
list_timer       -- list timer in system
list_device      -- list device in system
list             -- list all symbol in system
--variable:
dummy            -- dummy variable for finsh
finsh />

첫 번 째 문장 은 우리 가 방금 작성 한 함수 입 니 다. 왼쪽 은 함수 이름 이 고 오른쪽 은 함수 설명 입 니 다.
그 다음 에 finsh 에 t 를 입력 한 다음 에 Tab 키 를 누 르 면 finsh 는 자동 으로 testfunc 를 보완 해 줍 니 다. 그리고 우 리 는 수 동 으로 입력 () 한 후에 차 로 돌아 가면 다음 과 같은 운행 효 과 를 볼 수 있 습 니 다.
finsh />testfunc()
hello, rt-thread!
        0, 0x00000000
finsh />

주: finsh 는 Liux 의 셸 과 비슷 합 니 다. 모두 tab 키 가 자동 으로 완성 되 는 기능 을 가지 고 있 지만 약간 다 릅 니 다. finsh 의 명령 은 C 언어 스타일 이 고 명령 은 함수 호출 문 입 니 다.
finsh 에서 방금 작 성 된 testfuc 함 수 를 수 동 으로 호출 하 는 데 성공 한 것 을 볼 수 있 습 니 다.이 기능 은 디 버 깅 프로그램 에서 매우 유용 하 다.이 를 통 해 테스트 프로그램 을 만 들 고 finsh 를 통 해 수 동 으로 테스트 사례 를 호출 할 수 있 음 을 알 수 있 습 니 다.
실제로 정식 프로젝트 개발 에서 테스트 는 매우 중요 한 부분 이 고 절차 품질의 중요 한 보장 이다.우 리 는 이 를 위해 대량의 테스트 용례 를 작성 할 수 있 습 니 다. 이때 finsh 에서 수 동 으로 함수 이름 을 입력 하여 테스트 용례 를 실행 하 는 방식 은 분명히 원시 적 입 니 다. 이 작업 은 기술적 인 함량 이 없고 지루 하 며 화가 납 니 다. 그러면 이런 상황 에서 어떻게 해 야 합 니까?
걱정 하지 마 세 요. RTT 는 우리 에 게 이른바 테스트 용례 (TestCase, 약칭 TC) 프레임 워 크 를 제공 합 니 다.TC 프레임 워 크 는 여러 개의 테스트 용례 함 수 를 순서대로 자동 으로 호출 하 는 데 도움 을 줄 수 있 습 니 다.
다음 절 에 저 희 는 testfuc 2 함 수 를 추가 할 것 입 니 다. testfuc 함수 와 함께 TC 프레임 워 크 를 사용 할 것 입 니 다. 먼저 두 개의 테스트 사례 코드 를 준비 하 겠 습 니 다. (코드 의 선명 함 을 위해 저 희 는 테스트 사례 를 독립 된 c 파일 에 두 겠 습 니 다)
현재 BSP 홈 디 렉 터 리 에 testcase 라 는 폴 더 를 만 듭 니 다.아래 코드 를 testfunc1. c 로 저장 하여 testcase/아래 에 저장 합 니 다.
#include <rtthread.h>

int testfunc1(void)
{
	rt_kprintf("hello, rt-thread! this is testfunc1
"); } #include <finsh.h> FINSH_FUNCTION_EXPORT(testfunc1, just a test function);

아래 코드 를 testfunc 2. c 로 저장 하여 testcase/아래 에 저장 합 니 다.
#include <rtthread.h>

int testfunc2(void)
{
	rt_kprintf("hello, rt-thread! this is testfunc2
"); } #include <finsh.h> FINSH_FUNCTION_EXPORT(testfunc2, just a test function);

TC 프레임 워 크 기반 테스트 용례 작성
1. rtconfig. h 수정
다음 과 같이 두 개의 매크로 를 사용 할 수 있 도록 합 니 다.
#define RT_USING_TC
#define RT_USING_FINSH

2. TC 프레임 워 크 소스 코드 및 테스트 사례 소스 코드 추가
TC 테스트 프레임 워 크 는 다음 과 같은 두 파일 이 필요 하기 때 문 입 니 다. tccomm.c tc_comm. h 이 두 파일 은 RTT 소스 패키지 examples/kernel/디 렉 터 리 에 있 습 니 다. 이 디 렉 터 리 는 이 두 파일 을 제외 하고 다른 많은 파일 도 포함 되 어 있 습 니 다. 그 파일 들 은 RTT 공식 적 으로 TC 프레임 워 크 를 기반 으로 하 는 테스트 사례 를 제공 합 니 다. RTT 커 널 의 기본 기능 을 테스트 하 는 데 사 용 됩 니 다.
여기 서 필 자 는 몇 마디 토로 하 는 것 을 참 지 못 하고 현재 RTT 의 파일 배치 가 여전히 혼 란 스 럽 습 니 다. tccomm. c 와 tccomm. h 는 테스트 용례 와 함께 놓 아 서 는 안 된다.우 리 는 다른 구성 요 소 를 위 한 테스트 용례 를 어디 에 두 었 습 니까?
위의 두 파일 을 현재 BSP 디 렉 터 리 의 testcase 디 렉 터 리 에 복사 합 니 다.
다음 코드 testcase/SConscript 파일 을
from building import *

src = Glob("*.c")

group = DefineGroup('testcase', src, depend = ['RT_USING_TC'])

Return('group')

현재 BSP 디 렉 터 리 에 있 는 SConstuct 파일 을 수정 하고 다음 코드 를 추가 합 니 다.
if GetDepend('RT_USING_TC'):
	objs = objs + SConscript(GetCurrentDir() + '/testcase/SConscript', variant_dir='build/tc', duplicate=0)


3. testfunc 1. c 와 testfunc 2. c 를 수정 합 니 다.
testfunc 1. c 를 다음 으로 변경 합 니 다.
#include <rtthread.h>
#include "tc_comm.h"

int testfunc1(void)
{
	rt_kprintf("hello, rt-thread! this is testfunc1
"); } #include <finsh.h> FINSH_FUNCTION_EXPORT(testfunc1, just a test function); static void _tc_cleanup() { tc_done(TC_STAT_PASSED); } int _tc_testfunc1() { /* TestCase */ tc_cleanup(_tc_cleanup); testfunc1(); /* TestCase */ return 100; } /* finsh shell */ FINSH_FUNCTION_EXPORT(_tc_testfunc1, a dynamic thread example);

마찬가지 로 testfunc 2. c 를 다음 과 같이 수정 합 니 다.
#include <rtthread.h>
#include "tc_comm.h"

int testfunc2(void)
{
	rt_kprintf("hello, rt-thread! this is testfunc2
"); } #include <finsh.h> FINSH_FUNCTION_EXPORT(testfunc2, just a test function); static void _tc_cleanup() { tc_done(TC_STAT_PASSED); } int _tc_testfunc2() { /* TestCase */ tc_cleanup(_tc_cleanup); testfunc2(); /* TestCase */ return 100; } /* finsh shell */ FINSH_FUNCTION_EXPORT(_tc_testfunc2, a dynamic thread example);

4. 컴 파일 실행
명령 행 에서 scons 컴 파일 을 실행 한 다음 finsh 를 시작 하고 tab 키 를 누 르 면 testfunc 1 과 testfunc 2 를 볼 수 있 습 니 다. 그 밖 에 세 개의 함수 가 더 있 습 니 다. 각각
  • tc_start
  • tc_stop
  • list_tc

  • tccomm. h 에 이 세 함수 의 원형 이 있 습 니 다. 이 세 가지 함 수 는 바로 TC 프레임 워 크 가 우리 에 게 제공 하 는 함수 입 니 다. 우 리 는 tc 만 실행 해 야 합 니 다.start ("test"), TC 프레임 워 크 는 테스트 func 1 과 테스트 func 2 함 수 를 자동 으로 순서대로 호출 합 니 다.효 과 는 다음 과 같다.
    finsh />tc_start("test")
            805434376, 0x3001f408
    finsh />Run TestCase: testfunc1
    hello, rt-thread! this is testfunc1
    TestCase[testfunc1] passed
    Run TestCase: testfunc2
    hello, rt-thread! this is testfunc2
    TestCase[testfunc2] passed
    RT-Thread TestCase Running Done!
    
    finsh />
    

    tcstart ("test") 의 의 미 는 두 개의 테스트 함수 의 함수 이름 을 각각 작성 합 니 다.
  • testfunc1
  • testfunc2

  • 분명히 이 두 함 수 는 공 통 된 접두사 문자열 을 가지 고 있 습 니 다. 여기 서 제 가 입력 한 것 은 'test' 입 니 다. 물론 'testf', 'testfun' 등 도 입력 할 수 있 습 니 다.
    확장 읽 기
    Finsh Shell 에 대한 더 많은 소 개 는 'RT Thread 실시 간 운영 체제 프로 그래 밍 가이드' 의 'Finsh Shell 시스템' 장 을 참고 하 시기 바 랍 니 다.
    RTT 공식 테이프 의 TC 용례 를 실행 합 니 다.
    RTT 의 공식 소스 패키지 에는 example/디 렉 터 리 에 있 는 테스트 사례 가 포함 되 어 있 습 니 다.독자 들 은 example/kernel 디 렉 터 리 에 있 는 소스 파일 만 TC 기반 테스트 사례 이 고 다른 하위 디 렉 터 리 에 있 는 파일 은 TC 프레임 워 크 를 기반 으로 작 성 된 것 이 아 닙 니 다.
    현재 BSP 디 렉 터 리 에 있 는 SConstuct 파일 을 수정 하면 다음 코드 를 사용 합 니 다.
    if GetDepend('RT_USING_TC'):
    	objs = objs + SConscript(GetCurrentDir() + '/testcase/SConscript', variant_dir='build/tc', duplicate=0)
    
       
    
    
    if GetDepend('RT_USING_TC'):
    	objs = objs + SConscript((RTT_ROOT + '/example/kernel/SConscript', variant_dir='build/tc/kernel', duplicate=0)
    

    컴 파일 실행, finsh 를 시작 한 후 TAB 키 를 누 르 면 많은 함수 가 나타 날 수 있 습 니 다. 이 함수 들 은 Finsh 에 출력 되 는 테스트 사례 입 니 다.
    tc 실행 가능start ("thread") 커 널 스 레 드 관련 테스트 tcstart ("timer") 커 널 타이머 테스트 tcstart ("semahore") 커 널 신 호 량 관련 테스트... 등등
    다음 절 에 서 는 RTT 의 TestCase 프레임 소스 코드 를 분석 할 것 이다.
    TestCase 프레임 원리 분석
    example/kernel/아래 tc 를 제공 합 니 다.sample. c, 이것 은 RTT 가 공식 적 으로 제공 하 는 TC 테스트 용례 의 샘플 코드 입 니 다.우 리 는 이 파일 을 연구 하여 TestCase 프레임 워 크 를 분석 할 것 이다.
    TC 프레임 워 크 와 관련 된 파일 은 examples/kernel/tc 입 니 다.comm.c examples/kernel/tc_comm.h examples/kernel/tc_sample.c
    그 중 tcsample. c 원본 코드 는 다음 과 같 습 니 다.
    #include <rtthread.h>
    #include "tc_comm.h"
    
    static rt_thread_t tid = RT_NULL;
    static void sample_thread(void* parameter)
    {
    	rt_kprintf("I'm sample!
    "); } static void sample_thread_cleanup(struct rt_thread *p) { tid = RT_NULL; tc_done(TC_STAT_PASSED); } int sample_init() { tid = rt_thread_create("t", sample_thread, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid != RT_NULL) { rt_thread_startup(tid); tid->cleanup = sample_thread_cleanup; } else tc_stat(TC_STAT_END | TC_STAT_FAILED); return 0; } #ifdef RT_USING_TC static void _tc_cleanup() { /* lock scheduler */ rt_enter_critical(); /* delete thread */ if (tid != RT_NULL) { rt_kprintf("tid1 is bad
    "); tc_stat(TC_STAT_FAILED); } /* unlock scheduler */ rt_exit_critical(); } int _tc_sample() { /* set tc cleanup */ tc_cleanup(_tc_cleanup); sample_init(); return 25; } FINSH_FUNCTION_EXPORT(_tc_sample, a thread testcase example); #else int rt_application_init() { sample_init(); return 0; } #endif
    
    
        ....

    좋은 웹페이지 즐겨찾기