11#include "helpers/_countof.h"
27 const char* blockName = NULL;
66 const char* message =
"";
71 message =
"Operation succeeded";
75 message =
"Memory block is already open and cannot be opened again";
79 message =
"Memory block is closed and cannot be accessed";
83 message =
"The given name is not a recognized memory block name";
87 message =
"The handle argument does not correspond to a valid open memory block";
91 message =
"The given offset is out of bounds";
95 message =
"The block name pointer or return handle pointer argument is NULL";
99 message =
"Unrecognized error code.";
144 bool openOkay =
false;
149 if (blockName != NULL)
175 bool closeOkay =
true;
193 bool sizeOkay =
false;
197 if (sizeInBytes != NULL)
203 *sizeInBytes = chunkSize *
sizeof(uint32_t);
223bool Adapter_ReadMemory(
int dataHandle,
int byteOffset, uint8_t* buffer,
int maxBytes,
int* bytesRead)
225 bool readOkay =
false;
233 int chunkOffset = byteOffset / (
sizeof(uint32_t));
240 int byteOffsetInChunk = byteOffset % (
sizeof(uint32_t));
241 while (bufferIndex < maxBytes)
243 buffer[bufferIndex] = value & 0xff;
247 if (byteOffsetInChunk ==
sizeof(uint32_t))
254 byteOffsetInChunk = 0;
265 if (bytesRead != NULL)
267 *bytesRead = bufferIndex;
294bool Adapter_WriteMemory(
int dataHandle,
int byteOffset,
const uint8_t* buffer,
int maxBytes,
int* bytesWritten)
296 bool writeOkay =
false;
305 int chunkOffset = byteOffset /
sizeof(uint32_t);
307 int byteOffsetInChunk = byteOffset %
sizeof(uint32_t);
309 uint32_t byteMask = 0xff << (byteOffsetInChunk * 8);
310 if (byteOffsetInChunk != 0)
316 while (bufferIndex < maxBytes)
319 value |= ((uint32_t)buffer[bufferIndex]) << (byteOffsetInChunk * 8);
323 if (byteOffsetInChunk ==
sizeof(uint32_t))
329 byteOffsetInChunk = 0;
351 if (byteOffsetInChunk != 0)
358 if (bytesWritten != NULL)
360 *bytesWritten = bufferIndex;
371 _ReportDDRError(errorCode,
"Reading memory in preparation to writing memory");
403 hexdumpstring[0] =
'\0';
405 if (data != NULL && maxBytes > 0)
407 char indentation[10] = { 0 };
408 if (indent > (
int)
_countof(indentation) - 1)
410 indent = (int)(
_countof(indentation) - 1);
412 memcpy(indentation,
" ", indent);
413 indentation[indent] =
'\0';
414 uint32_t bytesPerRow = 32;
415 size_t stringBufferLength = 0;
416 size_t hexdumpBufferLength =
sizeof(
_hexdump);
417 char stringBuffer[192] = {0};
418 for (uint32_t row = 0; row < maxBytes; row += bytesPerRow)
420 snprintf(stringBuffer,
sizeof(stringBuffer),
"%s%04x --", indentation, row);
421 stringBufferLength = strlen(stringBuffer);
422 if (stringBufferLength >= hexdumpBufferLength)
425 hexdumpstring = NULL;
428 strncat(
_hexdump, stringBuffer, hexdumpBufferLength);
429 hexdumpBufferLength -= stringBufferLength;
431 for (uint32_t col = 0; col < bytesPerRow && (row + col) < maxBytes; col++)
433 char *separator = col > 0 ?
" " :
"";
434 uint32_t dataIndex = row + col;
435 snprintf(stringBuffer,
sizeof(stringBuffer),
"%s%02x", separator, (
int)data[dataIndex]);
436 stringBufferLength = strlen(stringBuffer);
437 if (stringBufferLength >= hexdumpBufferLength)
440 hexdumpstring = NULL;
443 strncat(
_hexdump, stringBuffer, hexdumpBufferLength);
444 hexdumpBufferLength -= stringBufferLength;
446 if (hexdumpBufferLength > 1)
452 return hexdumpstring;
const char * BLOCK_NAME_0
Name of the first block.
DDR_ErrorCode DDR_SetDataChunk(int dataHandle, int chunkOffset, uint32_t value)
Writes a single 32-bit value to the given offset in the memory block indicated by the specified handl...
const char * BLOCK_NAME_2
Name of the third block.
DDR_ErrorCode DDR_GetDataChunk(int dataHandle, int chunkOffset, uint32_t *value)
Read a single 32-bit value at the given offset in the memory block indicated by the specified handle.
DDR_ErrorCode DDR_OpenMemoryBlock(const char *blockName, int *dataHandle)
Open access to a memory block for exclusive use, given the name of the memory block.
DDR_ErrorCode DDR_CloseMemoryBlock(int dataHandle)
Close access to a previously opened memory block, thus releasing it for others to open.
const char * BLOCK_NAME_1
Name of the second block.
DDR_ErrorCode DDR_GetMemorySize(int dataHandle, int *memorySizeInChunks)
Retrieve the number of chunks in the memory block indicated by the handle to the successfully opened ...
Declaration of the "low-level" memory block read/write functions that are provided in a separate DLL ...
DDR_ErrorCode
Represents the possible errors that can be returned from the memory block access functions.
@ DDR_ErrorCode_Block_Not_Opened
Memory block is closed and cannot be accessed.
@ DDR_ErrorCode_Block_Already_Opened
Memory block is already open and cannot be opened again.
@ DDR_ErrorCode_Null_Argument
The block name pointer or return handle pointer argument is NULL.
@ DDR_ErrorCode_Invalid_Block_Name
The given name is not a recognized memory block name.
@ DDR_ErrorCode_Invalid_Handle
The handle argument does not correspond to a valid open memory block.
@ DDR_ErrorCode_Success
Operation succeeded.
@ DDR_ErrorCode_Invalid_Offset
The given offset is out of bounds.
@ DDR_MAX_OFFSET
All offsets must from 0 to 1 less than this value.
static void _ResetLastError(void)
Set the last error message to an empty string. Call this before doing any operation.
static char _lastError[128]
Holds last error message.
static const char * _GetBlockNameForBlockNumber(MemoryBlockNumber blockNumber)
Given a block number, retrieve the corresponding block name.
static const char * _GetErrorMessage(DDR_ErrorCode errorCode)
Convert the given error code to a string message.
static char _hexdump[512]
Collects hex dump as a single string. We do not expect more than about 424 bytes per hex dump.
static void _ReportDDRError(DDR_ErrorCode errorCode, const char *prompt)
Create a human-readable error message for the given error code, adding a prompt to provide some conte...
bool Adapter_CloseMemory(int dataHandle)
Closes a memory block from access.
bool Adapter_ReadMemory(int dataHandle, int byteOffset, uint8_t *buffer, int maxBytes, int *bytesRead)
Read a requested number of bytes from the memory block associated with the given handle.
bool Adapter_OpenMemory(MemoryBlockNumber blockNumber, int *dataHandle)
Open a memory block for access.
bool Adapter_WriteMemory(int dataHandle, int byteOffset, const uint8_t *buffer, int maxBytes, int *bytesWritten)
Write a requested number of bytes to the memory block associated with the given handle.
bool Adapter_GetMemorySize(int dataHandle, int *sizeInBytes)
Retrieve the number of bytes in the memory block associated with the specified data handle.
const char * Adapter_BufferToString(const uint8_t *data, uint32_t maxBytes, int indent)
Convert the specified data up to the specified number of bytes into a string by performing a "hex dum...
const char * Adapter_GetLastErrorMessage(void)
Retrieve a string describing the last error that occurred in the Adapter.
static void _ReportErrorMessage(const char *message, const char *prompt)
Format the given message and prompt into a single error message string.
Declaration of the Adapter functions used in the Adapter Pattern.
MemoryBlockNumber
Represents the memory blocks that can be accessed. Hides how memory blocks are actually identified.
@ Memory_Block_0
First block.
@ Memory_Block_1
Second block.
@ Memory_Block_2
Third block.