天天看點

opnet程序執行過程解讀

一、程序概念

在opnet中,程序模型是執行的最小機關,程序模型實際上就是一個函數,不同于作業系統中程序的概念。

在作業系統中,程序執行貫穿始終,從建立開始,到退出結束。

在opnet中,程序隻是一個函數,每次由opnet核心調用,程序從調用開始,到return退出,整個過程,就是一次函數調用。每次調用時,對于臨時變量都會重新初始化,不會保留上次調用後的值。

對于狀态變量和全局變量,是整個項目可見的,這點可以參照C語言程式設計中的全局變量和局部變量的概念。

C語言 opnet
對應關系 全局變量 狀态變量和全局變量
對應關系 局部變量 臨時變量

二、狀态模型

1)強制狀态

執行過程:opnet核心調用程序模型時,如果目前狀态是強制狀态時,首先執行其進入代碼,然後跳轉到離開代碼,再判斷轉移條件,直接跳轉到目标狀态的進入代碼,執行,跳轉過程是通過加标号label和跳轉語句goto實作的,整個過程沒有離開程序函數。

opnet程式執行過程解讀

2)非強制狀态

執行過程:opnet核心調用程序模型時,如果目前狀态是非強制狀态時,首先執行其進入代碼,然後設定下一狀态為該狀态的離開代碼,然後函數傳回return,等待下次調用。當再次調用程序函數時,此時狀态已是離開代碼,執行完後判斷轉移條件,直接跳轉到目标狀态的進入代碼,再次執行,跳轉過程同樣是通過加标号label和跳轉語句goto實作的,整個過程也沒有離開程序函數。

opnet程式執行過程解讀

3)綜述

程序函數隻有在執行完非強制狀态的進入代碼後開傳回,離開程序函數,傳回到opnet核心。

狀态轉移是按照常歸的switch語句實作的。

opnet程式執行過程解讀

三、案例分析

一個程序模型的部份源代碼:

void
csma_tx (OP_SIM_CONTEXT_ARG_OPT)
	{
....//其它代碼
	FIN_MT (csma_tx ());
		{
		/* Temporary Variables */
		Boolean state_reentered = OPC_FALSE;
		/* End of Temporary Variables */


		FSM_ENTER ("csma_tx")
		FSM_BLOCK_SWITCH
			{
			/*---------------------------------------------------------*/
			/** state (init) enter executives **/
			FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "csma_tx [init enter execs]")
				FSM_PROFILE_SECTION_IN ("csma_tx [init enter execs]", state0_enter_exec)
				{
				op_ima_sim_attr_get_int32("max packet count", &max_packet_count);	
				}
				FSM_PROFILE_SECTION_OUT (state0_enter_exec)


			/** state (init) exit executives **/
			FSM_STATE_EXIT_FORCED (0, "init", "csma_tx [init exit execs]")


			/** state (init) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle", "tr_0", "csma_tx [init -> idle : default / ]")
				/*---------------------------------------------------------*/


			/** state (idle) enter executives **/
			FSM_STATE_ENTER_UNFORCED (1, "idle", state1_enter_exec, "csma_tx [idle enter execs]")
				FSM_PROFILE_SECTION_IN ("csma_tx [idle enter execs]", state1_enter_exec)
				{
				if(state_reentered == OPC_FALSE)
					{
					printf("進入狀态\n");
					op_intrpt_schedule_self(op_sim_time() + 0.0001, 1);
					}
				else
					{
					printf("這個是次重入過程\n");
					}
				}
				FSM_PROFILE_SECTION_OUT (state1_enter_exec)


			/** blocking after enter executives of unforced state. **/
			FSM_EXIT (3,"csma_tx")//離開程序函數


			/** state (idle) exit executives **/
			FSM_STATE_EXIT_UNFORCED (1, "idle", "csma_tx [idle exit execs]")
				FSM_PROFILE_SECTION_IN ("csma_tx [idle exit execs]", state1_exit_exec)
				{				
				}
				FSM_PROFILE_SECTION_OUT (state1_exit_exec)


			/** state (idle) transition processing **/
			FSM_PROFILE_SECTION_IN ("csma_tx [idle trans conditions]", state1_trans_conds)
			FSM_INIT_COND (PKT_ARVL && FREE)
			FSM_TEST_COND (PKT_ARVL && !FREE)
			FSM_DFLT_COND
			FSM_TEST_LOGIC ("idle")
			FSM_PROFILE_SECTION_OUT (state1_trans_conds)


			FSM_TRANSIT_SWITCH
				{
				FSM_CASE_TRANSIT (0, 2, state2_enter_exec, print_power_channelidle();, "PKT_ARVL && FREE", "print_power_channelidle()", "idle", "tx_pkt", "tr_1", "csma_tx [idle -> tx_pkt : PKT_ARVL && FREE / print_power_channelidle()]")
				FSM_CASE_TRANSIT (1, 3, state3_enter_exec, print_power_channelbusy();, "PKT_ARVL && !FREE", "print_power_channelbusy()", "idle", "wait_free", "tr_8", "csma_tx [idle -> wait_free : PKT_ARVL && !FREE / print_power_channelbusy()]")
				FSM_CASE_TRANSIT (2, 1, state1_enter_exec, SET_REENTRY;, "default", "SET_REENTRY", "idle", "idle", "tr_3", "csma_tx [idle -> idle : default / SET_REENTRY]")
				}
				/*---------------------------------------------------------*/
				....//其它代碼
			}


		FSM_EXIT (0,"csma_tx")
		}
           

接下來看一次标紅處的宏是什麼(P_fsm_dec.h):

采用常歸的switch語句實作狀态轉移

opnet程式執行過程解讀

強制狀态進入宏,通過case先擇執行哪個狀态

opnet程式執行過程解讀
opnet程式執行過程解讀

強制狀态離開宏,設定離開後的下一個狀态2 * sn + 1

opnet程式執行過程解讀
opnet程式執行過程解讀

強制狀态離開後轉移過程,通和設定标号label和goto語句實作跳轉

opnet程式執行過程解讀

非強制狀态進入宏,通過case先擇執行哪個狀态

opnet程式執行過程解讀
opnet程式執行過程解讀

進入非強制狀态後,執行return,傳回opnet核心

opnet程式執行過程解讀
opnet程式執行過程解讀

非強制狀态離開宏,設定離開後的下一個狀态2 * sn + 1

opnet程式執行過程解讀
opnet程式執行過程解讀

非強制狀态離開後轉移過程,同樣通和設定标号label和goto語句實作跳轉

opnet程式執行過程解讀
opnet程式執行過程解讀