static ER handle_module_cfg_tab(T_LDM_CAN *ldm_can) { // TODO: check cfg table memory assert(ldm_can->cfg_entry_num > 0 && ldm_can->cfg_table != NULL); assert(probe_ldm_memory(ldm_can->cfg_table, sizeof(MOD_CFG_ENTRY) * ldm_can->cfg_entry_num, ldm_can)); ER_ID ercd = E_OK; // Creation stage for(SIZE i = 0; i < ldm_can->cfg_entry_num && ercd == E_OK; ++i) { MOD_CFG_ENTRY *ent = &ldm_can->cfg_table[i]; switch(ent->sfncd) { case TSFN_CRE_TSK: { syslog(LOG_DEBUG, "%s(): MOD_CFG_ENTRY TSFN_CRE_TSK", __FUNCTION__); assert(probe_ldm_memory(ent->argument, sizeof(T_CTSK), ldm_can)); assert(probe_ldm_memory(ent->retvalptr, sizeof(ID), ldm_can)); T_CTSK pk_ctsk = *(T_CTSK*)ent->argument; assert(probe_ldm_memory(pk_ctsk.stk, pk_ctsk.stksz, ldm_can)); // Check user stack assert(pk_ctsk.sstk == NULL); // Check system stack pk_ctsk.tskatr &= ~TA_ACT; // Clear TA_ACT assert(get_atrdomid(pk_ctsk.tskatr) == TDOM_SELF); // Check original DOMID pk_ctsk.tskatr |= TA_DOM(ldm_can->domid); // Set new DOMID pk_ctsk.task = app_tsk_wrapper; // Use task wrapper pk_ctsk.exinf = (intptr_t)ent->argument; ercd = acre_tsk(&pk_ctsk); assert(ercd > 0); if(ercd > 0) { // Store ID *(ID*)ent->retvalptr = ercd; // Setup task exception routine T_DTEX dtex; dtex.texatr = TA_NULL; dtex.texrtn = app_tex_rtn; ercd = def_tex(ercd, &dtex); assert(ercd == E_OK); #if defined(DEBUG) syslog(LOG_NOTICE, "%s(): Task (tid = %d) created.", __FUNCTION__, *(ID*)ent->retvalptr); #endif ercd = E_OK; } break; } case TSFN_CRE_SEM: { syslog(LOG_DEBUG, "%s(): MOD_CFG_ENTRY TSFN_CRE_SEM", __FUNCTION__); assert(probe_ldm_memory(ent->argument, sizeof(T_CSEM), ldm_can)); assert(probe_ldm_memory(ent->retvalptr, sizeof(ID), ldm_can)); T_CSEM pk_csem = *(T_CSEM*)ent->argument; // TODO: check pk_csem ercd = acre_sem(&pk_csem); assert(ercd > 0); if(ercd > 0) { // Store ID *(ID*)ent->retvalptr = ercd; #if defined(DEBUG) syslog(LOG_NOTICE, "%s(): Semaphore (id = %d) is created.", __FUNCTION__, *(ID*)ent->retvalptr); #endif ercd = E_OK; } break; } case TSFN_CRE_FLG: { syslog(LOG_DEBUG, "%s(): MOD_CFG_ENTRY TSFN_CRE_FLG", __FUNCTION__); assert(probe_ldm_memory(ent->argument, sizeof(T_CFLG), ldm_can)); assert(probe_ldm_memory(ent->retvalptr, sizeof(ID), ldm_can)); T_CFLG pk_cflg = *(T_CFLG*)ent->argument; // TODO: check pk_csem ercd = acre_flg(&pk_cflg); assert(ercd > 0); if(ercd > 0) { // Store ID *(ID*)ent->retvalptr = ercd; #if defined(DEBUG) syslog(LOG_NOTICE, "%s(): Event flag (id = %d) is created.", __FUNCTION__, *(ID*)ent->retvalptr); #endif ercd = E_OK; } break; } default: syslog(LOG_ERROR, "%s(): Unsupported static function code %d.", __FUNCTION__, ent->sfncd); ercd = E_OBJ; } } // Rollback stage // TODO: implement this assert(ercd == E_OK); syslog(LOG_DEBUG, "%s(): text paddr: 0x%x, data paddr: 0x%x", __FUNCTION__, ldm_can->text_mempool, ldm_can->data_mempool); // Acting stage for(SIZE i = 0; i < ldm_can->cfg_entry_num; ++i) { MOD_CFG_ENTRY *ent = &ldm_can->cfg_table[i]; switch(ent->sfncd) { case TSFN_CRE_TSK: { T_CTSK pk_ctsk = *(T_CTSK*)ent->argument; if(pk_ctsk.tskatr & TA_ACT) { ercd = act_tsk(*(ID*)ent->retvalptr); assert(ercd == E_OK); } break; } default: syslog(LOG_ERROR, "%s(): Unsupported static function code %d.", __FUNCTION__, ent->sfncd); } } return ercd; }
/* * メインタスク */ 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 */ #ifdef TOPPERS_SUPPORT_GET_UTM SYSUTM utime1, utime2; #endif /* TOPPERS_SUPPORT_GET_UTM */ T_CTSK ctsk; T_DTEX dtex; ID TASK3 = -1; 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回目の測定結果 * を使う. * * タスク例外処理ルーチン内での空ループの回数(tex_loop)は, * task_loopの4分の1の値(空ループの実行時間が0.1秒になるループ回 * 数)に設定する. */ #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 * 400UL / (stime2 - stime1); #endif /* TASK_LOOP */ tex_loop = task_loop / 4; /* * タスクの起動 */ SVC_PERROR(act_tsk(TASK1)); SVC_PERROR(act_tsk(TASK2)); /* * メインループ */ 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_tex(%d, 0x0001U)", tskno); SVC_PERROR(ras_tex(tskid, 0x0001U)); break; case 'X': syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno); SVC_PERROR(ras_tex(tskid, 0x0002U)); 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, 5000)"); SVC_PERROR(sta_alm(ALMHDR1, 5000)); break; case 'B': syslog(LOG_INFO, "#stp_alm(1)"); SVC_PERROR(stp_alm(ALMHDR1)); break; case '@': ctsk.tskatr = TA_NULL; ctsk.exinf = 3; ctsk.task = task; ctsk.itskpri = MID_PRIORITY; ctsk.stksz = STACK_SIZE; ctsk.stk = NULL; SVC_PERROR(TASK3 = acre_tsk(&ctsk)); dtex.texatr = TA_NULL; dtex.texrtn = tex_routine; SVC_PERROR(def_tex(TASK3, &dtex)); syslog(LOG_NOTICE, "task3 is created with tskid = %d.", (int_t) TASK3); break; case '!': syslog(LOG_INFO, "#del_tsk(%d)", tskno); SVC_PERROR(del_tsk(tskid)); break; case 'V': #ifdef TOPPERS_SUPPORT_GET_UTM SVC_PERROR(get_utm(&utime1)); SVC_PERROR(get_utm(&utime2)); syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld", (ulong_t) utime1, (ulong_t) utime2); #else /* TOPPERS_SUPPORT_GET_UTM */ syslog(LOG_NOTICE, "get_utm is not supported."); #endif /* TOPPERS_SUPPORT_GET_UTM */ 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 */ case '$': syslog(LOG_INFO, "#%d#twai_sem(10000)", tskno); SVC_PERROR(twai_sem(TEST_SEM, 10000)); break; default: break; } } while (c != '\003' && c != 'Q'); syslog(LOG_NOTICE, "Sample program ends."); SVC_PERROR(ext_ker()); assert(0); }