// $RCSfile: pubfuncs.c,v $Revision: 1.24 $Date: 2005/03/11 15:08:57 #include "allnodes.h" #include "node1.h" #include #include "configura.h" #include "MilDef.h" #include "allnodes.h" #include "node1.h" #include "err_hdl.h" #include "cmd_seq.h" #include "tables.h" #include "pubfuncs.h" #include "time_tsk.h" //----------------------- Global Variables ------------------------------------- // the following array is a global variable for monitoring the number of // used blocks inside the 5 Virtuoso memory pools; it is written by the // functions get_block, release_block and it is read by the function res_chk. unsigned int Memory_Pool_Occupation[5] = {0, 0, 0, 0, 0}; unsigned int Hs_event = HS_EVENT; // Following a last-minute addendum, BB_ID must be reset when Obs_ID changes. // Any TC containing a BB_ID will consequently set it unsigned int Observation_ID = 0; unsigned int Meas_BuildingBlock_ID; unsigned int Cur_BuildingBlock_ID; //----------------------- init_block ------------------------------------------- // ! sets to null all the words of the block just requested // input: Pointer to the block structure and number of words to be initialized. void init_block (K_BLOCK *p_block, int length) { int i, *p_data; for (i = 0, p_data = p_block->pointer_to_data; i < length; *(p_data++) = 0, i++); } //----------------------- compute_and_add_LCU_CRC ------------------------------------------- // ! the input is a LCU macro vector of 14 elements. The crc is computed and added at the end if the original bits of the crc are zero void compute_and_add_LCU_CRC (unsigned int * lcu_macro) { unsigned int crc; int i; // check that this is really a LCU macro if ( (lcu_macro[0] & 0xFFF00000) != 0xF2000000 ) {generate_event(EVENT_EVENT_REPORT, RUNTIME_ERROR_EVID, ERR_PF_LCU_CRC, 0, NULL); return;} if ( (lcu_macro[13] & 0xFFF00000) != 0xF2F00000 ) {generate_event(EVENT_EVENT_REPORT, RUNTIME_ERROR_EVID, ERR_PF_LCU_CRC, 0, NULL); return;} // chck if the crc is to be added (depends on the last 20 bits of the last macro command if ( (lcu_macro[13] & 0x000FFFFF) == 0 ) return; // init CRC crc = 0xF00000; // compute crc for (i=1; i<=12; i++) crc = crc - (lcu_macro[i] & 0xFFFFF); // add crc to the macro lcu_macro[13] = (lcu_macro[13] & 0xFFF00000) | (crc & 0xFFFFF); } //----------------------- prepare_TM_packet ------------------------------------ // ! this function writes the first 16 bytes of the TM packet (packet header and data field header) void prepare_TM_packet (K_BLOCK * block, unsigned int DFHF, unsigned int APID, unsigned int len, unsigned int type, unsigned int subtype) { typedef struct { TM_HEADER pakt_header; TM_DATA_FIELD_HEADER data_header; } HEADER; HEADER * header; // init header pointer header = (HEADER *) block->pointer_to_data; // Packet ID header->pakt_header.TC_packet_ID = 0; // First reset header->pakt_header.TC_packet_ID = APID | (DFHF << 11); // Packet Sequence Control (Source Sequence Counter and Segmentation Flag) header->pakt_header.packet_seq_ctrl = SEGM_FLAG_MSK; // here we just set the segmentation // flag two bits (only selfstanding packets are used); sequence counter will be written in tmtc task // Packet Length header->pakt_header.length = len; // 10 octets data field header + 2 octets CRC + source data length - 1 // Data Field Header: Type & subtype header->data_header.type_PUS = type; // PUS and spares are 0s header->data_header.subtype_spare = (subtype<<8); // spares are in the lsb // Data Field Header: On Board Time get_TS(&(header->data_header.TS)); // Current 48 bits Time Stamp } //----------------------- andmask ---------------------------------------------- unsigned int andmask (unsigned int * dst, unsigned int len, unsigned int mask) { for(; len>0; len--) *dst++ &= mask; return mask; } //------------ DPU_wait -------------------------------------------------------- //! This function is used to wait a time, defined in msec void DPU_wait (unsigned int time_to_wait) { K_TICKS timestamp, cumulative_diff = 0; (void) KS_LowTimerElapsed(×tamp); do cumulative_diff += KS_LowTimerElapsed(×tamp); while (cumulative_diff < time_to_wait); return; } /**********************************************************************************************/ /**********************************************************************************************/ /* VIRTUOSO POOL INTERFACE */ /**********************************************************************************************/ /**********************************************************************************************/ //----------------------- get_block -------------------------------------------- int get_block (K_BLOCK * block, K_POOL poolid, int size) { // allocation of the block if (KS_PoolGetBlock(block, poolid, size) != RC_OK) { generate_event(EVENT_EVENT_REPORT, RUNTIME_ERROR_EVID, ERR_PF_GET_BLOCK_FAIL, 1, &poolid); return RC_FAIL; } // now we must increment the counter of memory blocks in use switch (poolid) { case SD_POOL : KS_ResLockW(POOL_MONITOR); ++Memory_Pool_Occupation[0]; KS_ResUnlock(POOL_MONITOR); break; case TC_POOL : KS_ResLockW(POOL_MONITOR); ++Memory_Pool_Occupation[1]; KS_ResUnlock(POOL_MONITOR); break; case EV_POOL : KS_ResLockW(POOL_MONITOR); ++Memory_Pool_Occupation[2]; KS_ResUnlock(POOL_MONITOR); break; case HK_POOL : KS_ResLockW(POOL_MONITOR); ++Memory_Pool_Occupation[3]; KS_ResUnlock(POOL_MONITOR); break; case STF_POOL : KS_ResLockW(POOL_MONITOR); ++Memory_Pool_Occupation[4]; KS_ResUnlock(POOL_MONITOR); break; default: generate_event(EVENT_EVENT_REPORT, RUNTIME_ERROR_EVID, ERR_PF_GET_BLOCK_UNKNOWN_POOLID, 1, &poolid); break; } return RC_OK; } //----------------------- release_block ---------------------------------------- int release_block (K_BLOCK * block) { // we must decrement the counter of memory blocks in use switch (block->poolid) { case SD_POOL : KS_ResLockW(POOL_MONITOR); --Memory_Pool_Occupation[0]; KS_ResUnlock(POOL_MONITOR); break; case TC_POOL : KS_ResLockW(POOL_MONITOR); --Memory_Pool_Occupation[1]; KS_ResUnlock(POOL_MONITOR); break; case EV_POOL : KS_ResLockW(POOL_MONITOR); --Memory_Pool_Occupation[2]; KS_ResUnlock(POOL_MONITOR); break; case HK_POOL : KS_ResLockW(POOL_MONITOR); --Memory_Pool_Occupation[3]; KS_ResUnlock(POOL_MONITOR); break; case STF_POOL : KS_ResLockW(POOL_MONITOR); --Memory_Pool_Occupation[4]; KS_ResUnlock(POOL_MONITOR); break; default: generate_event(EVENT_EVENT_REPORT, RUNTIME_ERROR_EVID, ERR_PF_REL_BLOCK_UNKNOWN_POOLID, 1, &(block->poolid)); break; } // now free the block KS_PoolFreeBlock(block); return RC_OK; }