Пример #1
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;
}
Пример #2
0
/*
 *  メインタスク
 */
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);
}