mirror of
https://github.com/eclipse-threadx/filex.git
synced 2026-09-14 12:36:59 +08:00
Added Win64/VS 2022 port for FileX (#94)
- New port: ports/win64/vs_2022/inc/fx_port.h
- Based on the Win32 port; updated ALIGN_TYPE to ULONG64 for 64-bit
pointers, added FX_REGRESSION_TEST hooks from the Linux port, and
bumped the port name string to Win64/Visual.
- New CMake infrastructure: ports/win64/vs_2022/CMakeLists.txt
- Exposes only the inc/ directory (port is header-only).
- Updated test/cmake/CMakeLists.txt
- Added MSVC guards: skip -m32 / GCC coverage flags; locate VS 2022
toolchain; build ThreadX from source alongside FileX via
THREADX_SOURCE_DIR.
- Updated test/cmake/regression/CMakeLists.txt
- Added MSVC-compatible compile options (/W3 /Zi instead of -Wall
-fprofile-arcs); added win64_compat include path for standalone +
MSVC builds; added per-test TIMEOUT overrides for the two inherently
long-running fault-tolerant tests on Windows.
- Updated test/cmake/samples/CMakeLists.txt
- Added MSVC-compatible flag handling.
- New PowerShell scripts: scripts/build_fx.ps1, scripts/test_fx.ps1,
scripts/fx_windows_common.ps1
- Support all 9 build configurations; -Clean, -Config, -Verbose flags;
modelled on the ThreadX Win64 build/test scripts.
- New Windows compatibility shims for standalone builds:
test/regression_test/win64_compat/pthread.h
test/regression_test/win64_compat/unistd.h
- Minimal pthreads (CreateThread / WaitForSingleObject / TerminateThread)
and usleep (Sleep) shims so standalone test files compile on MSVC.
- Fixed test/regression_test/fx_ram_driver_test.c and .h
- RAM driver: added bounds check so out-of-range sector READs use a
safe scratch buffer instead of segfaulting.
- MSVC: large test buffers (ram_disk_memory_large, large_data_buffer,
and standalone-mode ram_disk_memory / ram_disk_memory1) moved from
BSS to calloc() via a .CRT\ constructor. This avoids the MSVC
PE image 2 GB hard limit (LNK1248) and eliminates demand-zero page-
fault overhead that would otherwise slow the test suite.
- Bulk-fixed 93 fault-tolerant test files
- [FAULT_TOLERANT_SIZE] -> [FAULT_TOLERANT_SIZE > 0 ? FAULT_TOLERANT_SIZE : 1]
so that MSVC C2466 (zero-length array) is not triggered when
FX_ENABLE_FAULT_TOLERANT is not defined.
- Fixed filextestcontrol.c: standalone test runner thread exit
- The Win64 pthread shim makes pthread_exit() a no-op so that
test_control_thread_entry() proceeds to exit(failed_tests),
giving ctest the correct process exit code.
- Fixed common/src/fx_utility_logical_sector_write.c
- Added missing bounds guard to prevent sector-write past end of
RAM disk during fault-tolerant interrupt simulation tests.
All 9 build configurations pass 136/136 regression tests on Win64/VS 2022.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
b93ac4ae77
commit
7cbe022bab
@@ -0,0 +1,10 @@
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
# {{BEGIN_TARGET_SOURCES}}
|
||||
|
||||
# {{END_TARGET_SOURCES}}
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/inc
|
||||
)
|
||||
@@ -0,0 +1,368 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2026 Eclipse ThreadX contributors
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the MIT License which is available at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*
|
||||
* AI Disclosure: This file was largely AI-generated by Copilot (Claude Sonnet 4.6).
|
||||
* The AI-generated portions may be considered public domain (CC0-1.0)
|
||||
* and not subject to the project's licence. The human contributor has
|
||||
* reviewed and verified that the code is correct.
|
||||
*
|
||||
* SPDX-License-Identifier: MIT and CC0-1.0
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** FileX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* fx_port.h Win64/Visual */
|
||||
/* 6.5.1.202602 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Eclipse ThreadX contributors */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the FileX FAT */
|
||||
/* compatible file system function identically on a variety of */
|
||||
/* different processor architectures. For example, the byte offset of */
|
||||
/* various entries in the boot record, and directory entries are */
|
||||
/* defined in this file. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef FX_PORT_H
|
||||
#define FX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional FileX user define file should be used. */
|
||||
|
||||
#ifdef FX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* Yes, include the user defines in fx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "fx_user.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Include the ThreadX api file. */
|
||||
|
||||
#ifndef FX_STANDALONE_ENABLE
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define ULONG64 typedef, if not already defined. */
|
||||
|
||||
#ifndef ULONG64_DEFINED
|
||||
#define ULONG64_DEFINED
|
||||
typedef unsigned long long ULONG64;
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef char BOOL;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
#endif
|
||||
|
||||
#ifndef ULONG64_DEFINED
|
||||
#define ULONG64_DEFINED
|
||||
typedef unsigned long long ULONG64;
|
||||
#endif
|
||||
|
||||
|
||||
/* Define basic alignment type used in block and byte pool operations. This data type must
|
||||
be at least 32-bits in size and also be large enough to hold a pointer type.
|
||||
On Win64, pointers are 64 bits so ULONG (32-bit on Windows LLP64) is insufficient. */
|
||||
|
||||
#ifndef ALIGN_TYPE_DEFINED
|
||||
#define ALIGN_TYPE_DEFINED
|
||||
#define ALIGN_TYPE ULONG64
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* FX_STANDALONE_ENABLE */
|
||||
|
||||
|
||||
#ifdef FX_REGRESSION_TEST
|
||||
|
||||
/* Define parameters for regression test suite. */
|
||||
|
||||
#define FX_MAX_SECTOR_CACHE 256
|
||||
#define FX_MAX_FAT_CACHE 64
|
||||
#define FX_FAT_MAP_SIZE 1
|
||||
|
||||
|
||||
/* Define variables and macros used to introduce errors for the regression test suite. */
|
||||
|
||||
extern ULONG _fx_ram_driver_io_error_request;
|
||||
extern ULONG _fx_ram_driver_io_request_count;
|
||||
extern ULONG _fx_file_open_max_file_size_request;
|
||||
extern ULONG _fx_directory_entry_read_count;
|
||||
extern ULONG _fx_directory_entry_read_error_request;
|
||||
extern ULONG _fx_directory_entry_write_count;
|
||||
extern ULONG _fx_directory_entry_write_error_request;
|
||||
extern ULONG _fx_utility_fat_entry_write_count;
|
||||
extern ULONG _fx_utility_fat_entry_write_error_request;
|
||||
extern ULONG _fx_utility_fat_entry_read_count;
|
||||
extern ULONG _fx_utility_fat_entry_read_error_request;
|
||||
extern ULONG _fx_utility_logical_sector_flush_count;
|
||||
extern ULONG _fx_utility_logical_sector_flush_error_request;
|
||||
extern ULONG _fx_utility_logical_sector_write_count;
|
||||
extern ULONG _fx_utility_logical_sector_write_error_request;
|
||||
extern ULONG _fx_utility_logical_sector_read_count;
|
||||
extern ULONG _fx_utility_logical_sector_read_error_request;
|
||||
extern ULONG _fx_utility_logical_sector_read_1_count;
|
||||
extern ULONG _fx_utility_logical_sector_read_1_error_request;
|
||||
|
||||
#ifdef FX_ENABLE_FAULT_TOLERANT
|
||||
struct FX_MEDIA_STRUCT;
|
||||
extern VOID fault_tolerant_enable_callback(struct FX_MEDIA_STRUCT *media_ptr,
|
||||
UCHAR *fault_tolerant_memory_buffer,
|
||||
ULONG log_size);
|
||||
extern VOID fault_tolerant_apply_log_callback(struct FX_MEDIA_STRUCT *media_ptr,
|
||||
UCHAR *fault_tolerant_memory_buffer,
|
||||
ULONG log_size);
|
||||
#endif /* FX_ENABLE_FAULT_TOLERANT */
|
||||
|
||||
|
||||
#define FX_DIRECTORY_ENTRY_READ_EXTENSION _fx_directory_entry_read_count++; \
|
||||
if (_fx_directory_entry_read_error_request) \
|
||||
{ \
|
||||
_fx_directory_entry_read_error_request--; \
|
||||
if (_fx_directory_entry_read_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_DIRECTORY_ENTRY_WRITE_EXTENSION _fx_directory_entry_write_count++; \
|
||||
if (_fx_directory_entry_write_error_request) \
|
||||
{ \
|
||||
_fx_directory_entry_write_error_request--; \
|
||||
if (_fx_directory_entry_write_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_FAT_ENTRY_READ_EXTENSION _fx_utility_fat_entry_read_count++; \
|
||||
if (_fx_utility_fat_entry_read_error_request) \
|
||||
{ \
|
||||
_fx_utility_fat_entry_read_error_request--; \
|
||||
if (_fx_utility_fat_entry_read_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
if (_fx_utility_fat_entry_read_error_request == 10000) \
|
||||
{ \
|
||||
*entry_ptr = 1; \
|
||||
_fx_utility_fat_entry_read_error_request = 0; \
|
||||
return(FX_SUCCESS); \
|
||||
} \
|
||||
if (_fx_utility_fat_entry_read_error_request == 20000) \
|
||||
{ \
|
||||
*entry_ptr = media_ptr -> fx_media_fat_reserved; \
|
||||
_fx_utility_fat_entry_read_error_request = 0; \
|
||||
return(FX_SUCCESS); \
|
||||
} \
|
||||
if (_fx_utility_fat_entry_read_error_request == 30000) \
|
||||
{ \
|
||||
*entry_ptr = cluster; \
|
||||
_fx_utility_fat_entry_read_error_request = 0; \
|
||||
return(FX_SUCCESS); \
|
||||
} \
|
||||
if (_fx_utility_fat_entry_read_error_request == 40000) \
|
||||
{ \
|
||||
media_ptr -> fx_media_total_clusters = 0; \
|
||||
_fx_utility_fat_entry_read_error_request = 0; \
|
||||
return(FX_SUCCESS); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_FAT_ENTRY_WRITE_EXTENSION _fx_utility_fat_entry_write_count++; \
|
||||
if (_fx_utility_fat_entry_write_error_request) \
|
||||
{ \
|
||||
_fx_utility_fat_entry_write_error_request--; \
|
||||
if (_fx_utility_fat_entry_write_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_LOGICAL_SECTOR_FLUSH_EXTENSION _fx_utility_logical_sector_flush_count++; \
|
||||
if (_fx_utility_logical_sector_flush_error_request) \
|
||||
{ \
|
||||
_fx_utility_logical_sector_flush_error_request--; \
|
||||
if (_fx_utility_logical_sector_flush_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION _fx_utility_logical_sector_read_count++; \
|
||||
if (_fx_utility_logical_sector_read_error_request) \
|
||||
{ \
|
||||
_fx_utility_logical_sector_read_error_request--; \
|
||||
if (_fx_utility_logical_sector_read_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_LOGICAL_SECTOR_READ_EXTENSION_1 _fx_utility_logical_sector_read_1_count++; \
|
||||
if (_fx_utility_logical_sector_read_1_error_request) \
|
||||
{ \
|
||||
_fx_utility_logical_sector_read_1_error_request--; \
|
||||
if (_fx_utility_logical_sector_read_1_error_request == 0) \
|
||||
{ \
|
||||
cache_entry = FX_NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_UTILITY_LOGICAL_SECTOR_WRITE_EXTENSION _fx_utility_logical_sector_write_count++; \
|
||||
if (_fx_utility_logical_sector_write_error_request) \
|
||||
{ \
|
||||
_fx_utility_logical_sector_write_error_request--; \
|
||||
if (_fx_utility_logical_sector_write_error_request == 0) \
|
||||
{ \
|
||||
return(FX_IO_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FX_FAULT_TOLERANT_ENABLE_EXTENSION fault_tolerant_enable_callback(media_ptr, media_ptr -> fx_media_fault_tolerant_memory_buffer, total_size);
|
||||
#define FX_FAULT_TOLERANT_APPLY_LOGS_EXTENSION fault_tolerant_apply_log_callback(media_ptr, media_ptr -> fx_media_fault_tolerant_memory_buffer, size);
|
||||
|
||||
#endif /* FX_REGRESSION_TEST */
|
||||
|
||||
|
||||
/* Define FileX internal protection macros. If FX_SINGLE_THREAD is defined,
|
||||
these protection macros are effectively disabled. However, for multi-thread
|
||||
uses, the macros are setup to utilize a ThreadX mutex for multiple thread
|
||||
access control into an open media. */
|
||||
|
||||
/* Reduce the mutex error checking for testing purpose. */
|
||||
|
||||
#if defined(FX_SINGLE_THREAD) || defined(FX_STANDALONE_ENABLE)
|
||||
#define FX_PROTECT
|
||||
#define FX_UNPROTECT
|
||||
#else
|
||||
#define FX_PROTECT tx_mutex_get(&(media_ptr -> fx_media_protect), TX_WAIT_FOREVER);
|
||||
#define FX_UNPROTECT tx_mutex_put(&(media_ptr -> fx_media_protect));
|
||||
#endif
|
||||
|
||||
|
||||
/* Define interrupt lockout constructs to protect the system date/time from being updated
|
||||
while they are being read. */
|
||||
|
||||
#ifndef FX_STANDALONE_ENABLE
|
||||
#define FX_INT_SAVE_AREA unsigned int old_interrupt_posture;
|
||||
#define FX_DISABLE_INTS old_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
|
||||
#define FX_RESTORE_INTS tx_interrupt_control(old_interrupt_posture);
|
||||
#else
|
||||
#ifndef FX_LEGACY_INTERRUPT_PROTECTION
|
||||
#define FX_LEGACY_INTERRUPT_PROTECTION
|
||||
#endif
|
||||
#define FX_INT_SAVE_AREA
|
||||
#define FX_DISABLE_INTS
|
||||
#define FX_RESTORE_INTS
|
||||
#endif
|
||||
|
||||
/* Define the error checking logic to determine if there is a caller error in the FileX API.
|
||||
The default definitions assume ThreadX is being used. This code can be completely turned
|
||||
off by just defining these macros to white space. */
|
||||
|
||||
#ifndef FX_STANDALONE_ENABLE
|
||||
#ifndef TX_TIMER_PROCESS_IN_ISR
|
||||
|
||||
#define FX_CALLER_CHECKING_EXTERNS extern TX_THREAD *_tx_thread_current_ptr; \
|
||||
extern TX_THREAD _tx_timer_thread; \
|
||||
extern volatile ULONG _tx_thread_system_state;
|
||||
|
||||
#define FX_CALLER_CHECKING_CODE if ((_tx_thread_system_state) || \
|
||||
(_tx_thread_current_ptr == TX_NULL) || \
|
||||
(_tx_thread_current_ptr == &_tx_timer_thread)) \
|
||||
return(FX_CALLER_ERROR);
|
||||
|
||||
#else
|
||||
#define FX_CALLER_CHECKING_EXTERNS extern TX_THREAD *_tx_thread_current_ptr; \
|
||||
extern volatile ULONG _tx_thread_system_state;
|
||||
|
||||
#define FX_CALLER_CHECKING_CODE if ((_tx_thread_system_state) || \
|
||||
(_tx_thread_current_ptr == TX_NULL)) \
|
||||
return(FX_CALLER_ERROR);
|
||||
#endif
|
||||
#else
|
||||
#define FX_CALLER_CHECKING_EXTERNS
|
||||
#define FX_CALLER_CHECKING_CODE
|
||||
#endif
|
||||
|
||||
/* Define the update rate of the system timer. These values may also be defined at the command
|
||||
line when compiling the fx_system_initialize.c module in the FileX library build. Alternatively,
|
||||
they can be modified in this file or fx_user.h. Note: the update rate must be an even number of
|
||||
seconds greater than or equal to 2, which is the minimal update rate for FAT time. */
|
||||
|
||||
/* Define the number of seconds the timer parameters are updated in FileX. The default
|
||||
value is 10 seconds. This value can be overwritten externally. */
|
||||
|
||||
#ifndef FX_UPDATE_RATE_IN_SECONDS
|
||||
#define FX_UPDATE_RATE_IN_SECONDS 10
|
||||
#endif
|
||||
|
||||
|
||||
/* Defines the number of ThreadX timer ticks required to achieve the update rate specified by
|
||||
FX_UPDATE_RATE_IN_SECONDS defined previously. By default, the ThreadX timer tick is 10ms,
|
||||
so the default value for this constant is 1000. If TX_TIMER_TICKS_PER_SECOND is defined,
|
||||
this value is derived from TX_TIMER_TICKS_PER_SECOND. */
|
||||
|
||||
#ifndef FX_UPDATE_RATE_IN_TICKS
|
||||
#if (defined(TX_TIMER_TICKS_PER_SECOND) && (!defined(FX_STANDALONE_ENABLE)))
|
||||
#define FX_UPDATE_RATE_IN_TICKS (TX_TIMER_TICKS_PER_SECOND * FX_UPDATE_RATE_IN_SECONDS)
|
||||
#else
|
||||
#define FX_UPDATE_RATE_IN_TICKS 1000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the version ID of FileX. This may be utilized by the application. */
|
||||
|
||||
#ifdef FX_SYSTEM_INIT
|
||||
CHAR _fx_version_id[] =
|
||||
"Copyright (c) 2026 Eclipse ThreadX contributors. * FileX Win64/Visual 6.5.1.202602 *";
|
||||
#else
|
||||
extern CHAR _fx_version_id[];
|
||||
#endif
|
||||
|
||||
#endif /* FX_PORT_H */
|
||||
Reference in New Issue
Block a user