From e1020c04a478c3e44f535ff6fdfaeedc02b7b539 Mon Sep 17 00:00:00 2001 From: Ollie <oliver2.beard@live.uwe.ac.uk> Date: Tue, 8 Apr 2025 14:14:54 +0000 Subject: [PATCH] Update 9 files - /Worksheet 1/Part 1/Code/cli.c - /Worksheet 1/Part 1/Code/cli.h - /Worksheet 1/Part 1/Code/CMakeLists.txt - /Worksheet 1/Part 1/Code/custom_fgets.c - /Worksheet 1/Part 1/Code/custom_fgets.h - /Worksheet 1/Part 1/Code/flash_ops.h - /Worksheet 1/Part 1/Code/main.c - /Worksheet 1/Part 1/Code/pico_sdk_import.cmake - /Worksheet 1/Part 1/Code/flash_ops.c --- Worksheet 1/Part 1/Code/CMakeLists.txt | 3 - Worksheet 1/Part 1/Code/cli.c | 37 +++------ Worksheet 1/Part 1/Code/cli.h | 2 +- Worksheet 1/Part 1/Code/custom_fgets.c | 1 - Worksheet 1/Part 1/Code/custom_fgets.h | 2 +- Worksheet 1/Part 1/Code/flash_ops.c | 78 +++++++++---------- Worksheet 1/Part 1/Code/flash_ops.h | 2 +- Worksheet 1/Part 1/Code/main.c | 4 +- Worksheet 1/Part 1/Code/pico_sdk_import.cmake | 5 -- 9 files changed, 54 insertions(+), 80 deletions(-) diff --git a/Worksheet 1/Part 1/Code/CMakeLists.txt b/Worksheet 1/Part 1/Code/CMakeLists.txt index c6fb6b5..979e975 100644 --- a/Worksheet 1/Part 1/Code/CMakeLists.txt +++ b/Worksheet 1/Part 1/Code/CMakeLists.txt @@ -1,12 +1,9 @@ cmake_minimum_required(VERSION 3.13) -# Manually set the PICO_SDK_PATH (ensure this is correct) set(PICO_SDK_PATH "${CMAKE_SOURCE_DIR}/../pico-sdk") -# Debugging output to check the path message(STATUS "Using PICO_SDK_PATH: ${PICO_SDK_PATH}") -# Ensure the SDK import file exists before including it if (NOT EXISTS "${PICO_SDK_PATH}/external/pico_sdk_import.cmake") message(FATAL_ERROR "Pico SDK not found at ${PICO_SDK_PATH}. Did you initialize the submodules?") endif() diff --git a/Worksheet 1/Part 1/Code/cli.c b/Worksheet 1/Part 1/Code/cli.c index fd2339c..bd86dfc 100644 --- a/Worksheet 1/Part 1/Code/cli.c +++ b/Worksheet 1/Part 1/Code/cli.c @@ -5,31 +5,16 @@ #include <string.h> #include "custom_fgets.h" -// Function: execute_command -// Parses and executes commands related to flash memory operations. -// -// Parameters: -// - command: A string containing the command and its arguments. -// -// The function supports the following commands: -// - FLASH_WRITE: Writes data to flash memory. -// - FLASH_READ: Reads data from flash memory. -// - FLASH_ERASE: Erases a sector of flash memory. -// -// Each command expects specific arguments following the command name. void execute_command(char *command) { - // Split the command string into tokens char *token = strtok(command, " "); - // Check for an empty or invalid command if (token == NULL) { printf("\nInvalid command\n"); return; } - // Handle the FLASH_WRITE command + //Handle the FLASH_WRITE command if (strcmp(token, "FLASH_WRITE") == 0) { - // Parse the address token = strtok(NULL, " "); if (token == NULL) { printf("\nFLASH_WRITE requires an address and data\n"); @@ -37,19 +22,18 @@ void execute_command(char *command) { } uint32_t address = atoi(token); - // Parse the data, assuming it's enclosed in quotes + //Parse the data, assuming it's enclosed in quotes token = strtok(NULL, "\""); if (token == NULL) { printf("\nInvalid data format for FLASH_WRITE\n"); return; } - // Execute the write operation + //Execute the write operation flash_write_safe(address, (uint8_t *)token, strlen(token)); } - // Handle the FLASH_READ command + //Handle the FLASH_READ command else if (strcmp(token, "FLASH_READ") == 0) { - // Parse the address token = strtok(NULL, " "); if (token == NULL) { printf("\nFLASH_READ requires an address and length\n"); @@ -57,7 +41,7 @@ void execute_command(char *command) { } uint32_t address = atoi(token); - // Parse the length of data to read + //Parse the length of data to read token = strtok(NULL, " "); if (token == NULL) { printf("\nInvalid length for FLASH_READ\n"); @@ -65,16 +49,15 @@ void execute_command(char *command) { } size_t length = atoi(token); - // Prepare the buffer and execute the read operation + //Prepare the buffer and execute the read operation uint8_t buffer[length]; flash_read_safe(address, buffer, length); - // Output the read data + //Output the read data printf("\nData: %s\n", buffer); } - // Handle the FLASH_ERASE command + //Handle the FLASH_ERASE command else if (strcmp(token, "FLASH_ERASE") == 0) { - // Parse the address token = strtok(NULL, " "); if (token == NULL) { printf("FLASH_ERASE requires an address\n"); @@ -82,10 +65,10 @@ void execute_command(char *command) { } uint32_t address = atoi(token); - // Execute the erase operation + //Execute the erase operation flash_erase_safe(address); } - // Handle unknown commands + //Handle unknown commands else { printf("\nUnknown command\n"); } diff --git a/Worksheet 1/Part 1/Code/cli.h b/Worksheet 1/Part 1/Code/cli.h index f3009fd..51a6067 100644 --- a/Worksheet 1/Part 1/Code/cli.h +++ b/Worksheet 1/Part 1/Code/cli.h @@ -3,4 +3,4 @@ void execute_command(char *command); -#endif // CLI_H +#endif diff --git a/Worksheet 1/Part 1/Code/custom_fgets.c b/Worksheet 1/Part 1/Code/custom_fgets.c index 6c87f0b..f30872a 100644 --- a/Worksheet 1/Part 1/Code/custom_fgets.c +++ b/Worksheet 1/Part 1/Code/custom_fgets.c @@ -18,7 +18,6 @@ char* custom_fgets(char* str, int n, FILE* stream) { str[i++] = (char)ch; printf("%c", ch); } - // Non-printable characters are ignored } str[i] = '\0'; return str; diff --git a/Worksheet 1/Part 1/Code/custom_fgets.h b/Worksheet 1/Part 1/Code/custom_fgets.h index 20ea3f3..b2e074e 100644 --- a/Worksheet 1/Part 1/Code/custom_fgets.h +++ b/Worksheet 1/Part 1/Code/custom_fgets.h @@ -5,4 +5,4 @@ char* custom_fgets(char* str, int n, FILE* stream); -#endif // CUSTOM_FGETS_H +#endif diff --git a/Worksheet 1/Part 1/Code/flash_ops.c b/Worksheet 1/Part 1/Code/flash_ops.c index f29e095..f7ab487 100644 --- a/Worksheet 1/Part 1/Code/flash_ops.c +++ b/Worksheet 1/Part 1/Code/flash_ops.c @@ -6,115 +6,115 @@ #include "hardware/flash.h" #include "hardware/sync.h" -// Define the offset (in bytes) where user data starts in flash memory -#define FLASH_TARGET_OFFSET (256 * 1024) // 256 KB into flash memory -// Define the total available flash size +//Define where user data starts in flash memory +#define FLASH_TARGET_OFFSET (256 * 1024) //256 KB into flash memory +//Define the total available flash size #define FLASH_SIZE PICO_FLASH_SIZE_BYTES -// Define the size of a flash sector (typically 4KB per sector) +//Define the size of a flash sector #ifndef FLASH_SECTOR_SIZE -#define FLASH_SECTOR_SIZE (4096) // 4KB sector size +#define FLASH_SECTOR_SIZE (4096) //4KB sector size #endif -// Structure for storing metadata and payload data in flash memory +//Structure for storing metadata and payload data in flash memory typedef struct __attribute__((packed)) { - uint32_t write_count; // Number of times this flash block has been written - uint32_t data_len; // Length of the payload data in bytes - uint8_t data[]; // Flexible array member holding actual data + uint32_t write_count; + uint32_t data_len; + uint8_t data[]; } flash_data_t; -// Function to write a structured data block safely into flash memory +//Write a structured data block safely into flash memory void flash_write_safe(uint32_t offset, const uint8_t *data, size_t data_len) { - uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; // Calculate absolute flash address - size_t total_len = sizeof(flash_data_t) + data_len; // Total data length (header + payload) + uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; //Calculate flash address + size_t total_len = sizeof(flash_data_t) + data_len; //Total data length - // Ensure the write operation does not exceed flash memory bounds + //Ensure the write operation does not exceed flash memory bounds if (flash_offset + total_len > FLASH_SIZE) { printf("Error: Write operation out of flash memory bounds.\n"); return; } - static uint8_t temp_buf[FLASH_SECTOR_SIZE]; // Temporary buffer for flash operations + static uint8_t temp_buf[FLASH_SECTOR_SIZE]; //Temporary buffer for flash operations - // Ensure the write size does not exceed sector size + //Ensure the write size does not exceed sector size if (total_len > FLASH_SECTOR_SIZE) { printf("Error: Data size exceeds sector size.\n"); return; } - // Copy existing flash data into the temporary buffer before modification + //Copy existing flash data into the temporary buffer before modification memcpy(temp_buf, (void *)(XIP_BASE + flash_offset), FLASH_SECTOR_SIZE); - // Prepare the flash data structure in the temporary buffer + //Prepare the flash data structure in the temporary buffer flash_data_t *flash_data = (flash_data_t *)temp_buf; - flash_data->write_count++; // Increment write count - flash_data->data_len = data_len; // Store data length - memcpy(flash_data->data, data, data_len); // Copy payload data + flash_data->write_count++; + flash_data->data_len = data_len; + memcpy(flash_data->data, data, data_len); - // Disable interrupts to prevent conflicts during flash operations + //Disable interrupts to prevent conflicts during flash operations uint32_t ints = save_and_disable_interrupts(); - // Erase the flash sector before writing new data + //Erase the flash sector before writing new data flash_range_erase(flash_offset, FLASH_SECTOR_SIZE); - // Program the flash memory with the new structured data block + //Program the flash memory with the new structured data block flash_range_program(flash_offset, temp_buf, FLASH_SECTOR_SIZE); - // Restore interrupts after flash operation is complete + //Restore interrupts after flash operation is complete restore_interrupts(ints); } -// Function to read structured data safely from flash memory +//Read structured data safely from flash memory void flash_read_safe(uint32_t offset, uint8_t *buffer, size_t buffer_len) { - uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; // Calculate absolute flash address + uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; - // Ensure the read operation does not exceed flash bounds + //Ensure the read operation does not exceed flash bounds if (flash_offset + sizeof(flash_data_t) > FLASH_SIZE) { printf("Error: Read operation out of flash memory bounds (header).\n"); return; } - // Read the flash header containing metadata + //Read the flash header containing metadata flash_data_t header; memcpy(&header, (void *)(XIP_BASE + flash_offset), sizeof(flash_data_t)); - // Ensure the payload data does not exceed flash memory boundaries + //Ensure the payload data does not exceed flash memory boundaries if (flash_offset + sizeof(flash_data_t) + header.data_len > FLASH_SIZE) { printf("Error: Read operation out of flash memory bounds (data payload).\n"); return; } - // Print metadata information + //Print metadata information printf("\n Flash Data Metadata:\n"); printf(" Write count: %u\n", header.write_count); printf(" Data length: %u\n", header.data_len); - // Ensure the provided buffer is large enough for the payload + //Ensure the provided buffer is large enough for the payload if (buffer_len < header.data_len) { printf("Error: Provided buffer is too small to hold flash data payload.\n"); return; } - // Copy the actual data payload from flash into the provided buffer + //Copy the actual data payload from flash into the provided buffer memcpy(buffer, (void *)(XIP_BASE + flash_offset + sizeof(flash_data_t)), header.data_len); } -// Function to erase a flash sector safely +//Function to erase a flash sector safely void flash_erase_safe(uint32_t offset) { - uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; // Calculate absolute flash address + uint32_t flash_offset = FLASH_TARGET_OFFSET + offset; - // Ensure erase operation does not exceed flash memory bounds + //Ensure erase operation does not exceed flash memory bounds if (flash_offset >= FLASH_SIZE) { printf("Error: Erase operation out of flash memory bounds.\n"); return; } - uint32_t ints = save_and_disable_interrupts(); // Disable interrupts during erase - flash_range_erase(flash_offset, FLASH_SECTOR_SIZE); // Erase the flash sector + uint32_t ints = save_and_disable_interrupts(); + flash_range_erase(flash_offset, FLASH_SECTOR_SIZE); - // Reset metadata to avoid corrupted reads after erasing + //Reset metadata to avoid corrupted reads after erasing flash_data_t reset_data = {0}; flash_range_program(flash_offset, (uint8_t *)&reset_data, sizeof(flash_data_t)); - restore_interrupts(ints); // Restore interrupts after erase operation + restore_interrupts(ints); } \ No newline at end of file diff --git a/Worksheet 1/Part 1/Code/flash_ops.h b/Worksheet 1/Part 1/Code/flash_ops.h index 027adc5..7319a6a 100644 --- a/Worksheet 1/Part 1/Code/flash_ops.h +++ b/Worksheet 1/Part 1/Code/flash_ops.h @@ -8,4 +8,4 @@ void flash_write_safe(uint32_t offset, const uint8_t *data, size_t data_len); void flash_read_safe(uint32_t offset, uint8_t *buffer, size_t buffer_len); void flash_erase_safe(uint32_t offset); -#endif // FLASH_OPS_H +#endif diff --git a/Worksheet 1/Part 1/Code/main.c b/Worksheet 1/Part 1/Code/main.c index 6578775..d4c2d25 100644 --- a/Worksheet 1/Part 1/Code/main.c +++ b/Worksheet 1/Part 1/Code/main.c @@ -7,12 +7,12 @@ int main() { stdio_init_all(); char command[256]; - // Wait for USB connection + //Wait for USB connection while (!stdio_usb_connected()) { sleep_ms(100); } - // Command loop + //Command loop while (1) { printf("\nEnter command: "); custom_fgets(command, sizeof(command), stdin); diff --git a/Worksheet 1/Part 1/Code/pico_sdk_import.cmake b/Worksheet 1/Part 1/Code/pico_sdk_import.cmake index 65f8a6f..dc01f2c 100644 --- a/Worksheet 1/Part 1/Code/pico_sdk_import.cmake +++ b/Worksheet 1/Part 1/Code/pico_sdk_import.cmake @@ -1,8 +1,3 @@ -# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake - -# This can be dropped into an external project to help locate this SDK -# It should be include()ed prior to project() - if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") -- GitLab