/** * MIL-STD 1553B Library - Carlo Gavazzi Space * * Filename : \file Milmem.c * * Purposes : \brief MIL-STD 1553B Library - Carlo Gavazzi Space * * Logical Task : N/A * * Author : CGSpace * * Last Developer : $Author: lorenzo $ * * Revision : $Revision: 1.3 * * Checkout Tag : $Name: $ * * Last Modification : $Date: 2006/10/20 09:22:14 $ * * Location : $RCSfile: Milmem.c,v $ * * \version : $Header: /home/local/cvsrep/OBS_FM/1553_Lib/Milmem.c,v 1.10 2006/10/20 09:22:14 lorenzo Exp $ */ /** * Commitments History : * As reported in Main cvs Documentation * ( https://www.cvshome.org/docs/manual/cvs-1.11.18/cvs_12.html#SEC102 ) * The Modification Log has been posted at End Of File. */ // ---------------------------------------------------------------------------// /* Milmem.c - These routines allow for the dynamic allocation of ACE memory. The system used is a linked list of handles (MemBlockType). The handle is to a memory block structure containing information such as absolute address, size, and protection status. This allows for the protection of blocks of memory and the automatic allocation of variable size memory blocks within the memory space of the ACEbrief description */ /* Purpose: The module contains the routine for the dynamic allocation of ACE memory Content: The module contains the following functions: - SUBHEADINGS Project : HSO/FIRST BASIC S/W Component : HSO/FIRST DRIVERS S/W Filename : $RCSfile: Milmem.c,v $ CI Number : Revision : Revision: 1.3 Company : Carlo Gavazzi Space S.P.A. Author : Andrea Bertoli Creation Date : 2000/05/15 SEE ALSO: ADD Ref: Inserted here reference with Architectural Design and Detail Document. Other Ref: Notes: */ /* include header */ #include "MilDef.h" extern unsigned int IFSI_MOD(unsigned int, unsigned int); /******************************************************************** * * CreateMemBlockHandle - create a new block handler * * function description * Returns a new block handler and initiliaze the structure * MemBlockHandle fields as follow. * - j_Size = 0; * - m_AbsAddr = 0; * - d-Status = UNUSED; * - pw_Next = NULL pointer * _ pw_Prev = NULL pointer* * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: handle to new block * * SEE ALSO: * MilAlloc( ) function * * INTERNAL * This section will not appear in the generated manual entry. * */ MemBlockHandle CreateMemBlockHandle( MilConf_p pw_MilConf ) { /* alloc handle */ MemBlockHandle pw_MemBlockHandler; pw_MemBlockHandler=MilMalloc(pw_MilConf,sizeof(MemBlockType)); /* initialize handler */ pw_MemBlockHandler->j_Size=0; pw_MemBlockHandler->m_AbsAddr=0; pw_MemBlockHandler->d_Status=UNUSED; pw_MemBlockHandler->pw_Next=NULL; pw_MemBlockHandler->pw_Prev=NULL; /* return handle */ return(pw_MemBlockHandler); } /******************************************************************** * * MemBlockRemove - Remove a memory block * * Description * Removes a memory block from the pw_MilConf->pw_AceMemory list. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Tp message handle to be removed * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error condition * * SEE ALSO: * * * INTERNAL * */ MilError_t MemBlockRemove( MilConf_p pw_MilConf, MemBlockHandle pw_Tp ) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); /* if p is the head of the list then make p's next the head */ if(pw_Tp == pw_MilConf->pw_AceMemory) pw_MilConf->pw_AceMemory = pw_Tp->pw_Next; /* if p is next free blk then set next free blk to p's next*/ if(pw_Tp == pw_MilConf->pw_AceCurrent) pw_MilConf->pw_AceCurrent = pw_Tp->pw_Next; /* if p has a next then connect it to p's prev */ if(pw_Tp->pw_Next) pw_Tp->pw_Next->pw_Prev = pw_Tp->pw_Prev; /* if p has a prev then connect it to p's next */ if(pw_Tp->pw_Prev) pw_Tp->pw_Prev->pw_Next = pw_Tp->pw_Next; /* free block */ MilFree(pw_MilConf, pw_Tp); return(MIL_SUCCESS); } /******************************************************************** * * MemBlockInsert - Insert a new block in the list * * Description * Inserts a memory block into the list before a * specified block. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Area The block handle to inser the message before * - pw_Blk The block handle to be inserted * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * N/A * * INTERNAL * */ MilError_t MemBlockInsert( MilConf_p pw_MilConf, MemBlockHandle pw_Area, MemBlockHandle pw_Blk ) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); /* check if area is valid */ if(pw_Area==NULL) { /* no, append to current AceListEnd */ pw_Blk->pw_Prev = pw_MilConf->pw_AceListEnd; /* there is no next at end of the list */ pw_Blk->pw_Next=NULL; /* current AceListEnd's next is now blk */ pw_MilConf->pw_AceListEnd->pw_Next = pw_Blk; /* AceListEnd become blk */ pw_MilConf->pw_AceListEnd = pw_Blk; } else { /* blk's next is now area */ pw_Blk->pw_Next = pw_Area; /* blk's prev is (area's old prev) */ pw_Blk->pw_Prev = pw_Area->pw_Prev; /* area's prev is blk */ pw_Area->pw_Prev=pw_Blk; /* if area had a prev then it's next is set to blk */ if(pw_Blk->pw_Prev) pw_Blk->pw_Prev->pw_Next= pw_Blk; /* if area was head of list then blk is made the head */ if(pw_Area == pw_MilConf->pw_AceMemory) pw_MilConf->pw_AceMemory= pw_Blk; } return(MIL_SUCCESS); } /******************************************************************** * * SwapMemBlocks - Swaps one block handle * * Description * Swaps one block handle with another block handle in * the list of message handles. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Tp a memory block handle to be swapped out * - pw_Tq a memory block handle to be swapped in * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * N/A * * INTERNAL * */ MilError_t SwapMemBlocks( MilConf_p pw_MilConf, MemBlockHandle pw_Tp, MemBlockHandle pw_Tq ) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); /* if p is at end of list then set the end to be q */ if(pw_Tp == pw_MilConf->pw_AceListEnd) pw_MilConf->pw_AceListEnd= pw_Tq; /* the link pointers of q are gotten from p */ pw_Tq->pw_Next=pw_Tp->pw_Next; pw_Tq->pw_Prev=pw_Tp->pw_Prev; /* the link pointers of p's neighbors are linked to q */ if(pw_Tp->pw_Next) pw_Tp->pw_Next->pw_Prev= pw_Tq; if(pw_Tp->pw_Prev) pw_Tp->pw_Prev->pw_Next= pw_Tq; MilFree(pw_MilConf, pw_Tp); return(MIL_SUCCESS); } /******************************************************************** * * MilInitBlockList - Initializes the memory management system * * Description * Initializes the memory managment system. The system is a * linked list of handles. Each handle is a fixed size, but * contains information about variable size memory blocks in * ram. It is initialized by creating a handle. This handle * is set to have an absolute address at the beginning of ram * and to contain all ram. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * CreateMemBlockHandlle( ) function * * INTERNAL * */ MilError_t MilInitBlockList( MilConf_p pw_MilConf ) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); /* AceMemory is the head of the list */ pw_MilConf->pw_AceMemory=(MemBlockHandle)CreateMemBlockHandle(pw_MilConf); /* block's size is whole of memory */ /* MilConf->AceMemory->size = MilConf->MilMemoryLength; fixed warinings - size should be typecast from BuConf.MilMemLength U32BIT to AceMemory.size */ pw_MilConf->pw_AceMemory->j_Size = (unsigned int)pw_MilConf->j_MilMemoryLength; /* block's offset is start of memory */ pw_MilConf->pw_AceMemory->m_AbsAddr = 0; /* AceCurrent is the next available free block */ pw_MilConf->pw_AceCurrent = pw_MilConf->pw_AceMemory; /* AceListEnd is the last block in the list */ pw_MilConf->pw_AceListEnd = pw_MilConf->pw_AceMemory; return(MIL_SUCCESS); } /******************************************************************** * * MilClearBlockList - Clear the memory * * Description * This routine is used to clean the memory block list of all * allocated block's (except PERMANENT blocks) * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * * INTERNAL * */ MilError_t MilClearBlockList( MilConf_p pw_MilConf ) { MemBlockHandle pw_Tp,pw_Tq; if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); pw_Tp=pw_Tq=pw_MilConf->pw_AceMemory; while(pw_Tq!=NULL) { pw_Tp= pw_Tq; pw_Tq= pw_Tq->pw_Next; if(!(pw_Tp->d_Status & PERMANENT)) { pw_Tp->d_Status=UNUSED; if(pw_Tp->pw_Prev) { if(pw_Tp->pw_Prev->d_Status==UNUSED) { /* increment the free Size */ pw_Tp->pw_Prev->j_Size += pw_Tp->j_Size; MemBlockRemove(pw_MilConf,pw_Tp); /* MilFree(pw_MilConf, pw_Tp); inserted in the MemBlockRemove */ } } } } /* AceCurrent is the next available free block */ pw_MilConf->pw_AceCurrent = pw_MilConf->pw_AceMemory; /* AceListEnd is the last block in the list */ pw_MilConf->pw_AceListEnd = pw_MilConf->pw_AceMemory; return(MIL_SUCCESS); } /******************************************************************** * * MilCloseBlockList - free's each handle in the block list * * Description * The memory managment system is a linked list of handles. * This routine starts at the head of the list, traverses the * list and free's each handle up to and including the tail. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * * INTERNAL * */ MilError_t MilCloseBlockList(MilConf_p pw_MilConf) { MemBlockHandle pw_Tp,pw_Tq; if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); pw_Tp=pw_Tq=pw_MilConf->pw_AceMemory; while(pw_Tq!=NULL) { pw_Tp=pw_Tq; pw_Tq=pw_Tq->pw_Next; MilFree(pw_MilConf,pw_Tp); } pw_MilConf->pw_AceMemory=NULL; pw_MilConf->pw_AceCurrent=NULL; pw_MilConf->pw_AceListEnd=NULL; return(MIL_SUCCESS); } /******************************************************************** * * CreatePermanentMemBlock - Create Permanent Memory Block * * Description * Creates a permanent memory block that is not destroyed * with MilClearBlockList() * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Area place to insert new permanent block * - m_Addr Absolute start address of the new Area * - j_Size Size of the new area * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Handler to new permanent block * * SEE ALSO: * * INTERNAL * */ MemBlockHandle CreatePermanentMemBlock( MilConf_p pw_MilConf, MemBlockHandle pw_Area, unsigned long m_Addr, unsigned int j_Size ) { MemBlockHandle pw_Tp; if(!pw_MilConf) return(NULL); pw_Tp= CreateProtectedMemBlock(pw_MilConf, pw_Area, m_Addr, j_Size); if(pw_Tp) pw_Tp->d_Status=PERMANENT; return(pw_Tp); } /******************************************************************** * * CreateProtectedMemBlock - Creates a protected memory block * * Description * Creates a protected memory block * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Area place to insert new permanent block * - m_Addr Absolute start address of the new Area * - j_Size Size of the new area * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Handler to new permanent block * * SEE ALSO: * * INTERNAL * The function when is called more time doesn't check the * overlapping * */ MemBlockHandle CreateProtectedMemBlock( MilConf_p pw_MilConf, MemBlockHandle pw_Area, unsigned long m_Addr, unsigned int j_Size ) { MemBlockHandle pw_Tp, pw_Tp2; if(!pw_MilConf)return(NULL); /* create new handle */ pw_Tp=CreateMemBlockHandle(pw_MilConf); /* set the address */ pw_Tp->m_AbsAddr=m_Addr; /* set the size */ pw_Tp->j_Size=j_Size; /* set the status */ pw_Tp->d_Status=PROTECTED; if(m_Addr> pw_Area->m_AbsAddr) { MemBlockInsert(pw_MilConf, pw_Area->pw_Next,pw_Tp); /* if the end of the original block does not match the end of the new block we must add an unused block after the newly declared block */ if((m_Addr+ j_Size)!=(pw_Area->m_AbsAddr+ pw_Area->j_Size)) { pw_Tp2=CreateMemBlockHandle(pw_MilConf); pw_Tp2->j_Size = (pw_Area->m_AbsAddr + pw_Area->j_Size)-(pw_Tp->m_AbsAddr + pw_Tp->j_Size); pw_Tp2->m_AbsAddr = pw_Tp->m_AbsAddr + pw_Tp->j_Size; /* calculate size and addr of third block and add it after newly defined block */ MemBlockInsert(pw_MilConf, pw_Tp->pw_Next, pw_Tp2); } pw_Area->j_Size = m_Addr - pw_Area->m_AbsAddr; } /* check to see if the absaddr of area is the same as addr */ else { if(m_Addr== pw_Area->m_AbsAddr) { /* yes, so insert tp before area */ MemBlockInsert(pw_MilConf,pw_Area,pw_Tp); /* the absaddr of area is now after tp's space */ pw_Area->m_AbsAddr = m_Addr + j_Size; /* and area's size is smaller since tp took some */ pw_Area->j_Size -= j_Size; /* if there is none left, the handle is removed */ if(pw_Area->j_Size==0) { MemBlockRemove(pw_MilConf,pw_Area); /* included in MemBlockRemove */ /* MilFree(pw_MilConf, pw_Area); */ } } else { MemBlockInsert(pw_MilConf, pw_Area->pw_Next,pw_Tp); /* if the end of the original block does not match the end of the new block we must add an unused block after the newly declared block */ if((m_Addr+ j_Size)!=(pw_Area->m_AbsAddr + pw_Area->j_Size)) { pw_Tp2=CreateMemBlockHandle(pw_MilConf); pw_Tp2->j_Size = (pw_Area->m_AbsAddr+ pw_Area->j_Size) -(pw_Tp->m_AbsAddr + pw_Tp->j_Size); pw_Tp2->m_AbsAddr = pw_Tp->m_AbsAddr + pw_Tp->j_Size; /* calculate size and addr of third block and add it after newly defined block */ MemBlockInsert(pw_MilConf, pw_Tp->pw_Next,pw_Tp2); } pw_Area->j_Size = m_Addr - pw_Area->m_AbsAddr; } } return(pw_Tp); } /******************************************************************** * * MilAllocateOnBoard - Takes an existing free memory block and splits * it into two blocks * * Description * Takes an existing free memory block and splits it into two * blocks. One is of (size), a handle to which is returned, the * other is any remaining free space. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Area the block of memory where the block will be put * - j_Size the size of memory to be allocated * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Handler to new permanent block * * SEE ALSO: * * INTERNAL * */ MemBlockHandle MilAllocateOnBoard( MilConf_p pw_MilConf, MemBlockHandle pw_Area, unsigned int j_Size) { MemBlockHandle pw_Tp; if(!pw_MilConf)return(NULL); /* create a new memory block handle */ pw_Tp=(MemBlockHandle)MilMalloc(pw_MilConf,sizeof(MemBlockType)); /* set the size of this new block to the requested size*/ pw_Tp->j_Size = j_Size; /* set the absolute address (address of start of tp block) equal to the */ /* absolute address of the area */ pw_Tp->m_AbsAddr = pw_Area->m_AbsAddr; /* this block is now in use */ pw_Tp->d_Status = USED; /* area is now (size) smaller, and the offset is set to after the end of */ /* the new block. the ptr address is also changed to the new value */ pw_Area->j_Size-=j_Size; pw_Area->m_AbsAddr+=j_Size; /* check if we used all the memory of area. if so, area is swapped out */ /* of the list and tp is swapped in. area is now junked */ if(pw_Area->j_Size==0) { SwapMemBlocks(pw_MilConf,pw_Area,pw_Tp); /* inserted in the Swap procedure MilFree(pw_MilConf,pw_Area);*/ /* otherwise with insert tp before area */ } else { MemBlockInsert(pw_MilConf,pw_Area,pw_Tp); } /* if area was the head, tp is now the head */ if(pw_Area == pw_MilConf->pw_AceMemory) pw_MilConf->pw_AceMemory = pw_Tp; /* pw_MilConf->pw_AceCurrent points to the next free memory block handle */ pw_MilConf->pw_AceCurrent= pw_Tp->pw_Next; return(pw_Tp); } /******************************************************************** * * MilAllocHandle - Allocates a memory block and returns a handle. * * Description * Allocates a memory block and returns a handle. * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - j_Size the size of memory to be allocated * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Handler to the block * * SEE ALSO: * * INTERNAL * */ MemBlockHandle MilAllocHandle( MilConf_p pw_MilConf, unsigned int j_Size ) { if(!pw_MilConf) return(NULL); return(MilAllocateOnBoard(pw_MilConf, MilFindSpace(pw_MilConf,j_Size,FALSE), j_Size)); } /******************************************************************** * * MilAllocHandleBoundary - Allocates a memory block with a word * boundary condition. * * Description * Allocates a memory block with a word * boundary condition and returns a handle * * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - j_Size the minimum size of the block * - j_Boundary Boundary of the block * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Handler to the block * * SEE ALSO: * * INTERNAL * */ MemBlockHandle MilAllocHandleBoundary( MilConf_p pw_MilConf, unsigned int j_Size, unsigned int j_Boundary ) { MemBlockHandle pw_Blk, pw_Tp, pw_Lf; unsigned int j_en,j_b,j_c; if(!pw_MilConf)return(NULL); /* find space on the boundary condition */ pw_Blk= MilFindSpace(pw_MilConf,j_Size, j_Boundary); if(pw_Blk) { /* create a new memory block handle */ pw_Tp=(MemBlockHandle)MilMalloc(pw_MilConf, sizeof(MemBlockType)); /* variables for boundary condition */ /* calculate c=start of block on boundary b=end of block on boundary */ j_en=pw_Blk->m_AbsAddr + pw_Blk->j_Size; //j_b=(j_en/j_Boundary)*j_Boundary; j_b = j_en - IFSI_MOD(j_en, j_Boundary); j_c = j_b - j_Boundary; /* set the size of this new block to the requested size * set the starting address to the calculated boundary address * and mark block as used. Initially (tp) is set to reside inside * of (blk). if (lf) is needed ie. space is left after the absolute * (tp) space this block is created and linked. (blk) is then adjusted * to the size between c and the absolute address of (blk). If this * this size is 0 (ie. tp and lf take up all the room), (blk) is * discarded. * * -> * | * | * |====c <- * | | * blk| |tp * | | * | | * |====b <- * | | * | |lf * | <- * -> */ pw_Tp->j_Size=j_Size; pw_Tp->m_AbsAddr=j_c; pw_Tp->d_Status= USED; /* check to see if there is an area left at the end of the block * if there is we create (lf) block and insert it after (tp) */ if((pw_Blk->m_AbsAddr+pw_Blk->j_Size)>(unsigned int)j_b) { pw_Lf=(MemBlockHandle)MilMalloc(pw_MilConf, sizeof(MemBlockType)); pw_Lf->m_AbsAddr= j_b; pw_Lf->j_Size=((pw_Blk->m_AbsAddr + pw_Blk->j_Size)- j_b); pw_Lf->d_Status = UNUSED; if(pw_Blk->pw_Next) pw_Blk->pw_Next->pw_Prev= pw_Lf; pw_Lf->pw_Next = pw_Blk->pw_Next; pw_Lf->pw_Prev = pw_Tp; pw_Tp->pw_Next = pw_Lf; } /* otherwise (lf) is not inserted and tp is linked to (blk)'s next * neighbor */ else { pw_Tp->pw_Next= pw_Blk->pw_Next; if(pw_Blk->pw_Next) pw_Blk->pw_Next->pw_Prev= pw_Tp; } /* the size of (blk) is now adjusted. This block is removed if * the size become 0 after the adjustment */ pw_Blk->j_Size = (j_c - pw_Blk->m_AbsAddr); pw_Blk->pw_Next= pw_Tp; pw_Tp->pw_Prev = pw_Blk; if(pw_Blk->j_Size==0) { MemBlockRemove(pw_MilConf,pw_Blk); /* MilFree(pw_MilConf, pw_Blk); */ } return(pw_Tp); } /* could not find space */ return(NULL); } /******************************************************************** * * MilReleaseHandle - Frees the memory used by a block. * * Description * Frees the memory used by a block. * * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_Tp Handle to the Block to free * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * * INTERNAL * */ MilError_t MilReleaseHandle( MilConf_p pw_MilConf, MemBlockHandle pw_Tp ) { MemBlockHandle pw_Tq; if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); if(pw_Tp->d_Status != USED) return(FALSE); if((pw_Tp->pw_Prev)&&(pw_Tp->pw_Prev->d_Status == UNUSED)) { if((pw_Tp->pw_Next)&&(pw_Tp->pw_Next->d_Status == UNUSED)) { pw_Tp->pw_Prev->j_Size += (pw_Tp->pw_Next->j_Size + pw_Tp->j_Size); pw_MilConf->pw_AceCurrent = pw_Tp->pw_Prev; pw_Tq = pw_Tp->pw_Next; MemBlockRemove(pw_MilConf,pw_Tp); MemBlockRemove(pw_MilConf,pw_Tq); /* MilFree(pw_MilConf, pw_Tp); MilFree(pw_MilConf, pw_Tq); */ } else { pw_Tp->pw_Prev->j_Size += pw_Tp->j_Size; pw_MilConf->pw_AceCurrent = pw_Tp->pw_Prev; MemBlockRemove(pw_MilConf,pw_Tp); /* MilFree(pw_MilConf,pw_Tp); */ } } else { if((pw_Tp->pw_Next)&&(pw_Tp->pw_Next->d_Status==UNUSED)) { pw_Tq = pw_Tp->pw_Next; pw_Tq->m_AbsAddr -= pw_Tp->j_Size; pw_Tq->j_Size += pw_Tp->j_Size; pw_MilConf->pw_AceCurrent = pw_Tq; MemBlockRemove(pw_MilConf, pw_Tp); /* MilFree(pw_MilConf, pw_Tp); */ } else pw_Tp->d_Status=UNUSED; } return(MIL_SUCCESS); } /******************************************************************** * * MilFindSpace - Creates a space of a specified size by moving messages * * Description * Creates a space of a specified size by moving messages * that are not actively being used off the board * * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - j-Size Size of space to be allocated * - j_Boundary FALSE if no boundary condition, otherwise the * boundary condition value. * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: handle to the unused space, null is returned if * a block could not be found * * SEE ALSO: * * INTERNAL * */ MemBlockHandle MilFindSpace( MilConf_p pw_MilConf, unsigned int j_Size, unsigned int j_Boundary ) { /* used to move through list */ MemBlockHandle pw_Mem; /* keeps track of starting node */ MemBlockHandle pw_Start; /* variables for boundary condition check */ int i_Start, i_End, i_b, i_c; if(!pw_MilConf) return(NULL); /* if at tail of list then go to the head */ if((pw_MilConf->pw_AceCurrent == NULL)||(pw_MilConf->pw_AceCurrent->d_Status == OFFBOARD)) pw_MilConf->pw_AceCurrent = pw_MilConf->pw_AceMemory; /* AceCurrent is a pointer used to determine where */ /* we start a search at the end of the search, AceCurrent */ /* is updated to point to the next handle after the handle */ /* which was found. */ pw_Mem = pw_MilConf->pw_AceCurrent; /* keep track of start to check for search completion */ pw_Start = pw_MilConf->pw_AceCurrent; do { /* check if the current block unused */ if(pw_Mem->d_Status == UNUSED) { /* check if the block is big enough if it is, we determine * if there is a boundary condition, if not then the possible * starting and ending address of the boundary block is * calculated. If this calculated block will fit in this unused * block we have found a block that meets all the criteria. */ if(pw_Mem->j_Size >= j_Size) { if(!j_Boundary) return(pw_Mem); else { i_Start = pw_Mem->m_AbsAddr; i_End= pw_Mem->m_AbsAddr + pw_Mem->j_Size; //i_b=(i_End/j_Boundary)*j_Boundary; i_b = i_End - IFSI_MOD(i_End, j_Boundary); i_c= i_b - j_Boundary; if(i_c>=i_Start) return(pw_Mem); } } } /* go to the next block */ pw_Mem= pw_Mem->pw_Next; /* if at tail of list then goto the head */ if(pw_Mem == NULL) pw_Mem= pw_MilConf->pw_AceMemory; /* check to see if we are where we started from */ } while(pw_Mem!= pw_Start); /* no free blocks found so return null */ return(NULL); } /******************************************************************** * * MilReadBlk - Reads a memory block into a buffer * * Description * Reads a memory block into a buffer * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_BlockHdl a handle to the block of memory to be read * - pj_DataPtr Pointer to the data buffer * - j-Size Size of space to be allocated * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * * INTERNAL * */ MilError_t MilReadBlk( MilConf_p pw_MilConf, MemBlockHandle pw_BlockHdl, unsigned int *pj_DataPtr, unsigned int j_Size ) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); if(pw_BlockHdl) { if(j_Size> MilGetBlkSize(pw_MilConf, pw_BlockHdl)) return(MIL_ERROR_BUFFERTOOSMALL); else return(MilBlockRead(pw_MilConf, MilGetBlkAddress(pw_MilConf, pw_BlockHdl), pj_DataPtr, j_Size)); } else return(MIL_ERROR_BADBLOCK); } /******************************************************************** * * MilWriteBlk - Writes an array of data to a block of memory * * Description * Writes an array of data to a block of memory * * ARGUMENTS * Input Parameters * - pw_MilConf Mil1553 management structure * - pw_BlockHdl a handle to the block of memory to be read * - pj_DataPtr a pointer where the data is stored * - j-Size Size of space to be allocated * * Output Parameters * N/A * * Global Variables * N/A * * RETURNS: Error Condition * * SEE ALSO: * * INTERNAL * */ MilError_t MilWriteBlk(MilConf_p pw_MilConf, MemBlockHandle pw_BlockHdl, unsigned int *pj_DataPtr, unsigned int j_Size) { if(!pw_MilConf) return(MIL_ERROR_NOTCONFIGURED); if(pw_BlockHdl) { if(j_Size > MilGetBlkSize(pw_MilConf, pw_BlockHdl)) return(MIL_ERROR_BLOCKTOOSMALL); else return(MilBlockWrite( pw_MilConf, MilGetBlkAddress(pw_MilConf, pw_BlockHdl), pj_DataPtr, j_Size)); } else return(MIL_ERROR_BADBLOCK); }/* end procedure */ /* * END: ACEMEM.C (MEMORY MANAGMENT ROUTINES) */ // ---------------------------------------------------------------------------// /* modification history -------------------- $Log: Milmem.c,v $ Revision 1.10 2006/10/20 09:22:14 lorenzo 1553 library updated Revision 1.7 2006/06/07 11:44:56 scige Some More Comment by Scige John Liu IFSI Revision 1.6 2006/02/15 14:56:57 scige Abstract comment reformatted History log replaced or moved at end of file */