Hi all,
I'm using the CMSIS ftp client to upload a file to a server.. All the process is ok, create the file in the memory card, write some data, connect to the server, start session and put the file... everything is ok.. but, the file on the server is always empty.
When I debug the program and place a breakpoint on the ftp_client_fread function where is the fread function that reads the file from the SD card requested by the ftp client, the fread function is returning a 0 value that is an error (no data readed)... for this reason the file on the server have size zero.
The function receives a correct file handler but can't read enything. If I place in the ftp_client_fread function a full code to open a file and read (to be sure that the handler is ok) fread returns zero:
__weak uint32_t ftp_client_fread (void *file, uint8_t *buf, uint32_t len) { // Read block of data from local file in FTP client. size_t ret; char data[40]; FILE *f = fopen ("M0:\\hola.txt", "r"); if (f != NULL){ ret = fread (data, 10, 1, (FILE *)f); fclose (f); } return (ret); }
But the file exists and is OK with data.. Also I tested the same with a ramdrive and the same result...
Thanks
the fread function is returning a 0 value that is an error
No, that's not (necessarily) an error. It's just telling you that it can only read zero bytes from that file, at this time. Which is perfectly normal for an empty file, or access to the data is temporarily unavaiable.
This might very well be caused by the routine that wrote the file failing to close it. Afterwords. While generic desktop or server OSes may allow concurrent access to files for writing and reading, within certain limitations, simpler systems like RTOS often don't.
Hi,
I said error because the file is not empty, it contains data. If I place the code outside this function the code is OK and the read function returns 1. If I do the same with a file already created and stored in the sd card the problem is the same...
Are you using the file system from multiple threads?
Did you check for stack overflow in the call back function?
Why did you modify the FTP_Client_FS.c file system interface? If you are using SD card, you shouldn't. FTP client calls interface functions to open, read, write and close a file on SD card. You should customize the functions in FTP_Client_UIF.c user interface only.
Here is more information: http://www.keil.com/pack/doc/mw/Network/html/using_ftp_client.html
FTP client functions are documented here: www.keil.com/.../group__net__ftpc_func.html
I commented this functions on the FTP_Client_FS.c because I need to do some special stuff like write to flash the new firmware. Because the firmware is too long can't save it in the ram drive and then copy to the flash, I need to copy it on the fly when the bytes are coming in by the ftp client...
Anyway I tried the same thing with the original FTP_Client_FS.c file and the result is the same.
Ok, I understand.
You probably mean FTP download (from FTP server to a local system) and not FTP upload.
When you start FTP client session with ftp_client_connect, the client will call interface functions in this sequence: - ftp_client_fopen (fname, "wb") - ftp_client_fwrite (file, buf, len) - ftp_client_fwrite (file, buf, len) - ... - ftp_client_fclose (file)
So for the firmware update you should: - erase the flash in ftp_client_fopen - write data to flash in subsequent calls to ftp_client_fwrite - terminate/lock the flash in ftp_client_fclose
The problem in your example published above is that you actually do not return the data to FTP client. The function should read the data to provided buffer:
ret = fread (buf, 10, 1, (FILE *)f);
You would normally want to download the flash image to the memory card. And not until the FTP transfer has ended and you have verified that you have a complete file - with correct CRC32/MD5/... and some magic marker that indicates that it really is a firmware for your specific platform - would you want to perform the flashing of the firmware.
And you would want to use a boot loader to perform the actual flashing (unless you can afford two separate application regions) so that you can survive a power loss during the flash operation and have the boot loader just continue with the flashing when the power returns. Just writing directly to flash on-the-fly tends to be a great way to get bricked units. Or is it your boot loader that contains the FTP client, so you can restart the FTP transfer after an unexpected reboot or power loss?
Yes, for the firmware update I need to download from the server and the proces will be:
- ftp_client_fopen (fname, "wb") - ftp_client_fwrite (file, buf, len) - ftp_client_fwrite (file, buf, len)
But in my first post the example was for upload a file and the executed function will be
__weak uint32_t ftp_client_fread (void *file, uint8_t *buf, uint32_t len
At this time I'm trying to upload a file and the function fread returns 0... don't know why bacause the file exist in the memory card.
Don't want to use a SD card for this for many reasons:
1. The SD card add extra cost to the project (this is not a home made project, is for large quantity)
2. If the power fails in a writing to the SD card the card can be broken (this is a problem with the SD cards) and the product will never be upgraded
I'm using a STM32F4 with 1M of flash and I have enough memory for bootloader, firmware (2 partitions), user data.
The process is the next:
1. Bootloader checks the latest firmware version of each of the two partitions 2. Check the MD5 for this partition with the MD5 saves to user data space 3. If the check fails boots from the other partition 4. If a new firmware will be downloaded this will be wrote to the not used partition and then restart. If the ftp fails and the data is corrupted the bootloader will boot from current partition
I think this boot and updating system can't fail
Did you mount the drive before calling fopen?
www.keil.com/.../group__system__routines.html
Ok course... first finit ("M0:") and then fmount ("M0:")
In fact if I open the file int the main function or other thread I can read or write the file without problems... The only problem is in the ftp_client_fread callback...