Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMake/binutils.ESP32.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,12 @@ macro(nf_setup_target_build)
${Graphics_Sources}
)

# include storage operation support, if feature is enabled
if(NF_FEATURE_HAS_ACCESSIBLE_STORAGE)
target_sources(${NANOCLR_PROJECT_NAME}.elf PUBLIC
${CMAKE_SOURCE_DIR}/src/HAL/nanoHAL_StorageOperation.cpp)
endif()

nf_add_platform_sources(${NANOCLR_PROJECT_NAME})

# include directories for nanoCLR
Expand Down
6 changes: 6 additions & 0 deletions CMake/binutils.common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ macro(nf_add_common_sources)
${Graphics_Sources}
)

# include storage operation support, if feature is enabled
if(NF_FEATURE_HAS_ACCESSIBLE_STORAGE)
target_sources(${NFACS_TARGET}.elf PUBLIC
${CMAKE_SOURCE_DIR}/src/HAL/nanoHAL_StorageOperation.cpp)
endif()

endif()

endmacro()
Expand Down
2 changes: 1 addition & 1 deletion src/CLR/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ bool CLR_DBG_Debugger::Monitor_StorageOperation(WP_Message *message)
Monitor_StorageOperation_Command *cmd = (Monitor_StorageOperation_Command *)message->m_payload;
Monitor_StorageOperation_Reply cmdReply;

cmdReply.ErrorCode = HAL_StorageOperation(cmd->Operation, cmd->NameLength, cmd->DataLength, cmd->Offset, cmd->Data);
cmdReply.ErrorCode = HAL_StorageOperation(cmd->Operation, cmd->DataLength, cmd->Offset, cmd->Data);

WP_ReplyToCommand(message, true, false, &cmdReply, sizeof(cmdReply));

Expand Down
18 changes: 2 additions & 16 deletions src/CLR/Debugger/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef DEBUGGER_H
#define DEBUGGER_H

#include <nanoHAL_StorageOperation.h>

// enum with CLR debugging commands
// backwards compatible with .NETMF
typedef enum CLR_DBG_Commands_Debugging
Expand Down Expand Up @@ -102,20 +104,4 @@ typedef enum AccessMemoryErrorCodes

} AccessMemoryErrorCodes;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// !!! KEEP IN SYNC WITH nanoFramework.Tools.Debugger.WireProtocol.StorageOperationErrorCode (in managed code) !!! //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef enum StorageOperationErrorCode
{
// no error
NoError = 0x0001,
// write error
WriteError = 0x0010,
// delete error
DeleteError = 0x0020,
// platform error
PlatformError = 0x0030,

} StorageOperationErrorCode;

