summaryrefslogtreecommitdiffstats
path: root/drivers/staging/epl/SharedBuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/epl/SharedBuff.c')
-rw-r--r--drivers/staging/epl/SharedBuff.c1762
1 files changed, 0 insertions, 1762 deletions
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
deleted file mode 100644
index 2b10c37..0000000
--- a/drivers/staging/epl/SharedBuff.c
+++ /dev/null
@@ -1,1762 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: Project independend shared buffer (linear + circular)
-
- Description: Implementation of platform independend part for the
- shared buffer
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- 2006/06/27 -rs: V 1.00 (initial version)
-
-****************************************************************************/
-
-#if defined(WIN32) || defined(_WIN32)
-
-#ifdef UNDER_RTSS
- // RTX header
-#include <windows.h>
-#include <process.h>
-#include <rtapi.h>
-
-#elif __BORLANDC__
- // borland C header
-#include <windows.h>
-#include <process.h>
-
-#elif WINCE
-#include <windows.h>
-
-#else
- // MSVC needs to include windows.h at first
- // the following defines ar necessary for function prototypes for waitable timers
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT 0x0400
-#include <windows.h>
-#include <process.h>
-#endif
-
-#endif
-
-#include "global.h"
-#include "SharedBuff.h"
-#include "ShbIpc.h"
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Constant definitions
-//---------------------------------------------------------------------------
-
-#define SBC_MAGIC_ID 0x53424323 // magic ID ("SBC#")
-#define SBL_MAGIC_ID 0x53424C23 // magic ID ("SBL#")
-
-//---------------------------------------------------------------------------
-// Local types
-//---------------------------------------------------------------------------
-
-// structure to administrate circular shared buffer head
-typedef struct {
- unsigned long m_ShbCirMagicID; // magic ID ("SBC#")
- unsigned long m_ulBufferTotalSize; // over-all size of complete buffer
- unsigned long m_ulBufferDataSize; // size of complete data area
- unsigned long m_ulWrIndex; // current write index (set bevore write)
- unsigned long m_ulRdIndex; // current read index (set after read)
- unsigned long m_ulNumOfWriteJobs; // number of currently (parallel running) write operations
- unsigned long m_ulDataInUse; // currently used buffer size (incl. uncompleted write operations)
- unsigned long m_ulDataApended; // buffer size of complete new written but not yet readable data (in case of m_ulNumOfWriteJobs>1)
- unsigned long m_ulBlocksApended; // number of complete new written but not yet readable data blocks (in case of m_ulNumOfWriteJobs>1)
- unsigned long m_ulDataReadable; // buffer size with readable (complete written) data
- unsigned long m_ulBlocksReadable; // number of readable (complete written) data blocks
- tShbCirSigHndlrNewData m_pfnSigHndlrNewData; // application handler to signal new data
- unsigned int m_fBufferLocked; // TRUE if buffer is locked (because of pending reset request)
- tShbCirSigHndlrReset m_pfnSigHndlrReset; // application handler to signal buffer reset is done
- unsigned char m_Data; // start of data area (the real data size is unknown at this time)
-
-} tShbCirBuff;
-
-// structure to administrate linear shared buffer head
-typedef struct {
- unsigned int m_ShbLinMagicID; // magic ID ("SBL#")
- unsigned long m_ulBufferTotalSize; // over-all size of complete buffer
- unsigned long m_ulBufferDataSize; // size of complete data area
- unsigned char m_Data; // start of data area (the real data size is unknown at this time)
-
-} tShbLinBuff;
-
-// type to save size of a single data block inside the circular shared buffer
-typedef struct {
- unsigned int m_uiFullBlockSize:28; // a single block must not exceed a length of 256MByte :-)
- unsigned int m_uiAlignFillBytes:4;
-
-} tShbCirBlockSize;
-
-#define SBC_BLOCK_ALIGNMENT 4 // alignment must *not* be lower than sizeof(tShbCirBlockSize)!
-#define SBC_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-#define SBL_BLOCK_ALIGNMENT 4
-#define SBL_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-//---------------------------------------------------------------------------
-// Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Get pointer to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbCirBuff *pShbCirBuff;
-
- pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
- ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID);
-
- return (pShbCirBuff);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbLinBuff *pShbLinBuff;
-
- pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
- ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID);
-
- return (pShbLinBuff);
-
-}
-
-// not inlined internal functions
-int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p);
-void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
- unsigned int fTimeOut_p);
-
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-// Initialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbInit(void)
-{
-
- tShbError ShbError;
-
- ShbError = ShbIpcInit();
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Deinitialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbExit(void)
-{
-
- tShbError ShbError;
-
- ShbError = ShbIpcExit();
-
- return (ShbError);
-
-}
-
-//-------------------------------------------------------------------------//
-// //
-// C i r c u l a r S h a r e d B u f f e r //
-// //
-//-------------------------------------------------------------------------//
-
-//---------------------------------------------------------------------------
-// Allocate Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p,
- const char *pszBufferID_p,
- tShbInstance * ppShbInstance_p,
- unsigned int *pfShbNewCreated_p)
-{
-
- tShbInstance pShbInstance;
- tShbCirBuff *pShbCirBuff;
- unsigned int fShbNewCreated;
- unsigned long ulBufferDataSize;
- unsigned long ulBufferTotalSize;
- tShbError ShbError;
-
- // check arguments
- if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- // calculate length of memory to allocate
- ulBufferDataSize =
- (ulBufferSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- ulBufferTotalSize = ulBufferDataSize + sizeof(tShbCirBuff);
-
- // allocate a new or open an existing shared buffer
- ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p,
- &pShbInstance, &fShbNewCreated);
- if (ShbError != kShbOk) {
- goto Exit;
- }
-
- if (pShbInstance == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- // get pointer to shared buffer
- pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance);
-
- // if the shared buffer was new created, than this process has
- // to initialize it, otherwise the buffer is already in use
- // and *must not* be reseted
- if (fShbNewCreated) {
-#ifndef NDEBUG
- {
- memset(pShbCirBuff, 0xCC, ulBufferTotalSize);
- }
-#endif
-
- pShbCirBuff->m_ShbCirMagicID = SBC_MAGIC_ID;
- pShbCirBuff->m_ulBufferTotalSize = ulBufferTotalSize;
- pShbCirBuff->m_ulBufferDataSize = ulBufferDataSize;
- pShbCirBuff->m_ulWrIndex = 0;
- pShbCirBuff->m_ulRdIndex = 0;
- pShbCirBuff->m_ulNumOfWriteJobs = 0;
- pShbCirBuff->m_ulDataInUse = 0;
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
- pShbCirBuff->m_ulDataReadable = 0;
- pShbCirBuff->m_ulBlocksReadable = 0;
- pShbCirBuff->m_pfnSigHndlrNewData = NULL;
- pShbCirBuff->m_fBufferLocked = FALSE;
- pShbCirBuff->m_pfnSigHndlrReset = NULL;
- } else {
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
- }
-
- Exit:
-
- *ppShbInstance_p = pShbInstance;
- *pfShbNewCreated_p = fShbNewCreated;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Release Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbOk;
- goto Exit;
- }
-
- ShbError = ShbIpcReleaseBuffer(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Reset Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
- unsigned long ulTimeOut_p,
- tShbCirSigHndlrReset pfnSignalHandlerReset_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulNumOfWriteJobs = 0; // d.k. GCC complains about uninitialized variable otherwise
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // start reset job by setting request request in buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- if (!pShbCirBuff->m_fBufferLocked) {
- ulNumOfWriteJobs = pShbCirBuff->m_ulNumOfWriteJobs;
-
- pShbCirBuff->m_fBufferLocked = TRUE;
- pShbCirBuff->m_pfnSigHndlrReset =
- pfnSignalHandlerReset_p;
- } else {
- ShbError = kShbAlreadyReseting;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (ShbError != kShbOk) {
- goto Exit;
- }
-
- // if there is currently no running write operation then reset buffer
- // immediately, otherwise wait until the last write job is ready by
- // starting a signal process
- if (ulNumOfWriteJobs == 0) {
- // there is currently no running write operation
- // -> reset buffer immediately
- ShbCirSignalHandlerReset(pShbInstance_p, FALSE);
- ShbError = kShbOk;
- } else {
- // there is currently at least one running write operation
- // -> starting signal process to wait until the last write job is ready
- ShbError =
- ShbIpcStartSignalingJobReady(pShbInstance_p, ulTimeOut_p,
- ShbCirSignalHandlerReset);
- }
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Write data block to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned int uiFullBlockSize;
- unsigned int uiAlignFillBytes;
- unsigned char *pShbCirDataPtr;
- unsigned char *pScrDataPtr;
- unsigned long ulDataSize;
- unsigned long ulChunkSize;
- unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise
- unsigned int fSignalNewData;
- unsigned int fSignalReset;
- tShbError ShbError;
- tShbError ShbError2;
- int fRes;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (ulDataBlockSize_p > SBC_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pScrDataPtr = (unsigned char *)pSrcDataBlock_p;
- fSignalNewData = FALSE;
- fSignalReset = FALSE;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // calculate data block size in circular buffer
- ulDataSize =
- (ulDataBlockSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header
- uiAlignFillBytes = ulDataSize - ulDataBlockSize_p;
-
- ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
- ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
- // reserve the needed memory for the write operation to do now
- // and make necessary adjustments in the circular buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- // check if there is sufficient memory available to store
- // the new data
- fRes =
- uiFullBlockSize <=
- (pShbCirBuff->m_ulBufferDataSize -
- pShbCirBuff->m_ulDataInUse);
- if (fRes) {
- // set write pointer for the write operation to do now
- // to the current write pointer of the circular buffer
- ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
- // reserve the needed memory for the write operation to do now
- pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
- // set new write pointer behind the reserved memory
- // for the write operation to do now
- pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
- pShbCirBuff->m_ulWrIndex %=
- pShbCirBuff->m_ulBufferDataSize;
-
- // increment number of currently (parallel running)
- // write operations
- pShbCirBuff->m_ulNumOfWriteJobs++;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (!fRes) {
- ShbError = kShbBufferFull;
- goto Exit;
- }
-
- // copy the data to the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- // write real size of current block (incl. alignment fill bytes)
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
- ulWrIndex += sizeof(tShbCirBlockSize);
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- if (ulWrIndex + ulDataBlockSize_p <= pShbCirBuff->m_ulBufferDataSize) {
- // linear write operation
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
- ulDataBlockSize_p);
- } else {
- // wrap-around write operation
- ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulChunkSize);
- memcpy(pShbCirDataPtr, pScrDataPtr + ulChunkSize,
- ulDataBlockSize_p - ulChunkSize);
- }
-
- // adjust header information for circular buffer with properties
- // of the wiritten data block
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataApended += uiFullBlockSize;
- pShbCirBuff->m_ulBlocksApended++;
-
- // decrement number of currently (parallel running) write operations
- if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
- // if there is no other write process running then
- // set new size of readable (complete written) data and
- // adjust number of readable blocks
- pShbCirBuff->m_ulDataReadable +=
- pShbCirBuff->m_ulDataApended;
- pShbCirBuff->m_ulBlocksReadable +=
- pShbCirBuff->m_ulBlocksApended;
-
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
-
- fSignalNewData = TRUE;
- fSignalReset = pShbCirBuff->m_fBufferLocked;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // signal new data event to a potentially reading application
- if (fSignalNewData) {
- ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
- // signal that the last write job has been finished to allow
- // a waiting application to reset the buffer now
- if (fSignalReset) {
- ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Allocate block within the Circular Shared Buffer for chunk writing
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- unsigned long ulDataBufferSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned int uiFullBlockSize;
- unsigned int uiAlignFillBytes;
- unsigned char *pShbCirDataPtr;
- unsigned long ulDataSize;
- unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise
- tShbError ShbError;
- int fRes;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if (ulDataBufferSize_p == 0) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if (ulDataBufferSize_p > SBC_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // calculate data block size in circular buffer
- ulDataSize =
- (ulDataBufferSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header
- uiAlignFillBytes = ulDataSize - ulDataBufferSize_p;
-
- ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
- ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
- // reserve the needed memory for the write operation to do now
- // and make necessary adjustments in the circular buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- // check if there is sufficient memory available to store
- // the new data
- fRes =
- (uiFullBlockSize <=
- (pShbCirBuff->m_ulBufferDataSize -
- pShbCirBuff->m_ulDataInUse));
- if (fRes) {
- // set write pointer for the write operation to do now
- // to the current write pointer of the circular buffer
- ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
- // reserve the needed memory for the write operation to do now
- pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
- // set new write pointer behind the reserved memory
- // for the write operation to do now
- pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
- pShbCirBuff->m_ulWrIndex %=
- pShbCirBuff->m_ulBufferDataSize;
-
- // increment number of currently (parallel running)
- // write operations
- pShbCirBuff->m_ulNumOfWriteJobs++;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (!fRes) {
- ShbError = kShbBufferFull;
- goto Exit;
- }
-
- // setup header information for allocated buffer
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- // write real size of current block (incl. alignment fill bytes)
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
- ulWrIndex += sizeof(tShbCirBlockSize);
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- // setup chunk descriptor
- pShbCirChunk_p->m_uiFullBlockSize = uiFullBlockSize;
- pShbCirChunk_p->m_ulAvailableSize = ulDataBufferSize_p;
- pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
- pShbCirChunk_p->m_fBufferCompleted = FALSE;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Write data chunk into an allocated buffer of the Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
- tShbCirChunk *pShbCirChunk_p,
- const void *pSrcDataChunk_p,
- unsigned long ulDataChunkSize_p,
- unsigned int *pfBufferCompleted_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned char *pShbCirDataPtr;
- unsigned char *pScrDataPtr;
- unsigned long ulSubChunkSize;
- unsigned long ulWrIndex;
- unsigned int fBufferCompleted;
- unsigned int fSignalNewData;
- unsigned int fSignalReset;
- tShbError ShbError;
- tShbError ShbError2;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)
- || (pfBufferCompleted_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pSrcDataChunk_p == NULL) || (ulDataChunkSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (pShbCirChunk_p->m_fBufferCompleted) {
- ShbError = kShbBufferAlreadyCompleted;
- goto Exit;
- }
-
- if (ulDataChunkSize_p > pShbCirChunk_p->m_ulAvailableSize) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pScrDataPtr = (unsigned char *)pSrcDataChunk_p;
- fSignalNewData = FALSE;
- fSignalReset = FALSE;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- ulWrIndex = pShbCirChunk_p->m_ulWrIndex;
-
- // copy the data to the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- if (ulWrIndex + ulDataChunkSize_p <= pShbCirBuff->m_ulBufferDataSize) {
- // linear write operation
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
- ulDataChunkSize_p);
- } else {
- // wrap-around write operation
- ulSubChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulSubChunkSize);
- memcpy(pShbCirDataPtr, pScrDataPtr + ulSubChunkSize,
- ulDataChunkSize_p - ulSubChunkSize);
- }
-
- // adjust chunk descriptor
- ulWrIndex += ulDataChunkSize_p;
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- pShbCirChunk_p->m_ulAvailableSize -= ulDataChunkSize_p;
- pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
-
- fBufferCompleted = (pShbCirChunk_p->m_ulAvailableSize == 0);
- pShbCirChunk_p->m_fBufferCompleted = fBufferCompleted;
-
- // if the complete allocated buffer is filled with data then
- // adjust header information for circular buffer with properties
- // of the wiritten data block
- if (fBufferCompleted) {
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataApended +=
- pShbCirChunk_p->m_uiFullBlockSize;
- pShbCirBuff->m_ulBlocksApended++;
-
- // decrement number of currently (parallel running) write operations
- if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
- // if there is no other write process running then
- // set new size of readable (complete written) data and
- // adjust number of readable blocks
- pShbCirBuff->m_ulDataReadable +=
- pShbCirBuff->m_ulDataApended;
- pShbCirBuff->m_ulBlocksReadable +=
- pShbCirBuff->m_ulBlocksApended;
-
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
-
- fSignalNewData = TRUE;
- fSignalReset = pShbCirBuff->m_fBufferLocked;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
- }
-
- // signal new data event to a potentially reading application
- if (fSignalNewData) {
- ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
- // signal that the last write job has been finished to allow
- // a waiting application to reset the buffer now
- if (fSignalReset) {
- ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
-
- *pfBufferCompleted_p = fBufferCompleted;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Read data block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulRdBuffSize_p,
- unsigned long *pulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned long ulDataReadable;
- unsigned char *pShbCirDataPtr;
- unsigned char *pDstDataPtr;
- unsigned long ulDataSize = 0; // d.k. GCC complains about uninitialized variable otherwise
- unsigned long ulChunkSize;
- unsigned long ulRdIndex;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- if ((pDstDataBlock_p == NULL) || (ulRdBuffSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- ShbError = kShbOk;
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pDstDataPtr = (unsigned char *)pDstDataBlock_p;
- ulDataSize = 0;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // get total number of readable bytes for the whole circular buffer
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulDataReadable = pShbCirBuff->m_ulDataReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // if there are readable data available, then there must be at least
- // one complete readable data block
- if (ulDataReadable > 0) {
- // get pointer to start of data area and current read index
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
- ulRdIndex = pShbCirBuff->m_ulRdIndex;
-
- // get real size of current block (incl. alignment fill bytes)
- ShbCirBlockSize =
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex);
- ulRdIndex += sizeof(tShbCirBlockSize);
- ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- // get size of user data inside the current block
- ulDataSize =
- ShbCirBlockSize.m_uiFullBlockSize -
- ShbCirBlockSize.m_uiAlignFillBytes;
- ulDataSize -= sizeof(tShbCirBlockSize);
- }
-
- // ulDataSize = MIN(ulDataSize, ulRdBuffSize_p);
- if (ulDataSize > ulRdBuffSize_p) {
- ulDataSize = ulRdBuffSize_p;
- ShbError = kShbDataTruncated;
- }
-
- if (ulDataSize == 0) {
- // nothing to do here
- ShbError = kShbNoReadableData;
- goto Exit;
- }
-
- // copy the data from the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
- // linear read operation
- memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulDataSize);
- } else {
- // wrap-around read operation
- ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
- memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulChunkSize);
- memcpy(pDstDataPtr + ulChunkSize, pShbCirDataPtr,
- ulDataSize - ulChunkSize);
- }
-
-#ifndef NDEBUG
- {
- tShbCirBlockSize ClrShbCirBlockSize;
-
- if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
- // linear buffer
- memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulDataSize);
- } else {
- // wrap-around read operation
- ulChunkSize =
- pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
- memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulChunkSize);
- memset(pShbCirDataPtr, 0xDD, ulDataSize - ulChunkSize);
- }
-
- ClrShbCirBlockSize.m_uiFullBlockSize = /*(unsigned int) */ -1; // -1 = xFFFFFFF
- ClrShbCirBlockSize.m_uiAlignFillBytes = /*(unsigned int) */ -1; // -1 = Fxxxxxxx
- *(tShbCirBlockSize *) (pShbCirDataPtr +
- pShbCirBuff->m_ulRdIndex) =
- ClrShbCirBlockSize;
- }
-#endif // #ifndef NDEBUG
-
- // set new size of readable data, data in use, new read index
- // and adjust number of readable blocks
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataInUse -= ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulDataReadable -=
- ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulBlocksReadable--;
-
- //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- if ((pShbCirBuff->m_ulDataInUse == 0)
- && (pShbCirBuff->m_ulDataReadable == 0)) {
- ASSERT(pShbCirBuff->m_ulBlocksReadable == 0);
-
- pShbCirBuff->m_ulWrIndex = 0;
- pShbCirBuff->m_ulRdIndex = 0;
- } else
- //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- {
- pShbCirBuff->m_ulRdIndex +=
- ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulRdIndex %=
- pShbCirBuff->m_ulBufferDataSize;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- *pulDataBlockSize_p = ulDataSize;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Get data size of next readable block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
- unsigned long *pulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulDataReadable;
- unsigned char *pShbCirDataPtr;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned long ulDataSize;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ulDataSize = 0;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // get total number of readable bytes for the whole circular buffer
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulDataReadable = pShbCirBuff->m_ulDataReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // if there are readable data available, then there must be at least
- // one complete readable data block
- if (ulDataReadable > 0) {
- pShbCirDataPtr =
- &pShbCirBuff->m_Data + pShbCirBuff->m_ulRdIndex;
-
- // get real size of current block (incl. alignment fill bytes)
- ShbCirBlockSize = *(tShbCirBlockSize *) pShbCirDataPtr;
-
- // get size of user data inside the current block
- ulDataSize =
- ShbCirBlockSize.m_uiFullBlockSize -
- ShbCirBlockSize.m_uiAlignFillBytes;
- ulDataSize -= sizeof(tShbCirBlockSize);
- }
-
- Exit:
-
- *pulDataBlockSize_p = ulDataSize;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Get number of readable blocks from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
- unsigned long *pulDataBlockCount_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulBlockCount;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ulBlockCount = 0;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulBlockCount = pShbCirBuff->m_ulBlocksReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- *pulDataBlockCount_p = ulBlockCount;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Set application handler to signal new data for Circular Shared Buffer
-// d.k.: new parameter priority as enum
-//---------------------------------------------------------------------------
-
-tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
- tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
- tShbPriority ShbPriority_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- if (pfnSignalHandlerNewData_p != NULL) {
- // set a new signal handler
- if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
- ShbError = kShbAlreadySignaling;
- goto Exit;
- }
-
- pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
- ShbError =
- ShbIpcStartSignalingNewData(pShbInstance_p,
- ShbCirSignalHandlerNewData,
- ShbPriority_p);
- } else {
- // remove existing signal handler
- ShbError = ShbIpcStopSignalingNewData(pShbInstance_p);
- if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
- pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, 0);
- }
- pShbCirBuff->m_pfnSigHndlrNewData = NULL;
- }
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// DEBUG: Trace Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- char szMagigID[sizeof(SBC_MAGIC_ID) + 1];
- tShbCirBlockSize ShbCirBlockSize;
- unsigned long ulDataReadable;
- unsigned char *pShbCirDataPtr;
- unsigned long ulBlockIndex;
- unsigned int nBlockCount;
- unsigned long ulDataSize;
- unsigned long ulChunkSize;
- unsigned long ulRdIndex;
- tShbError ShbError;
-
- TRACE0("\n\n##### Circular Shared Buffer #####\n");
-
- // check arguments
- if (pShbInstance_p == NULL) {
- TRACE1("\nERROR: invalid buffer address (0x%08lX)\n",
- (unsigned long)pShbInstance_p);
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- *(unsigned long *)&szMagigID[0] = pShbCirBuff->m_ShbCirMagicID;
- szMagigID[sizeof(SBC_MAGIC_ID)] = '\0';
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- TRACE1("\nBuffer Address: 0x%08lX\n",
- (unsigned long)pShbCirBuff);
-
- TRACE0("\nHeader Info:");
- TRACE2("\nMagigID: '%s' (%08lX)", szMagigID,
- pShbCirBuff->m_ShbCirMagicID);
- TRACE1("\nBufferTotalSize: %4lu [Bytes]",
- pShbCirBuff->m_ulBufferTotalSize);
- TRACE1("\nBufferDataSize: %4lu [Bytes]",
- pShbCirBuff->m_ulBufferDataSize);
- TRACE1("\nWrIndex: %4lu", pShbCirBuff->m_ulWrIndex);
- TRACE1("\nRdIndex: %4lu", pShbCirBuff->m_ulRdIndex);
- TRACE1("\nNumOfWriteJobs: %4lu",
- pShbCirBuff->m_ulNumOfWriteJobs);
- TRACE1("\nDataInUse: %4lu [Bytes]",
- pShbCirBuff->m_ulDataInUse);
- TRACE1("\nDataApended: %4lu [Bytes]",
- pShbCirBuff->m_ulDataApended);
- TRACE1("\nBlocksApended: %4lu",
- pShbCirBuff->m_ulBlocksApended);
- TRACE1("\nDataReadable: %4lu [Bytes]",
- pShbCirBuff->m_ulDataReadable);
- TRACE1("\nBlocksReadable: %4lu",
- pShbCirBuff->m_ulBlocksReadable);
- TRACE1("\nSigHndlrNewData: %08lX",
- (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData);
- TRACE1("\nBufferLocked: %d", pShbCirBuff->m_fBufferLocked);
- TRACE1("\nSigHndlrReset: %08lX",
- (unsigned long)pShbCirBuff->m_pfnSigHndlrReset);
-
- ShbTraceDump(&pShbCirBuff->m_Data,
- pShbCirBuff->m_ulBufferDataSize, 0x00000000L,
- "\nData Area:");
-
- ulDataReadable = pShbCirBuff->m_ulDataReadable;
- nBlockCount = 1;
- ulBlockIndex = pShbCirBuff->m_ulRdIndex;
-
- while (ulDataReadable > 0) {
- TRACE1("\n\n--- Block #%u ---", nBlockCount);
-
- // get pointer to start of data area and current read index
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
- ulRdIndex = ulBlockIndex;
-
- // get real size of current block (incl. alignment fill bytes)
- ShbCirBlockSize =
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex);
- ulRdIndex += sizeof(tShbCirBlockSize);
- ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- // get size of user data inside the current block
- ulDataSize =
- ShbCirBlockSize.m_uiFullBlockSize -
- ShbCirBlockSize.m_uiAlignFillBytes;
- ulDataSize -= sizeof(tShbCirBlockSize);
-
- TRACE1
- ("\nFull Data Size: %4u [Bytes] (incl. header and alignment fill bytes)",
- ShbCirBlockSize.m_uiFullBlockSize);
- TRACE1("\nUser Data Size: %4lu [Bytes]",
- ulDataSize);
- TRACE1("\nAlignment Fill Bytes: %4u [Bytes]",
- ShbCirBlockSize.m_uiAlignFillBytes);
-
- if (ulRdIndex + ulDataSize <=
- pShbCirBuff->m_ulBufferDataSize) {
- // linear data buffer
- ShbTraceDump(pShbCirDataPtr + ulRdIndex,
- ulDataSize, 0x00000000L, NULL);
- } else {
- // wrap-around data buffer
- ulChunkSize =
- pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
- ShbTraceDump(pShbCirDataPtr + ulRdIndex,
- ulChunkSize, 0x00000000L, NULL);
- ShbTraceDump(pShbCirDataPtr,
- ulDataSize - ulChunkSize,
- ulChunkSize, NULL);
- }
-
- nBlockCount++;
-
- ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize;
- ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize;
- }
-
- ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount - 1);
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-#endif
-
-//-------------------------------------------------------------------------//
-// //
-// L i n e a r S h a r e d B u f f e r //
-// //
-//-------------------------------------------------------------------------//
-
-//---------------------------------------------------------------------------
-// Allocate Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
- const char *pszBufferID_p,
- tShbInstance * ppShbInstance_p,
- unsigned int *pfShbNewCreated_p)
-{
-
- tShbInstance pShbInstance;
- tShbLinBuff *pShbLinBuff;
- unsigned int fShbNewCreated;
- unsigned long ulBufferDataSize;
- unsigned long ulBufferTotalSize;
- tShbError ShbError;
-
- // check arguments
- if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- // calculate length of memory to allocate
- ulBufferDataSize =
- (ulBufferSize_p +
- (SBL_BLOCK_ALIGNMENT - 1)) & ~(SBL_BLOCK_ALIGNMENT - 1);
- ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff);
-
- // allocate a new or open an existing shared buffer
- ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p,
- &pShbInstance, &fShbNewCreated);
- if (ShbError != kShbOk) {
- goto Exit;
- }
-
- if (pShbInstance == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- // get pointer to shared buffer
- pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance);
-
- // if the shared buffer was new created, than this process has
- // to initialize it, otherwise the buffer is already in use
- // and *must not* be reseted
- if (fShbNewCreated) {
-#ifndef NDEBUG
- {
- memset(pShbLinBuff, 0xCC, ulBufferTotalSize);
- }
-#endif
-
- pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID;
- pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize;
- pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize;
- } else {
- if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
- }
-
- Exit:
-
- *ppShbInstance_p = pShbInstance;
- *pfShbNewCreated_p = fShbNewCreated;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Release Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbOk;
- goto Exit;
- }
-
- ShbError = ShbIpcReleaseBuffer(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Write data block to Linear Shared Buffer
-//---------------------------------------------------------------------------
-tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
- unsigned long ulDstBufferOffs_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
-{
-
- tShbLinBuff *pShbLinBuff;
- unsigned char *pShbLinDataPtr;
- unsigned char *pScrDataPtr;
- unsigned long ulBufferDataSize;
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
- pScrDataPtr = (unsigned char *)pSrcDataBlock_p;
- ShbError = kShbOk;
-
- if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // check if offeset and size for the write operation matches with
- // the size of the shared buffer
- ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
- if ((ulDstBufferOffs_p > ulBufferDataSize) ||
- (ulDataBlockSize_p > ulBufferDataSize) ||
- ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) {
- ShbError = kShbDataOutsideBufferArea;
- goto Exit;
- }
-
- // copy the data to the linear buffer
- // (the copy process will be done inside of any critical/locked section)
- pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area
- pShbLinDataPtr += ulDstBufferOffs_p;
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- memcpy(pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p);
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Read data block from Linear Shared Buffer
-//---------------------------------------------------------------------------
-tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulSrcBufferOffs_p,
- unsigned long ulDataBlockSize_p)
-{
-
- tShbLinBuff *pShbLinBuff;
- unsigned char *pShbLinDataPtr;
- unsigned char *pDstDataPtr;
- unsigned long ulBufferDataSize;
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
- pDstDataPtr = (unsigned char *)pDstDataBlock_p;
- ShbError = kShbOk;
-
- if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // check if offeset and size for the read operation matches with
- // the size of the shared buffer
- ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
- if ((ulSrcBufferOffs_p > ulBufferDataSize) ||
- (ulDataBlockSize_p > ulBufferDataSize) ||
- ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) {
- ShbError = kShbDataOutsideBufferArea;
- goto Exit;
- }
-
- // copy the data to the linear buffer
- // (the copy process will be done inside of any critical/locked section)
- pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area
- pShbLinDataPtr += ulSrcBufferOffs_p;
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- memcpy(pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p);
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// DEBUG: Trace Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbLinBuff *pShbLinBuff;
- char szMagigID[sizeof(SBL_MAGIC_ID) + 1];
- tShbError ShbError;
-
- TRACE0("\n\n##### Linear Shared Buffer #####\n");
-
- // check arguments
- if (pShbInstance_p == NULL) {
- TRACE1("\nERROR: invalid buffer address (0x%08lX)\n",
- (unsigned long)pShbInstance_p);
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- *(unsigned int *)&szMagigID[0] = pShbLinBuff->m_ShbLinMagicID;
- szMagigID[sizeof(SBL_MAGIC_ID)] = '\0';
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- TRACE1("\nBuffer Address: 0x%08lX\n",
- (unsigned long)pShbLinBuff);
-
- TRACE0("\nHeader Info:");
- TRACE2("\nMagigID: '%s' (%08X)", szMagigID,
- pShbLinBuff->m_ShbLinMagicID);
- TRACE1("\nBufferTotalSize: %4lu [Bytes]",
- pShbLinBuff->m_ulBufferTotalSize);
- TRACE1("\nBufferDataSize: %4lu [Bytes]",
- pShbLinBuff->m_ulBufferDataSize);
-
- ShbTraceDump(&pShbLinBuff->m_Data,
- pShbLinBuff->m_ulBufferDataSize, 0x00000000L,
- "\nData Area:");
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-#endif
-
-//---------------------------------------------------------------------------
-// Dump buffer contents
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbTraceDump(const unsigned char *pabStartAddr_p,
- unsigned long ulDataSize_p,
- unsigned long ulAddrOffset_p, const char *pszInfoText_p)
-{
-
- const unsigned char *pabBuffData;
- unsigned long ulBuffSize;
- unsigned char bData;
- int nRow;
- int nCol;
-
- // get pointer to buffer and length of buffer
- pabBuffData = pabStartAddr_p;
- ulBuffSize = ulDataSize_p;
-
- if (pszInfoText_p != NULL) {
- TRACE1("%s", pszInfoText_p);
- }
- // dump buffer contents
- for (nRow = 0;; nRow++) {
- TRACE1("\n%08lX: ",
- (unsigned long)(nRow * 0x10) + ulAddrOffset_p);
-
- for (nCol = 0; nCol < 16; nCol++) {
- if ((unsigned long)nCol < ulBuffSize) {
- TRACE1("%02X ",
- (unsigned int)*(pabBuffData + nCol));
- } else {
- TRACE0(" ");
- }
- }
-
- TRACE0(" ");
-
- for (nCol = 0; nCol < 16; nCol++) {
- bData = *pabBuffData++;
- if ((unsigned long)nCol < ulBuffSize) {
- if ((bData >= 0x20) && (bData < 0x7F)) {
- TRACE1("%c", bData);
- } else {
- TRACE0(".");
- }
- } else {
- TRACE0(" ");
- }
- }
-
- if (ulBuffSize > 16) {
- ulBuffSize -= 16;
- } else {
- break;
- }
- }
-
- return (kShbOk);
-
-}
-#endif // #ifndef NDEBUG
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// Handler to signal new data event for Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulDataSize;
- unsigned long ulBlockCount;
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- return FALSE;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- return FALSE;
- }
-
- // call application handler
- if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
-/* do
- {*/
- ShbError = ShbCirGetReadDataSize(pShbInstance_p, &ulDataSize);
- if ((ulDataSize > 0) && (ShbError == kShbOk)) {
- pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p,
- ulDataSize);
- }
-
- ShbError =
- ShbCirGetReadBlockCount(pShbInstance_p, &ulBlockCount);
-/* }
- while ((ulBlockCount > 0) && (ShbError == kShbOk));*/
- }
- // Return TRUE if there are pending blocks.
- // In that case ShbIpc tries to call this function again immediately if there
- // is no other filled shared buffer with higher priority.
- return ((ulBlockCount > 0) && (ShbError == kShbOk));
-
-}
-
-//---------------------------------------------------------------------------
-// Handler to reset Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
- unsigned int fTimeOut_p)
-{
-
- tShbCirBuff *pShbCirBuff;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- return;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- return;
- }
-
- // reset buffer header
- if (!fTimeOut_p) {
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulWrIndex = 0;
- pShbCirBuff->m_ulRdIndex = 0;
- pShbCirBuff->m_ulNumOfWriteJobs = 0;
- pShbCirBuff->m_ulDataInUse = 0;
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
- pShbCirBuff->m_ulDataReadable = 0;
- pShbCirBuff->m_ulBlocksReadable = 0;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-#ifndef NDEBUG
- {
- memset(&pShbCirBuff->m_Data, 0xCC,
- pShbCirBuff->m_ulBufferDataSize);
- }
-#endif
- }
-
- // call application handler
- if (pShbCirBuff->m_pfnSigHndlrReset != NULL) {
- pShbCirBuff->m_pfnSigHndlrReset(pShbInstance_p, fTimeOut_p);
- }
-
- // unlock buffer
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_fBufferLocked = FALSE;
- pShbCirBuff->m_pfnSigHndlrReset = NULL;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- return;
-
-}
-
-// EOF
OpenPOWER on IntegriCloud