/* * シリアルポートからの1文字受信 */ static bool_t serialPort_readChar(CELLCB *p_cellcb, char *p_c) { bool_t buffer_empty; ER ercd; SVC(loc_cpu(), gen_ercd_sys(p_cellcb)); /* * 受信バッファから文字を取り出す. */ *p_c = VAR_receiveBuffer[VAR_receiveReadPointer]; INC_PTR(VAR_receiveReadPointer, ATTR_receiveBufferSize); VAR_receiveCount--; buffer_empty = (VAR_receiveCount == 0U); /* * STARTを送信する. */ if (VAR_receiveStopped && VAR_receiveCount <= BUFCNT_START(ATTR_receiveBufferSize)) { if (!serialPort_sendChar(p_cellcb, FC_START)) { VAR_receiveFlowControl = FC_START; } VAR_receiveStopped = false; } SVC(unl_cpu(), gen_ercd_sys(p_cellcb)); ercd = (ER_BOOL) buffer_empty; error_exit: return(ercd); }
static void ev3rt_console_set_visibility(bool_t visible) { #if 0 if (loc_mtx(EV3RT_CONSOLE_LOG_MTX) != E_OK) { assert(false); return; } #endif ER ercd; ercd = loc_cpu(); assert(ercd == E_OK); if (console_visible != visible) { // visibility changed console_visible = visible; if (console_visible) { current_button_flag = console_button_flag; log_view_refresh_ex(log_current_line); on_display_fb = ev3rt_console_fb; } else { current_button_flag = user_button_flag; on_display_fb = lcd_screen_fb; } log_view_scroll_mode = false; } ercd = unl_cpu(); assert(ercd == E_OK); #if 0 if (unl_mtx(EV3RT_CONSOLE_LOG_MTX) != E_OK) { assert(false); return; } #endif }
ER GPSRec_Close(void) { if (!bGPSRecOpened) return E_SYS; #if (RECEIVE_FROM_UART2) if (uart2_close() == E_OK) #else if (uart_close() == E_OK) #endif debug_msg(("UART2: close success\r\n")); else debug_err(("UART2: close fail!\r\n")); debug_msg("Terminate GPS receive task\r\n"); ter_tsk(GPSRECEIVE_ID); loc_cpu(); bGPSRecOpened = FALSE; unl_cpu(); return E_OK; }
static void log_view_scroll(bool_t up) { ER ercd; ercd = loc_cpu(); assert(ercd == E_OK); if (up) { if (!log_view_scroll_mode && log_current_line > 0) { log_view_scroll_mode = true; log_view_scroll_line = log_current_line - 1; } else if (log_view_scroll_mode && log_view_scroll_line > 0) { log_view_scroll_line--; } } else { if (log_view_scroll_mode) { log_view_scroll_line++; } } if (log_view_scroll_line >= log_current_line) { // Exit scroll mode log_view_scroll_mode = false; log_view_refresh_ex(log_current_line); } ercd = unl_cpu(); assert(ercd == E_OK); if (log_view_scroll_mode) log_view_refresh_ex(log_view_scroll_line); }
/* * シリアルポートへの送信 */ static BOOL serial_wri_chr(SPCB *spcb, char c) { BOOL buffer_full; /* * LF の前に CR を送信する. */ if (c == '\n' && (spcb->ioctl & IOCTL_CRLF) != 0) { if (serial_wri_chr(spcb, '\r')) { _syscall(wai_sem(spcb->spinib->snd_semid)); } } _syscall(loc_cpu()); if (spcb->snd_count == 0 && !(spcb->snd_stopped) && serial_snd_chr(spcb, c)) { /* * シリアルI/Oデバイスの送信レジスタに文字を入れるこ * とに成功した場合. */ buffer_full = FALSE; } else { /* * 送信バッファに文字を入れる. */ spcb->snd_buffer[spcb->snd_write_ptr] = c; INC_PTR(spcb->snd_write_ptr); spcb->snd_count++; buffer_full = (spcb->snd_count == SERIAL_BUFSZ); } _syscall(unl_cpu()); return(buffer_full); }
ER_UINT extsvc_routine(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid) { ER ercd; switch ((uint_t) par1) { case 1: ercd = loc_cpu(); break; case 2: ercd = unl_cpu(); break; case 3: ercd = dis_dsp(); break; case 4: ercd = ena_dsp(); break; case 5: ercd = chg_ipm((PRI) par2); break; case 6: ercd = rot_rdq((PRI) par2); break; default: ercd = E_NOSPT; break; } return(ercd); }
/* * シリアルポートからの1文字受信 */ static bool_t serial_rea_chr(SPCB *p_spcb, char *p_c) { bool_t buffer_empty; ER ercd; SVC(loc_cpu(), gen_ercd_sys(p_spcb)); /* * 受信バッファから文字を取り出す. */ *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr]; INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz); p_spcb->rcv_count--; buffer_empty = (p_spcb->rcv_count == 0U); /* * STARTを送信する. */ if (p_spcb->rcv_stopped && p_spcb->rcv_count <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) { if (!serial_snd_chr(p_spcb, FC_START)) { p_spcb->rcv_fc_chr = FC_START; } p_spcb->rcv_stopped = false; } SVC(unl_cpu(), gen_ercd_sys(p_spcb)); ercd = (ER_BOOL) buffer_empty; error_exit: return(ercd); }
/* * シリアルポートのクローズ */ ER serial_cls_por(ID portid) { SPCB *spcb; ER ercd; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); _syscall(loc_cpu()); if (!(spcb->openflag)) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * ハードウェア依存のクローズ処理 */ sio_cls_por(spcb->siopcb); spcb->openflag = FALSE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd); }
ER GPSRec_Open(UART_BAUDRATE BaudRate) { if (bGPSRecOpened) return E_SYS; #if (RECEIVE_FROM_UART2) if (uart2_open() == E_OK) #else if (uart_open() == E_OK) #endif { debug_msg("\r\nUART2: Open success\r\n"); #if (RECEIVE_FROM_UART2) uart2_init(BaudRate, UART_LEN_L8_S1, UART_PARITY_NONE); #else uart_init(BaudRate, UART_LEN_L8_S1, UART_PARITY_NONE); #endif } else { debug_err(("UART2: open fail!\r\n")); return E_SYS; } debug_msg("Start GPS receive task\r\n"); sta_tsk(GPSRECEIVE_ID,0); loc_cpu(); bGPSRecOpened = TRUE; unl_cpu(); return E_OK; }
void main_task(intptr_t exinf) { HRTCNT hrtcnt, prev_hrtcnt; char *prev_hrtcnt_pos; ulong_t i; cyclic_count = 0U; recent_hrtcnt = fch_hrt(); syslog(LOG_NOTICE, "system performance time test starts."); for (i = 0; i < NO_LOOP; i++) { (void) loc_cpu(); hrtcnt = fch_hrt(); prev_hrtcnt = recent_hrtcnt; prev_hrtcnt_pos = recent_hrtcnt_pos; recent_hrtcnt = hrtcnt; recent_hrtcnt_pos = "TSK"; (void) unl_cpu(); if (prev_hrtcnt > hrtcnt) { syslog(LOG_NOTICE, "system performance time goes back: %d(%s) %d(TSK)", prev_hrtcnt, prev_hrtcnt_pos, hrtcnt); } } syslog(LOG_NOTICE, "system performance time test finishes."); syslog(LOG_NOTICE, "number of cyclic handler execution: %d", cyclic_count); check_finish(0); }
void main_task(intptr_t exinf) { SYSUTM sysutm, prev_sysutm; char *prev_sysutm_pos; ulong_t i; cyclic_count = 0U; get_utm(&recent_sysutm); syslog(LOG_NOTICE, "system performance time test starts."); for (i = 0; i < NO_LOOP; i++) { loc_cpu(); get_utm(&sysutm); prev_sysutm = recent_sysutm; prev_sysutm_pos = recent_sysutm_pos; recent_sysutm = sysutm; recent_sysutm_pos = "TSK"; unl_cpu(); if (prev_sysutm > sysutm) { syslog(LOG_NOTICE, "system performance time goes back: %ld(%s) %ld(TSK)", ((long_t) prev_sysutm), prev_sysutm_pos, ((ulong_t) sysutm)); } } syslog(LOG_NOTICE, "system performance time test finishes."); syslog(LOG_NOTICE, "number of cyclic handler execution: %d", cyclic_count); test_finish(); }
void RTOS::unlockCpu(){ --lockcpu_count; if(lockcpu_count <= 0) { lockcpu_count = 0; unl_cpu(); } }
/* * シリアルI/Oポートからの非同期文字入力 */ INT sio_arcv_chr( void ) { SIOPCB* siopcb ; UH uhBase ; INT c = -1 ; /* * タスクコンテキストからのみ使用可 */ if ( sns_ctx() || sns_loc() || sns_dsp() ) return -1 ; /* * CPUロック状態にする */ loc_cpu() ; /* * 非同期用ポートを開く */ if ( ( siopcb = sio_opn_por( LOGTASK_PORTID, siopcb_table[LOGTASK_PORTID-1].vpiExinf ) ) != NULL ) { uhBase = siopcb->uhBase ; /* * 受信待ち */ while(1) { if ( __SFR(uhBase) & __UxCR_RXREADY ) { c = __SFRW(uhBase+2) & 0xff ; if ( c == '\r' ) { c = '\n' ; siopcb->bLastIsCr = TRUE ; } else { if ( c == '\n' && siopcb->bLastIsCr ) c = -1 ; siopcb->bLastIsCr = FALSE ; } } if ( c != -1 ) break ; unl_cpu() ; dly_tsk( 50 ) ; loc_cpu() ; } } /* * CPUロックを解除 */ unl_cpu() ; return c ; }
// 擬似乱数 int rnd() { static unsigned int seed = 1; loc_cpu(); seed = seed * 1566083941UL + 1; unl_cpu(); return (seed >> 16) % 0x7fff; }
/* * 並行実行されるタスク */ void task(VP_INT exinf) { _toppers_cxxrt_reset_specific(); volatile UW i; INT n = 0; INT tskno = (INT) exinf; char *graph[] = { "|", " +", " *" }; char c; ena_tex(); while (1) { syslog(LOG_NOTICE, "task%d is running (%03d). %s", tskno, ++n, graph[tskno-1]); for (i = 0; i < task_loop; i++); c = message[tskno-1]; message[tskno-1] = 0; switch (c) { case 'e': syslog(LOG_INFO, "#%d#ext_tsk()", tskno); ext_tsk(); case 's': syslog(LOG_INFO, "#%d#slp_tsk()", tskno); syscall(slp_tsk()); break; case 'S': syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno); syscall(tslp_tsk(10000)); break; case 'd': syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno); syscall(dly_tsk(10000)); break; case 'y': syslog(LOG_INFO, "#%d#dis_tex()", tskno); syscall(dis_tex()); break; case 'Y': syslog(LOG_INFO, "#%d#ena_tex()", tskno); syscall(ena_tex()); break; #ifdef CPUEXC1 case 'z': syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; break; case 'Z': loc_cpu(); syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; unl_cpu(); break; #endif /* CPUEXC1 */ default: break; } } }
/* * シリアルポートのクローズ(受け口関数) */ ER eSerialPort_close(CELLIDX idx) { CELLCB *p_cellcb; ER ercd; bool_t eflag = false; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!VALID_IDX(idx)) { return(E_ID); /* ポート番号のチェック */ } p_cellcb = GET_CELLCB(idx); SVC(dis_dsp(), gen_ercd_sys(p_cellcb)); if (!VAR_openFlag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * ハードウェア依存のクローズ処理 */ if (loc_cpu() < 0) { eflag = true; } cSIOPort_close(); VAR_openFlag = false; if (unl_cpu() < 0) { eflag = true; } /* * セマフォの初期化 */ if (cSendSemaphore_initialize() < 0) { eflag = true; } if (cReceiveSemaphore_initialize() < 0) { eflag = true; } /* * エラーコードの設定 */ if (eflag) { ercd = gen_ercd_sys(p_cellcb); } else { ercd = E_OK; } } SVC(ena_dsp(), gen_ercd_sys(p_cellcb)); error_exit: return(ercd); }
/* * 並行実行されるタスク */ void task(intptr_t exinf) { volatile ulong_t i; int_t n = 0; int_t tskno = (int_t) exinf; const char *graph[] = { "|", " +", " *" }; char c; SVC_PERROR(ena_tex()); while (true) { syslog(LOG_NOTICE, "task%d is running (%03d). %s", tskno, ++n, graph[tskno-1]); for (i = 0; i < task_loop; i++); c = message[tskno-1]; message[tskno-1] = 0; switch (c) { case 'e': syslog(LOG_INFO, "#%d#ext_tsk()", tskno); SVC_PERROR(ext_tsk()); assert(0); case 's': syslog(LOG_INFO, "#%d#slp_tsk()", tskno); SVC_PERROR(slp_tsk()); break; case 'S': syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno); SVC_PERROR(tslp_tsk(10000)); break; case 'd': syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno); SVC_PERROR(dly_tsk(10000)); break; case 'y': syslog(LOG_INFO, "#%d#dis_tex()", tskno); SVC_PERROR(dis_tex()); break; case 'Y': syslog(LOG_INFO, "#%d#ena_tex()", tskno); SVC_PERROR(ena_tex()); break; #ifdef CPUEXC1 case 'z': syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; break; case 'Z': SVC_PERROR(loc_cpu()); syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; SVC_PERROR(unl_cpu()); break; #endif /* CPUEXC1 */ default: break; } } }
/* * シリアルポートのクローズ(サービスコール) */ ER serial_cls_por(ID portid) { SPCB *p_spcb; ER ercd; bool_t eflag = false; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); SVC(dis_dsp(), gen_ercd_sys(p_spcb)); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * ハードウェア依存のクローズ処理 */ if (loc_cpu() < 0) { eflag = true; } sio_cls_por(p_spcb->p_siopcb); p_spcb->openflag = false; if (unl_cpu() < 0) { eflag = true; } /* * セマフォの初期化 */ if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) { eflag = true; } if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) { eflag = true; } /* * エラーコードの設定 */ if (eflag) { ercd = gen_ercd_sys(p_spcb); } else { ercd = E_OK; } } SVC(ena_dsp(), gen_ercd_sys(p_spcb)); error_exit: return(ercd); }
/* * シミュレーション時刻を進める(テストプログラム用) */ void simtim_advance(uint_t time) { bool_t locked; locked = sns_loc(); if (!locked) { loc_cpu(); } while (*p_event_flag && *p_event_simtim <= current_simtim + time) { /* * 時刻をtime進めると,高分解能タイマ割込みの発生時刻を過ぎ * る場合 */ if (current_simtim < *p_event_simtim) { time -= (*p_event_simtim - current_simtim); current_simtim = *p_event_simtim; } *p_event_flag = false; (*p_raise_event)(); select_event(); /* * ここで割込みを受け付ける. */ if (!locked) { unl_cpu(); delay_for_interrupt(); loc_cpu(); } } current_simtim += time; if (!locked) { unl_cpu(); } }
/* * シリアルI/Oポートへの非同期文字出力 */ void sio_asnd_chr( INT c ) { SIOPCB* siopcb ; UH uhBase ; int i ; /* * CPUロック状態にする */ BOOL bLocked ; if ( sns_loc() ) bLocked = TRUE ; else { bLocked = FALSE ; if ( sns_ctx() ) iloc_cpu() ; else loc_cpu() ; } /* * 非同期用ポートを開く */ if ( ( siopcb = sio_opn_por( LOGTASK_PORTID, siopcb_table[LOGTASK_PORTID-1].vpiExinf ) ) != NULL ) { uhBase = siopcb->uhBase ; /* * LFならまずCRを送出 */ if ( c == '\n' ) { for ( i = 0 ; i < TXREADY_TIMEOUT ; i++ ) { if ( __SFR(uhBase) & __UxCR_TXEMPTY ) break ; } if ( i < TXREADY_TIMEOUT ) { __SFRW(uhBase+4) = __UxTX_STOPBIT | '\r' ; } } /* * データ送出 */ for ( i = 0 ; i < TXREADY_TIMEOUT ; i++ ) { if ( __SFR(uhBase) & __UxCR_TXEMPTY ) break ; } if ( i < TXREADY_TIMEOUT ) { __SFRW(uhBase+4) = __UxTX_STOPBIT | c ; } } /* * CPUロックを元に戻す */ if ( !bLocked ) { if ( sns_ctx() ) iunl_cpu() ; else unl_cpu() ; } }
/* * シリアルポートのオープン */ ER serial_opn_por(ID portid) { SPCB *spcb; ER ercd; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); _syscall(loc_cpu()); if (spcb->openflag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * 変数の初期化 */ spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV); spcb->rcv_read_ptr = spcb->rcv_write_ptr = 0; spcb->rcv_count = 0; spcb->rcv_fc_chr = '\0'; spcb->rcv_stopped = FALSE; spcb->snd_read_ptr = spcb->snd_write_ptr = 0; spcb->snd_count = 0; spcb->snd_stopped = FALSE; /* * ハードウェア依存のオープン処理 */ spcb->siopcb = sio_opn_por(portid, (VP_INT) spcb); /* * 受信通知コールバックを許可する. */ sio_ena_cbr(spcb->siopcb, SIO_ERDY_RCV); spcb->openflag = TRUE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd); }
/* * シミュレーション時刻を強制的に進める(テストプログラム用) */ void simtim_add(uint_t time) { bool_t locked; locked = sns_loc(); if (!locked) { loc_cpu(); } current_simtim += time; if (!locked) { unl_cpu(); } }
/* * シリアルポートへの1文字送信 */ static ER_BOOL serial_wri_chr(SPCB *p_spcb, char c) { bool_t buffer_full; ER ercd, rercd; /* * LFの前にCRを送信する. */ if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) { /* * 以下のコードは再帰呼出しになっているが,引数cが'\n'の場合に * 引数cを'\r'として呼び出すことから,この再帰呼出しは2回目の * 呼び出しで必ず止まる. */ SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd); if ((bool_t) rercd) { SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid), gen_ercd_wait(rercd, p_spcb)); } } SVC(loc_cpu(), gen_ercd_sys(p_spcb)); if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped) && serial_snd_chr(p_spcb, c)) { /* * シリアルI/Oデバイスの送信レジスタに文字を入れることに成功し * た場合. */ buffer_full = false; } else { /* * 送信バッファに文字を入れる. */ p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c; INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz); p_spcb->snd_count++; buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz); } SVC(unl_cpu(), gen_ercd_sys(p_spcb)); ercd = (ER_BOOL) buffer_full; error_exit: return(ercd); }
void bt_fetch_snd_buf(uint8_t **buf, uint32_t *bytes) { ER ercd; ercd = loc_cpu(); assert(ercd == E_OK); // Switch send buffer uint8_t old_snd_buf_idx = bt_send_buffer_idx; bt_send_buffer_idx = 1 - bt_send_buffer_idx; bt_send_buffer_bytes[bt_send_buffer_idx] = 0; ercd = unl_cpu(); assert(ercd == E_OK); *buf = bt_send_buffer[old_snd_buf_idx]; *bytes = bt_send_buffer_bytes[old_snd_buf_idx]; }
/* * シリアルポートへの1文字送信 */ static ER_BOOL serialPort_writeChar(CELLCB *p_cellcb, char c) { bool_t buffer_full; ER ercd, rercd; /* * LFの前にCRを送信する. */ if (c == '\n' && (VAR_ioControl & IOCTL_CRLF) != 0U) { /* * 以下のコードは再帰呼出しになっているが,引数cが'\n'の場合に * 引数cを'\r'として呼び出すことから,この再帰呼出しは2回目の * 呼び出しで必ず止まる. */ SVC(rercd = serialPort_writeChar(p_cellcb, '\r'), rercd); if ((bool_t) rercd) { SVC(rercd = cSendSemaphore_wait(), gen_ercd_wait(rercd, p_cellcb)); } } SVC(loc_cpu(), gen_ercd_sys(p_cellcb)); if (VAR_sendCount == 0U && !VAR_sendStopped && serialPort_sendChar(p_cellcb, c)) { /* * SIOの送信レジスタに文字を入れることに成功した場合. */ buffer_full = false; } else { /* * 送信バッファに文字を入れる. */ VAR_sendBuffer[VAR_sendWritePointer] = c; INC_PTR(VAR_sendWritePointer, ATTR_sendBufferSize); VAR_sendCount++; buffer_full = (VAR_sendCount == ATTR_sendBufferSize); } SVC(unl_cpu(), gen_ercd_sys(p_cellcb)); ercd = (ER_BOOL) buffer_full; error_exit: return(ercd); }
int atexit(void (*func)(void)) { int result = -1; int sync = iniflg; if (sync) loc_cpu(); if (atexit_num < ATEXIT_MAX) { atexit_table[atexit_num++] = func; result = 0; } if (sync) unl_cpu(); return result; }
ER GPSRec_Open(UART_BAUDRATE BaudRate) { if (bGPSRecOpened) return E_SYS; #if (RECEIVE_FROM_UART2) if (uart2_open() == E_OK) #else if (uart_open() == E_OK) #endif { debug_msg("\r\nUART2: Open success\r\n"); #if (RECEIVE_FROM_UART2) uart2_init(BaudRate, UART_LEN_L8_S1, UART_PARITY_NONE); #else uart_init(BaudRate, UART_LEN_L8_S1, UART_PARITY_NONE); #endif } else { debug_err(("UART2: open fail!\r\n")); return E_SYS; } debug_msg("Start GPS receive task\r\n"); //#NT#2011/1/14#philex Lin-begin // init/toggle GPS Data buffer index, // GPS log buffer is double buffering mechanism. GPSRec_DataBufInit(); //#NT#2011/1/14#philex Lin-end sta_tsk(GPSRECEIVE_ID); loc_cpu(); bGPSRecOpened = TRUE; unl_cpu(); return E_OK; }
void cyclic_handler(intptr_t exinf) { HRTCNT hrtcnt, prev_hrtcnt; char *prev_hrtcnt_pos; (void) loc_cpu(); hrtcnt = fch_hrt(); prev_hrtcnt = recent_hrtcnt; prev_hrtcnt_pos = recent_hrtcnt_pos; recent_hrtcnt = hrtcnt; recent_hrtcnt_pos = "CYC"; (void) unl_cpu(); if (prev_hrtcnt > hrtcnt) { syslog(LOG_NOTICE, "system performance time goes back: %d(%s) %d(CYC)", prev_hrtcnt, prev_hrtcnt_pos, hrtcnt); } cyclic_count += 1U; }
/* * シリアルポートからの受信 */ static BOOL serial_rea_chr(SPCB *spcb, char *c) { BOOL buffer_empty; _syscall(loc_cpu()); /* * 受信バッファから文字を取り出す. */ *c = spcb->rcv_buffer[spcb->rcv_read_ptr]; INC_PTR(spcb->rcv_read_ptr); spcb->rcv_count--; buffer_empty = (spcb->rcv_count == 0); /* * START を送信する. */ if (spcb->rcv_stopped && spcb->rcv_count <= BUFCNT_START) { if (!serial_snd_chr(spcb, FC_START)) { spcb->rcv_fc_chr = FC_START; } spcb->rcv_stopped = FALSE; } _syscall(unl_cpu()); /* * エコーバック処理. */ if ((spcb->ioctl & IOCTL_ECHO) != 0) { _syscall(wai_sem(spcb->spinib->snd_semid)); if (!serial_wri_chr(spcb, *c)) { _syscall(sig_sem(spcb->spinib->snd_semid)); } } return(buffer_empty); }
/* * メインタスク */ void main_task(intptr_t exinf) { char c; ID tskid = TASK1; int_t tskno = 1; ER_UINT ercd; PRI tskpri; #ifndef TASK_LOOP volatile ulong_t i; SYSTIM stime1, stime2; #endif /* TASK_LOOP */ HRTCNT hrtcnt1, hrtcnt2; SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG))); syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf); /* * シリアルポートの初期化 * * システムログタスクと同じシリアルポートを使う場合など,シリアル * ポートがオープン済みの場合にはここでE_OBJエラーになるが,支障は * ない. */ ercd = serial_opn_por(TASK_PORTID); if (ercd < 0 && MERCD(ercd) != E_OBJ) { syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.", itron_strerror(ercd), SERCD(ercd)); } SVC_PERROR(serial_ctl_por(TASK_PORTID, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV))); /* * ループ回数の設定 * * 並行実行されるタスク内での空ループの回数(task_loop)は,空ルー * プの実行時間が約0.4秒になるように設定する.この設定のために, * LOOP_REF回の空ループの実行時間を,その前後でget_timを呼ぶことで * 測定し,その測定結果から空ループの実行時間が0.4秒になるループ回 * 数を求め,task_loopに設定する. * * LOOP_REFは,デフォルトでは1,000,000に設定しているが,想定したよ * り遅いプロセッサでは,サンプルプログラムの実行開始に時間がかか * りすぎるという問題を生じる.逆に想定したより速いプロセッサでは, * LOOP_REF回の空ループの実行時間が短くなり,task_loopに設定する値 * の誤差が大きくなるという問題がある. * * そこで,そのようなターゲットでは,target_test.hで,LOOP_REFを適 * 切な値に定義するのが望ましい. * * また,task_loopの値を固定したい場合には,その値をTASK_LOOPにマ * クロ定義する.TASK_LOOPがマクロ定義されている場合,上記の測定を * 行わずに,TASK_LOOPに定義された値を空ループの回数とする. * * ターゲットによっては,空ループの実行時間の1回目の測定で,本来よ * りも長めになるものがある.このようなターゲットでは,MEASURE_TWICE * をマクロ定義することで,1回目の測定結果を捨てて,2回目の測定結果 * を使う. */ #ifdef TASK_LOOP task_loop = TASK_LOOP; #else /* TASK_LOOP */ #ifdef MEASURE_TWICE task_loop = LOOP_REF; SVC_PERROR(get_tim(&stime1)); for (i = 0; i < task_loop; i++); SVC_PERROR(get_tim(&stime2)); #endif /* MEASURE_TWICE */ task_loop = LOOP_REF; SVC_PERROR(get_tim(&stime1)); for (i = 0; i < task_loop; i++); SVC_PERROR(get_tim(&stime2)); task_loop = LOOP_REF * 400LU / (ulong_t)(stime2 - stime1) * 1000LU; #endif /* TASK_LOOP */ /* * タスクの起動 */ SVC_PERROR(act_tsk(TASK1)); SVC_PERROR(act_tsk(TASK2)); SVC_PERROR(act_tsk(TASK3)); /* * メインループ */ do { SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1)); switch (c) { case 'e': case 's': case 'S': case 'd': case 'y': case 'Y': case 'z': case 'Z': message[tskno-1] = c; break; case '1': tskno = 1; tskid = TASK1; break; case '2': tskno = 2; tskid = TASK2; break; case '3': tskno = 3; tskid = TASK3; break; case 'a': syslog(LOG_INFO, "#act_tsk(%d)", tskno); SVC_PERROR(act_tsk(tskid)); break; case 'A': syslog(LOG_INFO, "#can_act(%d)", tskno); SVC_PERROR(ercd = can_act(tskid)); if (ercd >= 0) { syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd); } break; case 't': syslog(LOG_INFO, "#ter_tsk(%d)", tskno); SVC_PERROR(ter_tsk(tskid)); break; case '>': syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno); SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY)); break; case '=': syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno); SVC_PERROR(chg_pri(tskid, MID_PRIORITY)); break; case '<': syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno); SVC_PERROR(chg_pri(tskid, LOW_PRIORITY)); break; case 'G': syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno); SVC_PERROR(ercd = get_pri(tskid, &tskpri)); if (ercd >= 0) { syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri); } break; case 'w': syslog(LOG_INFO, "#wup_tsk(%d)", tskno); SVC_PERROR(wup_tsk(tskid)); break; case 'W': syslog(LOG_INFO, "#can_wup(%d)", tskno); SVC_PERROR(ercd = can_wup(tskid)); if (ercd >= 0) { syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd); } break; case 'l': syslog(LOG_INFO, "#rel_wai(%d)", tskno); SVC_PERROR(rel_wai(tskid)); break; case 'u': syslog(LOG_INFO, "#sus_tsk(%d)", tskno); SVC_PERROR(sus_tsk(tskid)); break; case 'm': syslog(LOG_INFO, "#rsm_tsk(%d)", tskno); SVC_PERROR(rsm_tsk(tskid)); break; case 'x': syslog(LOG_INFO, "#ras_ter(%d)", tskno); SVC_PERROR(ras_ter(tskid)); break; case 'r': syslog(LOG_INFO, "#rot_rdq(three priorities)"); SVC_PERROR(rot_rdq(HIGH_PRIORITY)); SVC_PERROR(rot_rdq(MID_PRIORITY)); SVC_PERROR(rot_rdq(LOW_PRIORITY)); break; case 'c': syslog(LOG_INFO, "#sta_cyc(1)"); SVC_PERROR(sta_cyc(CYCHDR1)); break; case 'C': syslog(LOG_INFO, "#stp_cyc(1)"); SVC_PERROR(stp_cyc(CYCHDR1)); break; case 'b': syslog(LOG_INFO, "#sta_alm(1, 5000000)"); SVC_PERROR(sta_alm(ALMHDR1, 5000000)); break; case 'B': syslog(LOG_INFO, "#stp_alm(1)"); SVC_PERROR(stp_alm(ALMHDR1)); break; case 'V': hrtcnt1 = fch_hrt(); hrtcnt2 = fch_hrt(); syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu", hrtcnt1, hrtcnt2); break; case 'o': #ifdef TOPPERS_SUPPORT_OVRHDR syslog(LOG_INFO, "#sta_ovr(%d, 2000000)", tskno); SVC_PERROR(sta_ovr(tskid, 2000000)); #else /* TOPPERS_SUPPORT_OVRHDR */ syslog(LOG_NOTICE, "sta_ovr is not supported."); #endif /* TOPPERS_SUPPORT_OVRHDR */ break; case 'O': #ifdef TOPPERS_SUPPORT_OVRHDR syslog(LOG_INFO, "#stp_ovr(%d)", tskno); SVC_PERROR(stp_ovr(tskid)); #else /* TOPPERS_SUPPORT_OVRHDR */ syslog(LOG_NOTICE, "stp_ovr is not supported."); #endif /* TOPPERS_SUPPORT_OVRHDR */ break; case 'v': SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG))); break; case 'q': SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG))); break; #ifdef BIT_KERNEL case ' ': SVC_PERROR(loc_cpu()); { extern ER bit_kernel(void); SVC_PERROR(ercd = bit_kernel()); if (ercd >= 0) { syslog(LOG_NOTICE, "bit_kernel passed."); } } SVC_PERROR(unl_cpu()); break; #endif /* BIT_KERNEL */ default: break; } } while (c != '\003' && c != 'Q'); syslog(LOG_NOTICE, "Sample program ends."); SVC_PERROR(ext_ker()); assert(0); }