/* * TOPPERS Software * Toyohashi Open Platform for Embedded Real-Time Systems * * Copyright (C) 2012 by Embedded and Real-Time Systems Laboratory * Graduate School of Information Science, Nagoya Univ., JAPAN * * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * * @(#) $Id: sample1.h 1716 2010-01-31 11:39:18Z ertl-hiro $ */ #include #include #include #include "syssvc/serial.h" #include "syssvc/syslog.h" #include "kernel_cfg.h" #include "perf.h" #include "histogram.h" #include "target_timer.h" #include "test_lib.h" /* * サービスコールのエラーのログ出力 */ Inline void svc_perror(const char *file, int_t line, const char *expr, ER ercd) { if (ercd < 0) { t_perror(LOG_ERROR, file, line, expr, ercd); } } #define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr)) /* * 起動時間測定用変数 */ PERFCNT perf_boot_time[4]; /* * 起動時間計測用初期化ルーチン */ void perf_boot_time_inithdr(intptr_t exinf) { x_get_pcc(&perf_boot_time[2]); x_rst_pcc(); } /* * 起動時間計測用タスク */ void perf_boot_time_task(intptr_t exinf) { x_get_pcc(&perf_boot_time[3]); x_rst_pcc(); } /* * 計測回数と実行時間分布を記録する最大時間 */ #define NO_MEASURE 10000U /* 計測回数 */ #define MAX_TIME 10000U /* 実行時間分布を記録する最大時間 */ /* * 実行時間分布を記録するメモリ領域 */ static uint_t histarea1[MAX_TIME + 1]; static uint_t histarea2[MAX_TIME + 1]; /* * act_tsk ディスパッチなし測定用関数 */ void task_act_tsk_nodsp_low(intptr_t exinf) { } void task_act_tsk_nodsp_high(intptr_t exinf) { uint_t i; for (i = 0; i < NO_MEASURE; i++) { begin_measure(1); act_tsk(TASK_ACT_TSK_NODSP_LOW); end_measure(1); ter_tsk(TASK_ACT_TSK_NODSP_LOW); } wup_tsk(MAIN_TASK); } /* * act_tsk ディスパッチあり測定用関数 */ void task_act_tsk_dsp_low(intptr_t exinf) { uint_t i; for (i = 0; i < NO_MEASURE; i++) { begin_measure(2); act_tsk(TASK_ACT_TSK_DSP_HIGH); end_measure(2); } wup_tsk(MAIN_TASK); } void task_act_tsk_dsp_high(intptr_t exinf) { } bool_t start_eval_int; bool_t end_eval_int; uint_t eval_int_hist[MAX_TIME + 1]; int perf_int_latency_count; /* * 割込み応答時間計測 */ void perf_int_latency(void) { uint_t timer_count; if (start_eval_int == true) { timer_count = target_timer_get_current(); if (TO_USEC(timer_count) < MAX_TIME){ eval_int_hist[TO_USEC(timer_count)]++; } else { eval_int_hist[MAX_TIME]++; } perf_int_latency_count++; if( perf_int_latency_count == NO_MEASURE) { perf_int_latency_count = 0; start_eval_int = false; end_eval_int = true; iwup_tsk(MAIN_TASK); } } } void print_perf_int_latency(void) { uint32_t i; int out_count = 0; for(i = 0; i < (MAX_TIME + 1); i++) { if (eval_int_hist[i] != 0) { syslog_2(LOG_NOTICE, "%d us, %d", i, eval_int_hist[i]); out_count++; } } } /* * メインタスク */ void main_task(intptr_t exinf) { ulong_t t0,t1,t2,t3; uint32_t i; /* * BSSの初期化を使用しない場合があるため,ここで初期化. */ for (i = 0; i <= MAX_TIME; i++) { histarea1[i] = 0; histarea2[i] = 0; eval_int_hist[i] =0; } syslog_1(LOG_NOTICE, "Performance evaluation program start. Please wait about %d sec.", NO_MEASURE/1000); syslog_flush(); /* * act_tsk ディスパッチなしの測定 */ init_hist(1, MAX_TIME, histarea1); act_tsk(TASK_ACT_TSK_NODSP_HIGH); slp_tsk(); ter_tsk(TASK_ACT_TSK_NODSP_HIGH); /* * act_tsk ディスパッチありの測定 */ init_hist(2, MAX_TIME, histarea2); act_tsk(TASK_ACT_TSK_DSP_LOW); slp_tsk(); ter_tsk(TASK_ACT_TSK_DSP_LOW); /* * 割込み応答時間の測定 */ perf_int_latency_count = 0; start_eval_int = true; slp_tsk(); /* * 計測結果の出力 */ t0 = x_cnv_nsec(perf_boot_time[0]); t1 = x_cnv_nsec(perf_boot_time[1]); t2 = x_cnv_nsec(perf_boot_time[2]); t3 = x_cnv_nsec(perf_boot_time[3]); syslog_0(LOG_NOTICE, "Boot time."); syslog_1(LOG_NOTICE, "Total time %ld ns", t0+t1+t2+t3); syslog_1(LOG_NOTICE, "Boot to sta_ker %ld ns", t0); syslog_1(LOG_NOTICE, "target init %ld ns", t1); syslog_1(LOG_NOTICE, "OS Obj init to inithdr %ld ns", t2); syslog_1(LOG_NOTICE, "inithdr to inittask %ld ns", t3); syslog_flush(); syslog_0(LOG_NOTICE, "act_tsk without dispatch[ns]."); print_hist(1); syslog_0(LOG_NOTICE, "act_tsk with dispatch[ns]."); print_hist(2); syslog_0(LOG_NOTICE, "Interrupt Latency."); print_perf_int_latency(); syslog_0(LOG_NOTICE, "Performance measurement end."); syslog_flush(); ext_ker(); assert(0); }