/****************************************************************************** ** Function: CFE_PSP_DeleteOSResources() ** ** Purpose: ** Clean up any OS resources when exiting from the cFE ** ** Arguments: ** (none) ** ** Return: ** (none) */ void CFE_PSP_DeleteOSResources (void) { uint32 i; int32 ReturnCode; for ( i = 0; i < OS_MAX_TASKS; i++) ReturnCode = OS_TaskDelete(i); printf("CFE_PSP: Deleted all Tasks in system\n"); for ( i = 0; i < OS_MAX_BIN_SEMAPHORES; i++ ) ReturnCode = OS_BinSemDelete(i); printf("CFE_PSP: Deleted all Binary Semaphores in system\n"); for ( i = 0; i < OS_MAX_COUNT_SEMAPHORES; i++ ) ReturnCode = OS_CountSemDelete(i); printf("CFE_PSP: Deleted all Counting Semaphores in system\n"); for ( i = 0; i < OS_MAX_MUTEXES; i++ ) ReturnCode = OS_MutSemDelete(i); printf("CFE_PSP: Deleted all Mutexes in system\n"); for ( i = 0; i < OS_MAX_QUEUES; i++ ) ReturnCode = OS_QueueDelete(i); printf("CFE_PSP: Deleted all Queues in system\n"); for ( i = 0; i < OS_MAX_TIMERS; i++ ) ReturnCode = OS_TimerDelete(i); printf("CFE_PSP: Deleted all Timers in system\n"); printf("CFE_PSP: NOTE: After quitting the cFE with a Control-C signal, it MUST be started next time\n"); printf(" with a Poweron Reset ( --reset PO ). \n"); }
/* ** CFE_ES_CreateCDSPool will initialize a pre-allocated memory pool. */ int32 CFE_ES_CreateCDSPool(uint32 CDSPoolSize, uint32 StartOffset) { char MutexName[10] = {"CDS_POOL"}; uint32 i = 0; uint32 Size = (CDSPoolSize & 0xfffffffc); /* create a semphore to protect this memory pool */ OS_MutSemCreate(&(CFE_ES_CDSMemPool.MutexId), MutexName, 0); /* Take the semaphore to ensure the mem pool is not being used during it's creation */ OS_MutSemTake(CFE_ES_CDSMemPool.MutexId); CFE_ES_CDSMemPool.Start = StartOffset; CFE_ES_CDSMemPool.End = StartOffset + Size; CFE_ES_CDSMemPool.Size = Size; CFE_ES_CDSMemPool.Current = StartOffset; CFE_ES_CDSMemPool.SizeIndex = -1; CFE_ES_CDSMemPool.CheckErrCntr = 0; CFE_ES_CDSMemPool.RequestCntr = 0; for (i=0; i<CFE_ES_CDS_NUM_BLOCK_SIZES; i++) { CFE_ES_CDSMemPool.SizeDesc[i].Top = 0; CFE_ES_CDSMemPool.SizeDesc[i].NumCreated = 0; CFE_ES_CDSMemPool.SizeDesc[i].MaxSize = CFE_ES_CDSMemPoolDefSize[i]; } if (CDSPoolSize < (CFE_ES_CDSMemPool.MinBlockSize + sizeof(CFE_ES_CDSBlockDesc_t))) { /* Must be able make Pool verification, block descriptor and at least one of the smallest blocks */ CFE_ES_WriteToSysLog("CFE_ES:CreateCDSPool-Pool size(%u) too small for one CDS Block, need >=%u\n", CDSPoolSize, (CFE_ES_CDSMemPool.MinBlockSize + sizeof(CFE_ES_CDSBlockDesc_t))); /* Give and delete semaphore since CDS Pool creation failed */ OS_MutSemGive(CFE_ES_CDSMemPool.MutexId); OS_MutSemDelete(CFE_ES_CDSMemPool.MutexId); return(CFE_ES_BAD_ARGUMENT); } OS_MutSemGive(CFE_ES_CDSMemPool.MutexId); return(CFE_SUCCESS); }
static void test_006_001_execute(void) { /* OS_MutSemCreate() is invoked with sem_id set to NULL, an error is expected.*/ test_set_step(1); { int32 err; err = OS_MutSemCreate(NULL, /* Error.*/ "failing semaphore", 0); test_assert(err == OS_INVALID_POINTER, "NULL not detected"); } /* OS_MutSemCreate() is invoked with sem_name set to NULL, an error is expected.*/ test_set_step(2); { int32 err; err = OS_MutSemCreate(&msid, NULL, /* Error.*/ 0); test_assert(err == OS_INVALID_POINTER, "NULL not detected"); } /* OS_MutSemCreate() is invoked with a very long timer name, an error is expected.*/ test_set_step(3); { #if 0 /* Semaphore name currently not implemented.*/ int32 err; err = OS_MutSemCreate(&msid, "very very long semaphore name", /* Error.*/ 0); test_assert(err == OS_ERR_NAME_TOO_LONG, "name limit not detected"); #endif } /* OS_MutSemDelete() is invoked with timer_id set to -1, an error is expected.*/ test_set_step(4); { int32 err; err = OS_MutSemDelete((uint32)-1); test_assert(err == OS_ERR_INVALID_ID, "wrong semaphore id not detected"); } /* OS_MutSemCreate() is invoked twice with duplicated name, an error is expected, then the queue is deleted using OS_MutSemDelete().*/ test_set_step(5); { int32 err; uint32 msid1; /*, msid2;*/ err = OS_MutSemCreate(&msid1, "my semaphore", 0); test_assert(err == OS_SUCCESS, "semaphore creation failed"); #if 0 /* Semaphore name currently not implemented.*/ err = OS_MutSemCreate(&msid2, "my semaphore", 0); test_assert(err == OS_ERR_NAME_TAKEN, "name conflict not detected"); #endif err = OS_MutSemDelete(msid1); test_assert(err == OS_SUCCESS, "semaphore deletion failed"); } }
int32 CFE_ES_PoolCreateEx(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 Size, uint32 NumBlockSizes, uint32 *BlockSizes, uint16 UseMutex ) { char MutexName[10]; uint32 i; uint32 j; uint32 k; uint32 *BlockSizeArrayPtr; uint32 BlockSizeArraySize; uint32 MinBlockSize; /* ** Local Variables */ Pool_t *PoolPtr = (Pool_t *)MemPtr; *HandlePtr = (uint32)MemPtr; /* Force the size given to be 32 bit aligned */ Size &= 0xFFFFFFFC; #ifdef CFE_ES_MEMPOOL_ALIGNED /* Determine if the memory pool address is 32-bit aligned */ if ((((uint32)MemPtr) & 0x00000003) != 0) { CFE_ES_WriteToSysLog("CFE_ES:poolCreate Pool Address(0x%08X) is not 32-bit aligned.\n", (uint32)MemPtr); return(CFE_ES_BAD_ARGUMENT); } #endif /* If too many sizes are specified, return an error */ if (NumBlockSizes > CFE_ES_MAX_MEMPOOL_BLOCK_SIZES) { CFE_ES_WriteToSysLog("CFE_ES:poolCreate Num Block Sizes (%d) greater than max (%d)\n", NumBlockSizes, CFE_ES_MAX_MEMPOOL_BLOCK_SIZES); return(CFE_ES_BAD_ARGUMENT); } if ((UseMutex != CFE_ES_USE_MUTEX) && (UseMutex != CFE_ES_NO_MUTEX)) { CFE_ES_WriteToSysLog("CFE_ES:poolCreate Invalid Mutex Usage Option (%d), must be %d or %d\n", UseMutex, CFE_ES_NO_MUTEX, CFE_ES_USE_MUTEX); return(CFE_ES_BAD_ARGUMENT); } if (UseMutex == CFE_ES_USE_MUTEX) { /* ** Construct a name for the Mutex from the address ** This is needed only because OS_MutSemCreate requires ** a unique name for each semaphore created. */ sprintf(MutexName, "%08X", (unsigned int)MemPtr); /* create a semphore to protect this memory pool */ OS_MutSemCreate(&(PoolPtr->MutexId), MutexName, 0); /* Take the semaphore to ensure the mem pool is not being used during its creation */ OS_MutSemTake(PoolPtr->MutexId); } PoolPtr->Start = (uint32 *)*HandlePtr; PoolPtr->End = (uint32)((uint8 *)PoolPtr->Start + Size); PoolPtr->Size = Size; PoolPtr->Current = (uint32 *)(MemPtr + sizeof(Pool_t)); PoolPtr->SizeDescPtr = NULL; PoolPtr->CheckErrCntr = 0; PoolPtr->RequestCntr = 0; PoolPtr->UseMutex = UseMutex; for (i=0; i<CFE_ES_MAX_MEMPOOL_BLOCK_SIZES; i++) { PoolPtr->SizeDesc[i].NumCreated = 0; PoolPtr->SizeDesc[i].NumFree = 0; PoolPtr->SizeDesc[i].MaxSize = 0; PoolPtr->SizeDesc[i].Top = NULL; } /* Use default block sizes if none or too many sizes are specified */ if ((NumBlockSizes == 0) || (BlockSizes == NULL)) { BlockSizeArrayPtr = &CFE_ES_MemPoolDefSize[0]; BlockSizeArraySize = CFE_ES_MAX_MEMPOOL_BLOCK_SIZES; } else { BlockSizeArrayPtr = BlockSizes; BlockSizeArraySize = NumBlockSizes; } /* Use specified block sizes but make sure they are ordered largest to smallest */ MinBlockSize = 0xffffffff; for (i=0; i<BlockSizeArraySize; i++) { if ((BlockSizeArrayPtr[i] < MinBlockSize) && (BlockSizeArrayPtr[i] != 0)) { MinBlockSize = BlockSizeArrayPtr[i]; } j = 0; while (j<CFE_ES_MAX_MEMPOOL_BLOCK_SIZES) { if (BlockSizeArrayPtr[i] > PoolPtr->SizeDesc[j].MaxSize) { /* Make space for new size */ for (k=i; k>j; k--) { PoolPtr->SizeDesc[k].MaxSize = PoolPtr->SizeDesc[k-1].MaxSize; } /* Insert the size in the correct location */ PoolPtr->SizeDesc[j].MaxSize = BlockSizeArrayPtr[i]; j = CFE_ES_MAX_MEMPOOL_BLOCK_SIZES; } else { j++; } } } if (Size <= (sizeof(Pool_t) + MinBlockSize + sizeof(BD_t) ) ) { /* must be able make Pool management structure and at least one of the smallest blocks */ CFE_ES_WriteToSysLog("CFE_ES:poolCreate Pool size(%d) too small for management structure, need >=(%d)\n", (int)Size, (int)(sizeof(Pool_t) + MinBlockSize + sizeof(BD_t)) ); if (UseMutex == CFE_ES_USE_MUTEX) { /* Mutex is no longer needed with error in initialization. Give it and delete it */ OS_MutSemGive(PoolPtr->MutexId); OS_MutSemDelete(PoolPtr->MutexId); } return(CFE_ES_BAD_ARGUMENT); } if (UseMutex == CFE_ES_USE_MUTEX) { OS_MutSemGive(PoolPtr->MutexId); } return(CFE_SUCCESS); }
/* ** Function: ** CFE_ES_RebuildCDSPool ** ** Purpose: ** */ int32 CFE_ES_RebuildCDSPool(uint32 CDSPoolSize, uint32 StartOffset) { char MutexName[10] = {"CDS_POOL"}; uint32 i = 0; uint32 Size = (CDSPoolSize & 0xfffffffc); int32 Status = OS_SUCCESS; uint32 Offset = StartOffset; int32 BinIndex = 0; /* create a semphore to protect this memory pool */ OS_MutSemCreate(&(CFE_ES_CDSMemPool.MutexId), MutexName, 0); /* Take the semaphore to ensure the mem pool is not being used during it's creation */ OS_MutSemTake(CFE_ES_CDSMemPool.MutexId); CFE_ES_CDSMemPool.Start = StartOffset; CFE_ES_CDSMemPool.End = StartOffset + Size; CFE_ES_CDSMemPool.Size = Size; CFE_ES_CDSMemPool.Current = 0; CFE_ES_CDSMemPool.SizeIndex = -1; CFE_ES_CDSMemPool.CheckErrCntr = 0; CFE_ES_CDSMemPool.RequestCntr = 0; for (i=0; i<CFE_ES_CDS_NUM_BLOCK_SIZES; i++) { CFE_ES_CDSMemPool.SizeDesc[i].Top = 0; CFE_ES_CDSMemPool.SizeDesc[i].NumCreated = 0; CFE_ES_CDSMemPool.SizeDesc[i].MaxSize = CFE_ES_CDSMemPoolDefSize[i]; } if (CDSPoolSize < (CFE_ES_CDSMemPool.MinBlockSize + sizeof(CFE_ES_CDSBlockDesc_t))) { /* Must be able make Pool verification, block descriptor and at least one of the smallest blocks */ CFE_ES_WriteToSysLog("CFE_ES:RebuildCDSPool-Pool size(%u) too small for one CDS Block, need >=%u\n", CDSPoolSize, (CFE_ES_CDSMemPool.MinBlockSize + sizeof(CFE_ES_CDSBlockDesc_t))); /* Give and delete semaphore since CDS Pool rebuild failed */ OS_MutSemGive(CFE_ES_CDSMemPool.MutexId); OS_MutSemDelete(CFE_ES_CDSMemPool.MutexId); return(CFE_ES_BAD_ARGUMENT); } /* Scan the CDS memory trying to find blocks that were created but are now free */ while ((Status == OS_SUCCESS) && (Offset < (CFE_ES_CDSMemPool.End - sizeof(CFE_ES_CDSBlockDesc_t))) && (CFE_ES_CDSMemPool.Current == 0)) { /* Read the block descriptor for the first block in the memory pool */ Status = CFE_PSP_ReadFromCDS(&CFE_ES_CDSBlockDesc, Offset, sizeof(CFE_ES_CDSBlockDesc_t)); if (Status == OS_SUCCESS) { /* First, determine if the block is being or has been used */ if (CFE_ES_CDSBlockDesc.CheckBits == CFE_ES_CDS_CHECK_PATTERN) { /* See if the block is currently being used */ if (CFE_ES_CDSBlockDesc.AllocatedFlag != CFE_ES_CDS_BLOCK_USED) { /* If the block is not currently being used, */ /* then add it to the appropriate linked list in the memory pool */ BinIndex = CFE_ES_CDSGetBinIndex(CFE_ES_CDSBlockDesc.SizeUsed); /* Sanity-check the block descriptor */ if (BinIndex >= 0) { CFE_ES_CDSBlockDesc.Next = CFE_ES_CDSMemPool.SizeDesc[BinIndex].Top; CFE_ES_CDSBlockDesc.AllocatedFlag = CFE_ES_CDS_BLOCK_UNUSED; CFE_ES_CDSMemPool.SizeDesc[BinIndex].Top = Offset; /* Store the new CDS Block Descriptor in the CDS */ Status = CFE_PSP_WriteToCDS(&CFE_ES_CDSBlockDesc, Offset, sizeof(CFE_ES_CDSBlockDesc_t)); if (Status != OS_SUCCESS) { CFE_ES_WriteToSysLog("CFE_ES:RebuildCDS-Err writing to CDS (Stat=0x%08x)\n", Status); Status = CFE_ES_CDS_ACCESS_ERROR; } } else { CFE_ES_CDSMemPool.CheckErrCntr++; CFE_ES_WriteToSysLog("CFE_ES:RebuildCDS-Invalid Block Descriptor \n"); Status = CFE_ES_CDS_ACCESS_ERROR; } } /* Skip to the next block of memory */ Offset = Offset + CFE_ES_CDSBlockDesc.ActualSize + sizeof(CFE_ES_CDSBlockDesc_t); } else { /* If the block has never been used, then we should save the offset as the current offset */ /* which in turn will finish the scan of the CDS memory */ CFE_ES_CDSMemPool.Current = Offset; } } else { CFE_ES_WriteToSysLog("CFE_ES:RebuildCDS-Err reading from CDS (Stat=0x%08x)\n", Status); Status = CFE_ES_CDS_ACCESS_ERROR; } } /* end while */ OS_MutSemGive(CFE_ES_CDSMemPool.MutexId); return Status; }