diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 322eb12..4590f5d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,13 @@ xscope fileio change log ======================== +1.1.1 +----- + + * REMOVED: xscope_fread() delay for Windows race condition + * ADDED: checks that xscope_io_init() has completed before allowing a file to be opened + * ADDED: adds helper function, xscope_fileio_is_initialized(), to allow application to check if the host connection has been established + 1.1.0 ----- @@ -13,7 +20,7 @@ xscope fileio change log * ADDED: support for building and running the host endpoint on Windows * ADDED: XMOS public V1 license * ADDED: support for run_on_target() to optionally redirect stdout to file - * REMOVED:run_on_target() method returns stdout/err as list of lines + * REMOVED:run_on_target() method returns stdout/err as list of lines * REMOVED: optional verbose kwarg in run_on_target()to reduce verbosity 0.4.0 diff --git a/README.rst b/README.rst index 4b678c7..32f9a74 100644 --- a/README.rst +++ b/README.rst @@ -59,6 +59,8 @@ Source and header files for device code are found in ``src_xcore`` void xscope_io_init(chanend_t xscope_end); + unsigned xscope_fileio_is_initialized(void); + xscope_file_t xscope_open_file(char* filename, char* attributes); //NOTE MAXIMUM n_bytes_to_read of 64kB on Linux http://bugzilla/show_bug.cgi?id=18528 @@ -68,7 +70,7 @@ Source and header files for device code are found in ``src_xcore`` void xscope_fseek(xscope_file_t *xscope_io_handle, int offset, int whence); - int xscope_ftell(xscope_file_t *xscope_file); + int xscope_ftell(xscope_file_t *xscope_file); void xscope_close_all_files(void); @@ -76,7 +78,7 @@ The device side application requires a multi-tile main since it uses the xscope_ to communicate with the host, which requires this. See examples for XC and C applications for how to do this. You will also need a copy of ``config.xscope`` in your firmware directory. This -enables xscope in the tools and sets up the xscope probes used by fileio for communicating with the host app. You +enables xscope in the tools and sets up the xscope probes used by fileio for communicating with the host app. You can find a copy in ``xscope_fileio/config.xscope xscope_fileio/config.xscope.txt`` which you should rename to ``config.xscope``. Note currently missing from fileio api: @@ -90,7 +92,7 @@ System Architecture ------------------- The ``run_on_target`` function calls ``xrun --xscope-port`` with the binary and specified target adapter, -and simultaneously launches a host application to communicate xscope data to/from +and simultaneously launches a host application to communicate xscope data to/from the xrun process via sockets. The host application responds to ``xscope_fileio`` API calls in the firmware code, reading/writing to the host file system. diff --git a/xscope_fileio/api/xscope_io_device.h b/xscope_fileio/api/xscope_io_device.h index c871868..67a2e51 100644 --- a/xscope_fileio/api/xscope_io_device.h +++ b/xscope_fileio/api/xscope_io_device.h @@ -31,10 +31,19 @@ extern "C"{ * * @param xscope_end is the app side channel end connected xscope_host_data() * task in the top level application. - * @return void + * @return void ******************************************************************************/ void xscope_io_init(chanend_t xscope_end); +/****************************************************************************** + * xscope_fileio_is_initialized + * + * This returns the status of the host xscope fileio connection + * + * @return 1 if initialized, else 0 + ******************************************************************************/ +unsigned xscope_fileio_is_initialized(void); + /****************************************************************************** * xscope_open_files * @@ -44,7 +53,7 @@ void xscope_io_init(chanend_t xscope_end); * * @param read_file_name to open on host * @param write_file_name to open on host - * @return an initialised xscope_file_handle + * @return an initialised xscope_file_handle ******************************************************************************/ xscope_file_t xscope_open_file(const char* filename, char* attributes); @@ -56,9 +65,9 @@ xscope_file_t xscope_open_file(const char* filename, char* attributes); * requested data from the file. Each read is contiguous from the previous read * * @param handle of file to operate on - * @param buffer that will be written the file read + * @param buffer that will be written the file read * @param n_bytes_to_read - * @return number of bytes actually read. Will be zero if EOF already hit. + * @return number of bytes actually read. Will be zero if EOF already hit. ******************************************************************************/ size_t xscope_fread(xscope_file_t *xscope_io_handle, uint8_t *buffer, size_t n_bytes_to_read); @@ -68,9 +77,9 @@ size_t xscope_fread(xscope_file_t *xscope_io_handle, uint8_t *buffer, size_t n_b * Writes a number of bytes from the buffer provided by the application. * * @param handle of file to operate on - * @param buffer that will be read and sent to be written on the host + * @param buffer that will be read and sent to be written on the host * @param n_bytes_to_write - * @return void + * @return void ******************************************************************************/ void xscope_fwrite(xscope_file_t *xscope_io_handle, uint8_t *buffer, size_t n_bytes_to_write); @@ -80,9 +89,9 @@ void xscope_fwrite(xscope_file_t *xscope_io_handle, uint8_t *buffer, size_t n_by * Sets the file position of the stream to the given offset * * @param handle of file to operate on - * @param offset in bytes + * @param offset in bytes * @param whence - SEEK_SET, SEEK_CUR or SEEK_END - * @return void + * @return void ******************************************************************************/ void xscope_fseek(xscope_file_t *xscope_io_handle, int offset, int whence); @@ -92,9 +101,9 @@ void xscope_fseek(xscope_file_t *xscope_io_handle, int offset, int whence); * Obtain the file position of the stream * * @param handle of file to operate on - * @return void + * @return void ******************************************************************************/ -int xscope_ftell(xscope_file_t *xscope_file); +int xscope_ftell(xscope_file_t *xscope_file); /****************************************************************************** @@ -104,7 +113,7 @@ int xscope_ftell(xscope_file_t *xscope_file); * This must be called at the end of device application as it also signals * terminate to the host app. * - * @return void + * @return void ******************************************************************************/ void xscope_close_all_files(void); @@ -112,4 +121,4 @@ void xscope_close_all_files(void); } #endif -#endif \ No newline at end of file +#endif diff --git a/xscope_fileio/module_build_info b/xscope_fileio/module_build_info index 7b658d6..e6ada03 100644 --- a/xscope_fileio/module_build_info +++ b/xscope_fileio/module_build_info @@ -1,4 +1,4 @@ -VERSION = 1.1.0 +VERSION = 1.1.1 MODULE_XCC_FLAGS = $(XCC_FLAGS) diff --git a/xscope_fileio/src/xscope_io_device.c b/xscope_fileio/src/xscope_io_device.c index 691ff68..616bfa5 100644 --- a/xscope_fileio/src/xscope_io_device.c +++ b/xscope_fileio/src/xscope_io_device.c @@ -16,6 +16,7 @@ chanend_t c_xscope = 0; unsigned file_idx = 0; lock_t file_access_lock; +volatile unsigned xscope_io_init_flag = 0; __attribute__((weak)) void xscope_fileio_lock_alloc(void) { @@ -33,14 +34,23 @@ void xscope_fileio_lock_release(void) { lock_release(file_access_lock); } +unsigned xscope_fileio_is_initialized(void) { + return xscope_io_init_flag; +} + void xscope_io_init(chanend_t xscope_end){ xscope_fileio_lock_alloc(); xscope_mode_lossless(); c_xscope = xscope_end; xscope_connect_data_from_host(c_xscope); + xscope_io_init_flag = 1; } xscope_file_t xscope_open_file(const char* filename, char* attributes){ + /* Wait until xscope_fileio is initialized */ + while(xscope_fileio_is_initialized() == 0) { + delay_ticks(1); + } xscope_fileio_lock_acquire(); xscope_file_t xscope_file; strcpy(xscope_file.filename, filename); @@ -93,16 +103,6 @@ size_t xscope_fread(xscope_file_t *xscope_file, uint8_t *buffer, size_t n_bytes_ xscope_bytes(XSCOPE_ID_READ_BYTES, sizeof(packet), packet); - // Add a delay to avoid a race condition seen only on Windows - // See issue 30 - #define XSCOPE_FREAD_RACE_CONDITION_DELAY ( XS1_TIMER_MHZ * 100 ) - - // Define the timeafter macro until it becomes available in C source files via xs1.h - #define timeafter(A, B) ((int)((B) - (A)) < 0) - - uint32_t time_delay = get_reference_time() + XSCOPE_FREAD_RACE_CONDITION_DELAY; - while(timeafter(time_delay, get_reference_time())); - do { int bytes_read = 0;