diff mbox series

[2/4] fatfs: add wrapper for FatFs

Message ID 20210318151632.2968-2-roland.gaudig-oss@weidmueller.com
State Changes Requested
Headers show
Series [1/4] fatfs: add FatFs library R0.14a by ChaN | expand

Commit Message

Roland Gaudig March 18, 2021, 3:16 p.m. UTC
From: Roland Gaudig <roland.gaudig@weidmueller.com>

Signed-off-by: Roland Gaudig <roland.gaudig@weidmueller.com>
---
 Kconfig                   |  1 +
 Makefile                  |  2 +-
 fatfs/Config.in           |  6 +++++
 fatfs/Makefile            |  3 +++
 fatfs/diskio.c            | 48 ++++++++++++++++++++-------------------
 fatfs/fat_fs.c            | 48 +++++++++++++++++++++++++++++++++++++++
 include/fatfs_interface.h | 13 +++++++++++
 7 files changed, 97 insertions(+), 24 deletions(-)
 create mode 100644 fatfs/Config.in
 create mode 100644 fatfs/Makefile
 create mode 100644 fatfs/fat_fs.c
 create mode 100644 include/fatfs_interface.h

Comments

Stefano Babic March 22, 2021, 2:27 p.m. UTC | #1
Hi Roland,

On 18.03.21 16:16, roland.gaudig-oss@weidmueller.com wrote:
> From: Roland Gaudig <roland.gaudig@weidmueller.com>
> 
> Signed-off-by: Roland Gaudig <roland.gaudig@weidmueller.com>
> ---
>   Kconfig                   |  1 +
>   Makefile                  |  2 +-
>   fatfs/Config.in           |  6 +++++
>   fatfs/Makefile            |  3 +++
>   fatfs/diskio.c            | 48 ++++++++++++++++++++-------------------
>   fatfs/fat_fs.c            | 48 +++++++++++++++++++++++++++++++++++++++
>   include/fatfs_interface.h | 13 +++++++++++
>   7 files changed, 97 insertions(+), 24 deletions(-)
>   create mode 100644 fatfs/Config.in
>   create mode 100644 fatfs/Makefile
>   create mode 100644 fatfs/fat_fs.c
>   create mode 100644 include/fatfs_interface.h
> 
> diff --git a/Kconfig b/Kconfig
> index 75f9eaa..83d2857 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -498,3 +498,4 @@ config ZSTD
>   
>   source parser/Config.in
>   source handlers/Config.in
> +source fatfs/Config.in
> diff --git a/Makefile b/Makefile
> index a1d185e..9231c41 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -359,7 +359,7 @@ include $(srctree)/Makefile.flags
>   # Defaults to vmlinux, but the arch makefile usually adds further targets
>   
>   objs-y		:= core handlers
> -libs-y		:= corelib mongoose parser suricatta bootloader
> +libs-y		:= corelib mongoose parser suricatta bootloader fatfs
>   bindings-y	:= bindings
>   tools-y		:= tools
>   
> diff --git a/fatfs/Config.in b/fatfs/Config.in
> new file mode 100644
> index 0000000..8d416f6
> --- /dev/null
> +++ b/fatfs/Config.in
> @@ -0,0 +1,6 @@
> +config FAT_FILESYSTEM
> +	bool "FAT file system creation support"
> +	depends on DISKFORMAT

