/*---------------------------------------------------------------------------* * Routine: sys_thread_new *---------------------------------------------------------------------------* * Description: * Starts a new thread with priority "prio" that will begin its * execution in the function "thread()". The "arg" argument will be * passed as an argument to the thread() function. The id of the new * thread is returned. Both the id and the priority are system * dependent. * Inputs: * char *name -- Name of thread * void (*thread)(void *arg) -- Pointer to function to run. * void *arg -- Argument passed into function * int stacksize -- Required stack amount in bytes * int priority -- Thread priority * Outputs: * sys_thread_t -- Pointer to thread handle. *---------------------------------------------------------------------------*/ sys_thread_t sys_thread_new(const char *pcName, void (*thread)(void *arg), void *arg, int stacksize, int priority) { ER ercd; T_CTSK ctsk; LWIP_DEBUGF(SYS_DEBUG, ("New Thread: %s\n", pcName)); if (thread_pool_index >= SYS_THREAD_POOL_N) { error("sys_thread_new number error\n"); } sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index]; thread_pool_index++; #ifdef CMSIS_OS_RTX t->def.pthread = (os_pthread)thread; t->def.tpriority = (osPriority)priority; t->def.stacksize = stacksize; t->def.stack_pointer = (uint32_t*)malloc(stacksize); if (t->def.stack_pointer == NULL) { error("Error allocating the stack memory"); } #endif // t->id = osThreadCreate(&t->def, arg); ctsk.tskatr = TA_ACT; ctsk.exinf = (intptr_t)arg; ctsk.task = (TASK)thread; ctsk.itskpri = (PRI)priority; ctsk.stksz = stacksize; ctsk.stk = NULL; ercd = acre_tsk(&ctsk); if (ercd < 0) { error("sys_thread_new create error\n"); } t->id = ercd; syslog(LOG_DEBUG, "A new task %s(ID=%d) with Pri=%d was created now.", pcName, t->id, priority); return t; }
/* * メインタスク */ 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; T_CTSK ctsk; ID TASK3 = -1; T_CALM calm; ID ALMHDR1 = -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回目の測定結果 * を使う. */ #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)); /* * メインループ */ 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 '@': 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)); 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 '$': calm.almatr = TA_NULL; calm.nfyinfo.nfymode = TNFY_HANDLER; calm.nfyinfo.nfy.handler.exinf = (intptr_t) 0; calm.nfyinfo.nfy.handler.tmehdr = (TMEHDR) alarm_handler; SVC_PERROR(ALMHDR1 = acre_alm(&calm)); syslog(LOG_NOTICE, "alarm handler is created with almid = %d.", (int_t) ALMHDR1); break; case '#': syslog(LOG_INFO, "#del_alm(1)"); SVC_PERROR(del_alm(ALMHDR1)); break; case 'V': hrtcnt1 = fch_hrt(); hrtcnt2 = fch_hrt(); syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu", hrtcnt1, hrtcnt2); 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); }
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; }