fwrite always returns 0

I’m attempting to use fopen, fwrite, and fread to store data on a Digi Connect ME, as follows:


printf("Opening %s for writing
",fname );
fp = fopen(fname, "wb");
if(fp == NULL)
{
	printf("Unable to open %s for writing
", fname);
	return false;
}
write_res=fwrite(data, 1, size, fp);	
if((write_res<=size)&&(write_res!=0))
{		
	printf("Wrote %d to the file
",write_res);
	return TRUE;
}
else
	return FALSE;

Where data is a void * and size is the number of bytes to write. The call to fopen returns a valid pointer to file, yet the call to fwrite always return 0.

fname is “RAM0/001.bin”

Am I missing something?

Hello

First things I would do are the following:

After calling fopen, do something like:
printf("error returned by fopen was %d
", getErrno());

By the same token, after calling fwrite do the following:
printf("error returned by fwrite %d
", getErrno());

What do you get in both cases?

BTW, you’ll need to add #include “sockapi.h” to get functional prtotype for getErrno().

Are you able to ftp file in to that folder of RAMfs?
Please run sample application C:
etos75\src\examples
afileio\ and report the result

Hello

I finally got a chance to run a test of what you are doing. I am NOT seeing the results you are seeing. As a matter of fact, I am successfully writing a binary file to the RAM file system. I can then access the file with FTP, pull it to my PC and look at it using a hex editor. I am going to attempt to post my c code herein.

/*
 *  Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
 *
 *  This software contains proprietary and confidential information of Digi
 *  International Inc.  By accepting transfer of this copy, Recipient agrees
 *  to retain this software in confidence, to prevent disclosure to others,
 *  and to make no use of this software other than that for which it was
 *  delivered.  This is an unpublished copyrighted work of Digi International
 *  Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 *  prohibited.
 *
 *  Restricted Rights Legend
 *
 *  Use, duplication, or disclosure by the Government is subject to
 *  restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 *  Technical Data and Computer Software clause at DFARS 252.227-7031 or
 *  subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 *  Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 *  Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 * Description.
 * =======================================================================
 *  applicationStart() is the entry point for user applications.  This
 *  This function will be called after the kernel has started and the
 *  TCP/IP stack has loaded.  applicationTcpDown() is called periodically
 *  after the kernel has started while the system is waiting for the
 *  TCP/IP stack to start.
 *
 *
 *
 *
 * Edit Date/Ver   Edit Description
 * ==============  =======================================================
 *  02/07/06   JZW   Added ability to create FLASH file system even if
 *                   BSP_INCLUDE_FILESYSTEM_FOR_CLIBRARY is FALSE in bsp_fs.h
 *
 */


#include 
#include 
#include "appconf.h"
#include "sysAccess.h"
#include "fservapi.h"
#include "ftpsvrfs.h"
#include "netosIo.h"
#include "bsp_api.h"

#include "fs_api.h"
#include "fs.h"
#include "sockapi.h"



unsigned char myBinaryData [] =
{
		0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19
};

#define NUM_CHARACTERS (sizeof(myBinaryData)/sizeof(myBinaryData[0]))

#define MY_FILE_NAME "RAM0/my_binary_file.bin"


#define WANT_DEBUG_OUTPUT   (0)


static void MyErrorHandler(char * UserName, char * Password, struct sockaddr_storage * ipAddr, int Protocol, int ErrorCode)
{

    if ((UserName == NULL) || (Password == NULL) || (ipAddr))
    {
#if WANT_DEBUG_OUTPUT
        printf ("Found null pointer....exiting
");
#endif
        return;
    }

#if WANT_DEBUG_OUTPUT
    printf("User:%s, Pass:%s, proto:%d, err: %d
", UserName, Password, Protocol, ErrorCode);
#endif
}


/*
 *
 *  Function: void applicationTcpDown (void)
 *
 *  Description:
 *
 *      This routine will be called by the NET+OS root thread once every
 *      clock tick while it is waiting for the TCP/IP stack to come up.
 *      This function can increment a counter everytime it's called to
 *      keep track of how long we've been waiting for the stack to start.
 *      If we've been waiting too long, then this function can do something
 *      to handle the error.
 *
 *      This function will not be called once the stack has started.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

void applicationTcpDown (void)

{
    static int ticksPassed = 0;

    ticksPassed++;
/*
 * Code to handle error condition if the stack doesn't come up goes here.
 */
}




/*
 *
 *  Function: void applicationStart (void)
 *
 *  Description:
 *
 *      This routine is responsible for starting the user application.  It should
 *      create any threads or other resources the application needs.
 *
 *      ThreadX, the NET+OS device drivers, and the TCP/IP stack will be running
 *      when this function is called.
 *
 *  Parameters:
 *
 *      none
 *
 *  Return Values:
 *
 *      none
 *
 */

void applicationStart (void)
{
    //int status, fd;
	int status = 0;
    //char filedata[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

	FILE * theFP = NULL;
	int bytesWritten = 0;

    /******************************************************************
     *
     *  Setup two user accounts
     *
     *  Account dir0/dir0 can access group 1
     *  Account dir1/dir1 can access group 2
     *
     *  Don't forget, you can also use the root account
     */
    status = NAsetSysAccess (NASYSACC_ADD, "dir0", "dir0", (NASYSACC_FS_GROUP1_READ | NASYSACC_FS_GROUP1_WRITE | NASYSACC_LEVEL_RW), NULL);
    if (status != 0)
    {
        printf("APP: NASetSysAccess[%d]: username: dir0 password: dir0
", status);
    }

    status = NAsetSysAccess (NASYSACC_ADD, "dir1", "dir1", (NASYSACC_FS_GROUP2_READ | NASYSACC_FS_GROUP2_WRITE | NASYSACC_LEVEL_RW), NULL);
    if (status != 0)
    {
        printf("APP: NASetSysAccess[%d]: username: dir1 password: dir1
", status);
    }

    /*  Registers a callback for authentication failures.   */
    NARegisterTraceFailure (MyErrorHandler);

    /******************************************************************
     *
     *  Start the FTP server with the File System hooks
     */
    status = FSInitialize(5);
    if (status != NAFTPS_SUCCESS)
    {
        printf("APP: FSInitialize[%d]
", status);
        return;
    }

    status = FSInstallFileSystem("RAM0/");
    if (status != NAFTPS_SUCCESS)
    {
        printf("APP: FSInstallFileSystem[%d]
", status);
        return;
    }

    /* start ftp server */
    status = FSStartServer();
    if (status != NAFTPS_SUCCESS)
    {
        printf("APP: FSStartServer[%d]
", status);
        return;
    }


    /******************************************************************
     *
     *  Populate the /RAM0 file system with two directories and some files.
     */

    if (NABspFilesystemForCLib == 0)
    {
        printf ("BSP does not include file system for C library
");
        return;
    }


    printf("Starting my test
");

    // open a file for write binary
     theFP = fopen(MY_FILE_NAME, "wb");
     if(theFP == NULL)
     {
     	printf("Unable to open file reason %d
", getErrno());
     	return;
     }
     else
     {
     	printf("File opened
");
     }
     // try writing binary data to file
     printf("trying to write %d characters
", NUM_CHARACTERS);
     bytesWritten = fwrite(myBinaryData, 1, NUM_CHARACTERS, theFP);
     if((bytesWritten <= NUM_CHARACTERS) && (bytesWritten != 0))
     {
     	printf("Wrote %d characters
", bytesWritten);
     }
     else
     {
     	printf("Bytes written was %d error was %d
", bytesWritten, getErrno());
     }
     // close file
     fclose(theFP);

     printf("End of test
");

     tx_thread_suspend (tx_thread_identify ());

}

1 Like

Yes, thank you. This turned out to be an issue with the FILE* being overwritten. What I originally posted was a bit of an oversimplification. It turned out I had neither the flash filesystem (I really wanted to use FLASH0 instead of RAM0) nor the FTP server enabled in appservices.h. But, thank you for doing this test and posting the code, hopefully others will find it helpful in the future.

So, now, I’m onto the web interface for the device (using pBuilder, which is turning into a major PITA).