I think this should be independent from DISKFORMAT. Yes, it is the main 
user (and maybe there won't be a second), but this is just a piece of 
generic code adding FATFS support. DISKFORMAT then depends on libfdisk, 
but the code in fatfs has no dependency. I think it is fine if the 
depends above is removed.

> +	default n
> +	help
> +	  Enable support for creating FAT file systems.
> diff --git a/fatfs/Makefile b/fatfs/Makefile
> new file mode 100644
> index 0000000..551528d
> --- /dev/null
> +++ b/fatfs/Makefile
> @@ -0,0 +1,3 @@
> +lib-$(CONFIG_FAT_FILESYSTEM) += diskio.o \
> +				fat_fs.o \
> +				ff.o
> diff --git a/fatfs/diskio.c b/fatfs/diskio.c
> index 1976add..479aec9 100644
> --- a/fatfs/diskio.c
> +++ b/fatfs/diskio.c
> @@ -21,37 +21,44 @@
>   
>   #define SECTOR_SIZE	512
>   
> -static int file_descriptor;
> -static char device_name[MAX_VOLNAME];
> -static bool init_status;
> -
> -int fatfs_init(char *device);
> -void fatfs_release(void);
> +static int file_descriptor = -1;
>   
>   
> +/*
> + * Extension to FatFs library: fatfs_init associates the fatfs library with
> + * a disk device file. It has to be called before using any FatFs API function.
> + */
>   int fatfs_init(char *device)
>   {
> -	if (strnlen(device_name, MAX_VOLNAME)) {
> +	if (file_descriptor >= 0) {
>   		ERROR("Called fatfs_init second time without fatfs_release");
>   		return -1;

This is what I asked before, so it is fine on my side.

>   	}
>   
> -	strncpy(device_name, device, sizeof(device_name));
> -	file_descriptor = open(device_name, O_RDWR);
> +	if (!device) {
> +		ERROR("Device name is NULL pointer");
> +		return -1;
> +	}
> +
> +	file_descriptor = open(device, O_RDWR);
>   
>   	if (file_descriptor < 0) {
> -		ERROR("Device %s cannot be opened: %s", device_name, strerror(errno));
> -		return -ENODEV;
> +		ERROR("Device %s cannot be opened: %s", device, strerror(errno));
> +		return -1;
>   	}
>   
>   	return 0;
>   }
>   
> +/*
> + * Extension to FatFs libary: fatfs_release closes a disk device.
> + */
>   void fatfs_release(void)
>   {
> -	(void)close(file_descriptor);
> -	memset(device_name, 0, MAX_VOLNAME);
> -	init_status = false;
> +	if (file_descriptor >= 0) {
> +		(void)close(file_descriptor);
> +		file_descriptor = -1;
> +	}
>   }
>   
>   DSTATUS disk_status(BYTE pdrv)
> @@ -59,10 +66,7 @@ DSTATUS disk_status(BYTE pdrv)
>   	DSTATUS status = 0;
>   	(void)pdrv;
>   
> -	if (!strnlen(device_name, MAX_VOLNAME))
> -		status |= STA_NODISK;
> -
> -	if (!init_status)
> +	if (file_descriptor < 0)
>   		status |= STA_NOINIT;
>   
>   	return status;
> @@ -70,8 +74,6 @@ DSTATUS disk_status(BYTE pdrv)
>   
>   DSTATUS disk_initialize(BYTE pdrv)
>   {
> -	init_status = true;
> -
>   	return disk_status(pdrv);
>   }
>   
> @@ -128,14 +130,14 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
>   		if (!buff)
>   			return RES_PARERR;
>   
> -		*(LBA_t*)buff = size;
> +		*(LBA_t *)buff = size;
>   		break;
>   	}
>   	case GET_SECTOR_SIZE:
>   		if (!buff)
>   			return RES_PARERR;
>   
> -		*(WORD*)buff = SECTOR_SIZE;
> +		*(WORD *)buff = SECTOR_SIZE;
>   		break;
>   	case GET_BLOCK_SIZE:
>   		/* Get erase block size of flash memories, return 1 if not a
> @@ -144,7 +146,7 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
>   		if (!buff)
>   			return RES_PARERR;
>   
> -		*(WORD*)buff = 1;
> +		*(WORD *)buff = 1;
>   		break;
>   	default:
>   		ERROR("cmd %d not implemented", cmd);
> diff --git a/fatfs/fat_fs.c b/fatfs/fat_fs.c
> new file mode 100644
> index 0000000..942e96e
> --- /dev/null
> +++ b/fatfs/fat_fs.c
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
> + * Roland Gaudig <roland.gaudig@weidmueller.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0-or-later
> + */
> +
> +#include <errno.h>
> +#include <stddef.h>
> +
> +#include <fatfs_interface.h>
> +#include <swupdate.h>
> +#include <util.h>
> +
> +#include "ff.h"
> +
> +
> +int fat_mkfs(char *device_name)
> +{
> +	if (fatfs_init(device_name))
> +		return -1;
> +
> +	void* working_buffer = malloc(FF_MAX_SS);
> +
> +	if (!working_buffer) {
> +		fatfs_release();
> +		return -ENOMEM;
> +	}
> +
> +	MKFS_PARM mkfs_parm = {
> +		.fmt = FM_ANY | FM_SFD,
> +		.au_size = 0,
> +		.align = 0,
> +		.n_fat = 0,
> +		.n_root = 0
> +	};
> +
> +	FRESULT result = f_mkfs("", &mkfs_parm, working_buffer, FF_MAX_SS);
> +	free(working_buffer);
> +
> +	if (result != FR_OK) {
> +		fatfs_release();
> +		return -1;
> +	}
> +
> +	fatfs_release();
> +	return 0;
> +}
> diff --git a/include/fatfs_interface.h b/include/fatfs_interface.h
> new file mode 100644
> index 0000000..a5d8ef7
> --- /dev/null
> +++ b/include/fatfs_interface.h
> @@ -0,0 +1,13 @@
> +/*
> + * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
> + * Roland Gaudig <roland.gaudig@weidmueller.com>
> + *
> + * SPDX-License-Identifier:     GPL-2.0-or-later
> + */
> +
> +#ifndef _FATFS_INTERFACE_H
> +#define _FATFS_INTERFACE_H
> +
> +extern int fat_mkfs(char *device_name);
> +
> +#endif
> 

Best regards,
Stefano Babic
Stefano Babic March 22, 2021, 2:42 p.m. UTC | #2
On 22.03.21 15:27, Stefano Babic wrote:
> Hi Roland,
> 
> On 18.03.21 16:16, roland.gaudig-oss@weidmueller.com wrote:
>> From: Roland Gaudig <roland.gaudig@weidmueller.com>
>>
>> Signed-off-by: Roland Gaudig <roland.gaudig@weidmueller.com>
>> ---
>>   Kconfig                   |  1 +
>>   Makefile                  |  2 +-
>>   fatfs/Config.in           |  6 +++++
>>   fatfs/Makefile            |  3 +++
>>   fatfs/diskio.c            | 48 ++++++++++++++++++++-------------------
>>   fatfs/fat_fs.c            | 48 +++++++++++++++++++++++++++++++++++++++
>>   include/fatfs_interface.h | 13 +++++++++++
>>   7 files changed, 97 insertions(+), 24 deletions(-)
>>   create mode 100644 fatfs/Config.in
>>   create mode 100644 fatfs/Makefile
>>   create mode 100644 fatfs/fat_fs.c
>>   create mode 100644 include/fatfs_interface.h
>>
>> diff --git a/Kconfig b/Kconfig
>> index 75f9eaa..83d2857 100644
>> --- a/Kconfig
>> +++ b/Kconfig
>> @@ -498,3 +498,4 @@ config ZSTD
>>   source parser/Config.in
>>   source handlers/Config.in
>> +source fatfs/Config.in
>> diff --git a/Makefile b/Makefile
>> index a1d185e..9231c41 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -359,7 +359,7 @@ include $(srctree)/Makefile.flags
>>   # Defaults to vmlinux, but the arch makefile usually adds further 
>> targets
>>   objs-y        := core handlers
>> -libs-y        := corelib mongoose parser suricatta bootloader
>> +libs-y        := corelib mongoose parser suricatta bootloader fatfs
>>   bindings-y    := bindings
>>   tools-y        := tools
>> diff --git a/fatfs/Config.in b/fatfs/Config.in
>> new file mode 100644
>> index 0000000..8d416f6
>> --- /dev/null
>> +++ b/fatfs/Config.in
>> @@ -0,0 +1,6 @@
>> +config FAT_FILESYSTEM
>> +    bool "FAT file system creation support"
>> +    depends on DISKFORMAT
> 
> I think this should be independent from DISKFORMAT. Yes, it is the main 
> user (and maybe there won't be a second), but this is just a piece of 
> generic code adding FATFS support. DISKFORMAT then depends on libfdisk, 
> but the code in fatfs has no dependency. I think it is fine if the 
> depends above is removed.

I have already changed my mind: it seems better how you implement it 
instead of my proposal - so discard this comment.

Regards,
Stefano Babic

> 
>> +    default n
>> +    help
>> +      Enable support for creating FAT file systems.
>> diff --git a/fatfs/Makefile b/fatfs/Makefile
>> new file mode 100644
>> index 0000000..551528d
>> --- /dev/null
>> +++ b/fatfs/Makefile
>> @@ -0,0 +1,3 @@
>> +lib-$(CONFIG_FAT_FILESYSTEM) += diskio.o \
>> +                fat_fs.o \
>> +                ff.o
>> diff --git a/fatfs/diskio.c b/fatfs/diskio.c
>> index 1976add..479aec9 100644
>> --- a/fatfs/diskio.c
>> +++ b/fatfs/diskio.c
>> @@ -21,37 +21,44 @@
>>   #define SECTOR_SIZE    512
>> -static int file_descriptor;
>> -static char device_name[MAX_VOLNAME];
>> -static bool init_status;
>> -
>> -int fatfs_init(char *device);
>> -void fatfs_release(void);
>> +static int file_descriptor = -1;
>> +/*
>> + * Extension to FatFs library: fatfs_init associates the fatfs 
>> library with
>> + * a disk device file. It has to be called before using any FatFs API 
>> function.
>> + */
>>   int fatfs_init(char *device)
>>   {
>> -    if (strnlen(device_name, MAX_VOLNAME)) {
>> +    if (file_descriptor >= 0) {
>>           ERROR("Called fatfs_init second time without fatfs_release");
>>           return -1;
> 
> This is what I asked before, so it is fine on my side.
> 
>>       }
>> -    strncpy(device_name, device, sizeof(device_name));
>> -    file_descriptor = open(device_name, O_RDWR);
>> +    if (!device) {
>> +        ERROR("Device name is NULL pointer");
>> +        return -1;
>> +    }
>> +
>> +    file_descriptor = open(device, O_RDWR);
>>       if (file_descriptor < 0) {
>> -        ERROR("Device %s cannot be opened: %s", device_name, 
>> strerror(errno));
>> -        return -ENODEV;
>> +        ERROR("Device %s cannot be opened: %s", device, 
>> strerror(errno));
>> +        return -1;
>>       }
>>       return 0;
>>   }
>> +/*
>> + * Extension to FatFs libary: fatfs_release closes a disk device.
>> + */
>>   void fatfs_release(void)
>>   {
>> -    (void)close(file_descriptor);
>> -    memset(device_name, 0, MAX_VOLNAME);
>> -    init_status = false;
>> +    if (file_descriptor >= 0) {
>> +        (void)close(file_descriptor);
>> +        file_descriptor = -1;
>> +    }
>>   }
>>   DSTATUS disk_status(BYTE pdrv)
>> @@ -59,10 +66,7 @@ DSTATUS disk_status(BYTE pdrv)
>>       DSTATUS status = 0;
>>       (void)pdrv;
>> -    if (!strnlen(device_name, MAX_VOLNAME))
>> -        status |= STA_NODISK;
>> -
>> -    if (!init_status)
>> +    if (file_descriptor < 0)
>>           status |= STA_NOINIT;
>>       return status;
>> @@ -70,8 +74,6 @@ DSTATUS disk_status(BYTE pdrv)
>>   DSTATUS disk_initialize(BYTE pdrv)
>>   {
>> -    init_status = true;
>> -
>>       return disk_status(pdrv);
>>   }
>> @@ -128,14 +130,14 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
>>           if (!buff)
>>               return RES_PARERR;
>> -        *(LBA_t*)buff = size;
>> +        *(LBA_t *)buff = size;
>>           break;
>>       }
>>       case GET_SECTOR_SIZE:
>>           if (!buff)
>>               return RES_PARERR;
>> -        *(WORD*)buff = SECTOR_SIZE;
>> +        *(WORD *)buff = SECTOR_SIZE;
>>           break;
>>       case GET_BLOCK_SIZE:
>>           /* Get erase block size of flash memories, return 1 if not a
>> @@ -144,7 +146,7 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
>>           if (!buff)
>>               return RES_PARERR;
>> -        *(WORD*)buff = 1;
>> +        *(WORD *)buff = 1;
>>           break;
>>       default:
>>           ERROR("cmd %d not implemented", cmd);
>> diff --git a/fatfs/fat_fs.c b/fatfs/fat_fs.c
>> new file mode 100644
>> index 0000000..942e96e
>> --- /dev/null
>> +++ b/fatfs/fat_fs.c
>> @@ -0,0 +1,48 @@
>> +/*
>> + * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
>> + * Roland Gaudig <roland.gaudig@weidmueller.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0-or-later
>> + */
>> +
>> +#include <errno.h>
>> +#include <stddef.h>
>> +
>> +#include <fatfs_interface.h>
>> +#include <swupdate.h>
>> +#include <util.h>
>> +
>> +#include "ff.h"
>> +
>> +
>> +int fat_mkfs(char *device_name)
>> +{
>> +    if (fatfs_init(device_name))
>> +        return -1;
>> +
>> +    void* working_buffer = malloc(FF_MAX_SS);
>> +
>> +    if (!working_buffer) {
>> +        fatfs_release();
>> +        return -ENOMEM;
>> +    }
>> +
>> +    MKFS_PARM mkfs_parm = {
>> +        .fmt = FM_ANY | FM_SFD,
>> +        .au_size = 0,
>> +        .align = 0,
>> +        .n_fat = 0,
>> +        .n_root = 0
>> +    };
>> +
>> +    FRESULT result = f_mkfs("", &mkfs_parm, working_buffer, FF_MAX_SS);
>> +    free(working_buffer);
>> +
>> +    if (result != FR_OK) {
>> +        fatfs_release();
>> +        return -1;
>> +    }
>> +
>> +    fatfs_release();
>> +    return 0;
>> +}
>> diff --git a/include/fatfs_interface.h b/include/fatfs_interface.h
>> new file mode 100644
>> index 0000000..a5d8ef7
>> --- /dev/null
>> +++ b/include/fatfs_interface.h
>> @@ -0,0 +1,13 @@
>> +/*
>> + * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
>> + * Roland Gaudig <roland.gaudig@weidmueller.com>
>> + *
>> + * SPDX-License-Identifier:     GPL-2.0-or-later
>> + */
>> +
>> +#ifndef _FATFS_INTERFACE_H
>> +#define _FATFS_INTERFACE_H
>> +
>> +extern int fat_mkfs(char *device_name);
>> +
>> +#endif
>>
> 
> Best regards,
> Stefano Babic
>
diff mbox series

Patch

diff --git a/Kconfig b/Kconfig
index 75f9eaa..83d2857 100644
--- a/Kconfig
+++ b/Kconfig
@@ -498,3 +498,4 @@  config ZSTD
 
 source parser/Config.in
 source handlers/Config.in
+source fatfs/Config.in
diff --git a/Makefile b/Makefile
index a1d185e..9231c41 100644
--- a/Makefile
+++ b/Makefile
@@ -359,7 +359,7 @@  include $(srctree)/Makefile.flags
 # Defaults to vmlinux, but the arch makefile usually adds further targets
 
 objs-y		:= core handlers
-libs-y		:= corelib mongoose parser suricatta bootloader
+libs-y		:= corelib mongoose parser suricatta bootloader fatfs
 bindings-y	:= bindings
 tools-y		:= tools
 
diff --git a/fatfs/Config.in b/fatfs/Config.in
new file mode 100644
index 0000000..8d416f6
--- /dev/null
+++ b/fatfs/Config.in
@@ -0,0 +1,6 @@ 
+config FAT_FILESYSTEM
+	bool "FAT file system creation support"
+	depends on DISKFORMAT
+	default n
+	help
+	  Enable support for creating FAT file systems.
diff --git a/fatfs/Makefile b/fatfs/Makefile
new file mode 100644
index 0000000..551528d
--- /dev/null
+++ b/fatfs/Makefile
@@ -0,0 +1,3 @@ 
+lib-$(CONFIG_FAT_FILESYSTEM) += diskio.o \
+				fat_fs.o \
+				ff.o
diff --git a/fatfs/diskio.c b/fatfs/diskio.c
index 1976add..479aec9 100644
--- a/fatfs/diskio.c
+++ b/fatfs/diskio.c
@@ -21,37 +21,44 @@ 
 
 #define SECTOR_SIZE	512
 
-static int file_descriptor;
-static char device_name[MAX_VOLNAME];
-static bool init_status;
-
-int fatfs_init(char *device);
-void fatfs_release(void);
+static int file_descriptor = -1;
 
 
+/*
+ * Extension to FatFs library: fatfs_init associates the fatfs library with
+ * a disk device file. It has to be called before using any FatFs API function.
+ */
 int fatfs_init(char *device)
 {
-	if (strnlen(device_name, MAX_VOLNAME)) {
+	if (file_descriptor >= 0) {
 		ERROR("Called fatfs_init second time without fatfs_release");
 		return -1;
 	}
 
-	strncpy(device_name, device, sizeof(device_name));
-	file_descriptor = open(device_name, O_RDWR);
+	if (!device) {
+		ERROR("Device name is NULL pointer");
+		return -1;
+	}
+
+	file_descriptor = open(device, O_RDWR);
 
 	if (file_descriptor < 0) {
-		ERROR("Device %s cannot be opened: %s", device_name, strerror(errno));
-		return -ENODEV;
+		ERROR("Device %s cannot be opened: %s", device, strerror(errno));
+		return -1;
 	}
 
 	return 0;
 }
 
+/*
+ * Extension to FatFs libary: fatfs_release closes a disk device.
+ */
 void fatfs_release(void)
 {
-	(void)close(file_descriptor);
-	memset(device_name, 0, MAX_VOLNAME);
-	init_status = false;
+	if (file_descriptor >= 0) {
+		(void)close(file_descriptor);
+		file_descriptor = -1;
+	}
 }
 
 DSTATUS disk_status(BYTE pdrv)
@@ -59,10 +66,7 @@  DSTATUS disk_status(BYTE pdrv)
 	DSTATUS status = 0;
 	(void)pdrv;
 
-	if (!strnlen(device_name, MAX_VOLNAME))
-		status |= STA_NODISK;
-
-	if (!init_status)
+	if (file_descriptor < 0)
 		status |= STA_NOINIT;
 
 	return status;
@@ -70,8 +74,6 @@  DSTATUS disk_status(BYTE pdrv)
 
 DSTATUS disk_initialize(BYTE pdrv)
 {
-	init_status = true;
-
 	return disk_status(pdrv);
 }
 
@@ -128,14 +130,14 @@  DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
 		if (!buff)
 			return RES_PARERR;
 
-		*(LBA_t*)buff = size;
+		*(LBA_t *)buff = size;
 		break;
 	}
 	case GET_SECTOR_SIZE:
 		if (!buff)
 			return RES_PARERR;
 
-		*(WORD*)buff = SECTOR_SIZE;
+		*(WORD *)buff = SECTOR_SIZE;
 		break;
 	case GET_BLOCK_SIZE:
 		/* Get erase block size of flash memories, return 1 if not a
@@ -144,7 +146,7 @@  DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
 		if (!buff)
 			return RES_PARERR;
 
-		*(WORD*)buff = 1;
+		*(WORD *)buff = 1;
 		break;
 	default:
 		ERROR("cmd %d not implemented", cmd);
diff --git a/fatfs/fat_fs.c b/fatfs/fat_fs.c
new file mode 100644
index 0000000..942e96e
--- /dev/null
+++ b/fatfs/fat_fs.c
@@ -0,0 +1,48 @@ 
+/*
+ * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
+ * Roland Gaudig <roland.gaudig@weidmueller.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0-or-later
+ */
+
+#include <errno.h>
+#include <stddef.h>
+
+#include <fatfs_interface.h>
+#include <swupdate.h>
+#include <util.h>
+
+#include "ff.h"
+
+
+int fat_mkfs(char *device_name)
+{
+	if (fatfs_init(device_name))
+		return -1;
+
+	void* working_buffer = malloc(FF_MAX_SS);
+
+	if (!working_buffer) {
+		fatfs_release();
+		return -ENOMEM;
+	}
+
+	MKFS_PARM mkfs_parm = {
+		.fmt = FM_ANY | FM_SFD,
+		.au_size = 0,
+		.align = 0,
+		.n_fat = 0,
+		.n_root = 0
+	};
+
+	FRESULT result = f_mkfs("", &mkfs_parm, working_buffer, FF_MAX_SS);
+	free(working_buffer);
+
+	if (result != FR_OK) {
+		fatfs_release();
+		return -1;
+	}
+
+	fatfs_release();
+	return 0;
+}
diff --git a/include/fatfs_interface.h b/include/fatfs_interface.h
new file mode 100644
index 0000000..a5d8ef7
--- /dev/null
+++ b/include/fatfs_interface.h
@@ -0,0 +1,13 @@ 
+/*
+ * Copyright (C) 2021 Weidmueller Interface GmbH & Co. KG
+ * Roland Gaudig <roland.gaudig@weidmueller.com>
+ *
+ * SPDX-License-Identifier:     GPL-2.0-or-later
+ */
+
+#ifndef _FATFS_INTERFACE_H
+#define _FATFS_INTERFACE_H
+
+extern int fat_mkfs(char *device_name);
+
+#endif