#endif // DEBUGGER_H
1 change: 0 additions & 1 deletion src/CLR/Include/WireProtocol_MonitorCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ typedef struct __nfpack Monitor_UpdateConfiguration_Command
typedef struct Monitor_StorageOperation_Command
{
uint32_t Operation;
uint32_t NameLength;
uint32_t DataLength;
uint32_t Offset;
uint8_t Data[1];
Expand Down
23 changes: 17 additions & 6 deletions src/HAL/Include/nanoHAL_StorageOperation.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,28 @@

#include <nanoCLR_Headers.h>

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// !!! KEEP IN SYNC WITH nanoFramework.Tools.Debugger.WireProtocol.StorageOperationErrorCode (in managed code) !!! //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef enum StorageOperationErrorCode
{
// no error
NoError = 0x0001,
// write error
WriteError = 0x0010,
// delete error
DeleteError = 0x0020,
// platform error
PlatformError = 0x0030,

} StorageOperationErrorCode;

#ifdef __cplusplus
extern "C"
{
#endif

uint32_t HAL_StorageOperation(
uint8_t operation,
uint32_t nameLength,
uint32_t dataLength,
uint32_t offset,
uint8_t *data);
uint32_t HAL_StorageOperation(uint8_t operation, uint32_t dataLength, uint32_t offset, uint8_t *data);

#ifdef __cplusplus
}
Expand Down
151 changes: 151 additions & 0 deletions src/HAL/nanoHAL_StorageOperation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

#include <nanoHAL.h>
#include <nanoHAL_v2.h>
#include <nanoWeak.h>
#include <nanoCLR_Runtime.h>
#include <nanoCLR_Types.h>
#include <nanoPAL_FileSystem.h>
#include <nanoCLR_FileStream.h>
#include <nanoHAL_StorageOperation.h>
#include <WireProtocol_MonitorCommands.h>

#if CONFIG_NF_FEATURE_HAS_ACCESSIBLE_STORAGE

uint32_t HAL_StorageOperation(uint8_t operation, uint32_t dataLength, uint32_t offset, uint8_t *data)
{
(void)offset;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

char *storageName = NULL;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
char *rootName = NULL;
char *relativePath = NULL;
uint8_t *fileData = NULL;
uint32_t rootNameLength = 0;
FileSystemVolume *volume = NULL;
StorageOperationErrorCode errorCode = StorageOperationErrorCode::NoError;

// point to the storage name in the data buffer
storageName = (char *)data;

// split the path into root name and relative path
if (FAILED(CLR_RT_FileStream::SplitFilePath(storageName, rootName, rootNameLength, relativePath)))
{
errorCode = StorageOperationErrorCode::PlatformError;
goto done;
}

// find the volume for this path
volume = FileSystemVolumeList::FindVolume(rootName, rootNameLength);

if (volume == NULL)
{
errorCode = StorageOperationErrorCode::PlatformError;
goto done;
}

// point to the file data in the data buffer (after the storage name and null terminator)
fileData = (uint8_t *)(data + hal_strlen_s(storageName) + 1);

if (operation == StorageOperation_Monitor::StorageOperation_Write)
{
void *fileHandle = NULL;
char dirPath[FS_MAX_DIRECTORY_LENGTH];
char *lastSeparator;
int64_t position;
int bytesWritten = 0;

// extract parent directory from relative path and create it if needed
snprintf(dirPath, sizeof(dirPath), "%s", relativePath);

lastSeparator = strrchr(dirPath, '\\');
if (lastSeparator == NULL)
{
lastSeparator = strrchr(dirPath, '/');
}

if (lastSeparator != NULL && lastSeparator != dirPath)
{
*lastSeparator = '\0';

if (FAILED(volume->CreateDirectory(dirPath)))
{
errorCode = StorageOperationErrorCode::WriteError;
goto done;
}
}

// open the file (creates it, if it doesn't exist)
if (FAILED(volume->Open(relativePath, fileHandle)))
{
errorCode = StorageOperationErrorCode::WriteError;
goto done;
}

// truncate and seek to the beginning, for a full write
volume->SetLength(fileHandle, 0);
volume->Seek(fileHandle, 0, SEEKORIGIN_BEGIN, &position);

// write the data
volume->Write(fileHandle, fileData, (int)dataLength, &bytesWritten);

// close file
volume->Close(fileHandle);

if ((uint32_t)bytesWritten != dataLength)
{
// failed to write expected number of bytes
errorCode = StorageOperationErrorCode::WriteError;
}
}
else if (operation == StorageOperation_Monitor::StorageOperation_Append)
{
void *fileHandle = NULL;
int64_t position;
int bytesWritten = 0;

// open the file
if (FAILED(volume->Open(relativePath, fileHandle)))
{
errorCode = StorageOperationErrorCode::WriteError;
goto done;
}

// seek to the end, to append
volume->Seek(fileHandle, 0, SEEKORIGIN_END, &position);

// append the data
volume->Write(fileHandle, fileData, (int)dataLength, &bytesWritten);

// close file
volume->Close(fileHandle);

if ((uint32_t)bytesWritten != dataLength)
{
// failed to write expected number of bytes
errorCode = StorageOperationErrorCode::WriteError;
}
}
else if (operation == StorageOperation_Monitor::StorageOperation_Delete)
{
// remove the file
if (FAILED(volume->Delete(relativePath, false)))
{
errorCode = StorageOperationErrorCode::DeleteError;
}
}

done:

// free buffer memory
if (storageName != NULL)
{
platform_free(storageName);
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

return errorCode;
}

#endif // CONFIG_NF_FEATURE_HAS_ACCESSIBLE_STORAGE
5 changes: 0 additions & 5 deletions targets/ChibiOS/_common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ if(NF_FEATURE_HAS_CONFIG_BLOCK)
list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_ConfigurationManager.cpp)
endif()

# include internal storage, if feature is enabled
if(NF_FEATURE_HAS_ACCESSIBLE_STORAGE)
list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_StorageOperation.cpp)
endif()

# append nanoHAL
list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c)
list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp)
Expand Down
Loading
Loading