9 changed files with 631 additions and 37 deletions
@ -0,0 +1,207 @@
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
/*
|
||||
ArduPilot filesystem interface for ROMFS |
||||
*/ |
||||
#include "AP_Filesystem.h" |
||||
#include "AP_Filesystem_ROMFS.h" |
||||
#include <AP_HAL/AP_HAL.h> |
||||
#include <AP_Math/AP_Math.h> |
||||
#include <AP_ROMFS/AP_ROMFS.h> |
||||
|
||||
#if defined(HAL_HAVE_AP_ROMFS_EMBEDDED_H) && HAVE_FILESYSTEM_SUPPORT |
||||
|
||||
int AP_Filesystem_ROMFS::open(const char *fname, int flags) |
||||
{ |
||||
uint8_t idx; |
||||
for (idx=0; idx<max_open_file; idx++) { |
||||
if (file[idx].data == nullptr) { |
||||
break; |
||||
} |
||||
} |
||||
if (idx == max_open_file) { |
||||
errno = ENFILE; |
||||
return -1; |
||||
} |
||||
if (file[idx].data != nullptr) { |
||||
errno = EBUSY; |
||||
return -1; |
||||
} |
||||
file[idx].data = AP_ROMFS::find_decompress(fname, file[idx].size); |
||||
if (file[idx].data == nullptr) { |
||||
errno = ENOENT; |
||||
return -1; |
||||
} |
||||
file[idx].ofs = 0; |
||||
return idx; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::close(int fd) |
||||
{ |
||||
if (fd < 0 || fd >= max_open_file || file[fd].data == nullptr) { |
||||
errno = EBADF; |
||||
return -1; |
||||
} |
||||
AP_ROMFS::free(file[fd].data); |
||||
file[fd].data = nullptr; |
||||
return 0; |
||||
} |
||||
|
||||
ssize_t AP_Filesystem_ROMFS::read(int fd, void *buf, size_t count) |
||||
{ |
||||
if (fd < 0 || fd >= max_open_file || file[fd].data == nullptr) { |
||||
errno = EBADF; |
||||
return -1; |
||||
} |
||||
count = MIN(file[fd].size - file[fd].ofs, count); |
||||
if (count == 0) { |
||||
return 0; |
||||
} |
||||
memcpy(buf, &file[fd].data[file[fd].ofs], count); |
||||
file[fd].ofs += count; |
||||
return count; |
||||
} |
||||
|
||||
ssize_t AP_Filesystem_ROMFS::write(int fd, const void *buf, size_t count) |
||||
{ |
||||
errno = EROFS; |
||||
return -1; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::fsync(int fd) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
off_t AP_Filesystem_ROMFS::lseek(int fd, off_t offset, int seek_from) |
||||
{ |
||||
if (fd < 0 || fd >= max_open_file || file[fd].data == nullptr) { |
||||
errno = EBADF; |
||||
return -1; |
||||
} |
||||
switch (seek_from) { |
||||
case SEEK_SET: |
||||
file[fd].ofs = MIN(file[fd].size, offset); |
||||
break; |
||||
case SEEK_CUR: |
||||
file[fd].ofs = MIN(file[fd].size, offset+file[fd].ofs); |
||||
break; |
||||
case SEEK_END: |
||||
file[fd].ofs = file[fd].size; |
||||
break; |
||||
} |
||||
return file[fd].ofs; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::stat(const char *name, struct stat *stbuf) |
||||
{ |
||||
uint32_t size; |
||||
const uint8_t *data = AP_ROMFS::find_decompress(name, size); |
||||
if (data == nullptr) { |
||||
errno = ENOENT; |
||||
return -1; |
||||
} |
||||
AP_ROMFS::free(data); |
||||
memset(stbuf, 0, sizeof(*stbuf)); |
||||
stbuf->st_size = size; |
||||
return 0; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::unlink(const char *pathname) |
||||
{ |
||||
errno = EROFS; |
||||
return -1; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::mkdir(const char *pathname) |
||||
{ |
||||
errno = EROFS; |
||||
return -1; |
||||
} |
||||
|
||||
void *AP_Filesystem_ROMFS::opendir(const char *pathname) |
||||
{ |
||||
uint8_t idx; |
||||
for (idx=0; idx<max_open_dir; idx++) { |
||||
if (dir[idx].path == nullptr) { |
||||
break; |
||||
} |
||||
} |
||||
if (idx == max_open_dir) { |
||||
errno = ENFILE; |
||||
return nullptr; |
||||
} |
||||
dir[idx].ofs = 0; |
||||
dir[idx].path = strdup(pathname); |
||||
if (!dir[idx].path) { |
||||
return nullptr; |
||||
} |
||||
return (void*)&dir[idx]; |
||||
} |
||||
|
||||
struct dirent *AP_Filesystem_ROMFS::readdir(void *dirp) |
||||
{ |
||||
uint32_t idx = ((rdir*)dirp) - &dir[0]; |
||||
if (idx >= max_open_dir) { |
||||
errno = EBADF; |
||||
return nullptr; |
||||
} |
||||
const char *name = AP_ROMFS::dir_list(dir[idx].path, dir[idx].ofs); |
||||
if (!name) { |
||||
return nullptr; |
||||
} |
||||
const uint32_t plen = strlen(dir[idx].path); |
||||
if (strncmp(name, dir[idx].path, plen) != 0 || name[plen] != '/') { |
||||
return nullptr; |
||||
} |
||||
name += plen + 1; |
||||
dir[idx].de.d_type = DT_REG; |
||||
strncpy(dir[idx].de.d_name, name, sizeof(dir[idx].de.d_name)); |
||||
return &dir[idx].de; |
||||
} |
||||
|
||||
int AP_Filesystem_ROMFS::closedir(void *dirp) |
||||
{ |
||||
uint32_t idx = ((rdir *)dirp) - &dir[0]; |
||||
if (idx >= max_open_dir) { |
||||
errno = EBADF; |
||||
return -1; |
||||
} |
||||
free(dir[idx].path); |
||||
dir[idx].path = nullptr; |
||||
return 0; |
||||
} |
||||
|
||||
// return free disk space in bytes
|
||||
int64_t AP_Filesystem_ROMFS::disk_free(const char *path) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
// return total disk space in bytes
|
||||
int64_t AP_Filesystem_ROMFS::disk_space(const char *path) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
set mtime on a file |
||||
*/ |
||||
bool AP_Filesystem_ROMFS::set_mtime(const char *filename, const time_t mtime_sec) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
#endif // HAL_HAVE_AP_ROMFS_EMBEDDED_H
|
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include "AP_Filesystem_backend.h" |
||||
|
||||
#if HAVE_FILESYSTEM_SUPPORT |
||||
|
||||
class AP_Filesystem_ROMFS : public AP_Filesystem_Backend |
||||
{ |
||||
public: |
||||
// functions that closely match the equivalent posix calls
|
||||
int open(const char *fname, int flags) override; |
||||
int close(int fd) override; |
||||
ssize_t read(int fd, void *buf, size_t count) override; |
||||
ssize_t write(int fd, const void *buf, size_t count) override; |
||||
int fsync(int fd) override; |
||||
off_t lseek(int fd, off_t offset, int whence) override; |
||||
int stat(const char *pathname, struct stat *stbuf) override; |
||||
int unlink(const char *pathname) override; |
||||
int mkdir(const char *pathname) override; |
||||
void *opendir(const char *pathname) override; |
||||
struct dirent *readdir(void *dirp) override; |
||||
int closedir(void *dirp) override; |
||||
|
||||
// return free disk space in bytes, -1 on error
|
||||
int64_t disk_free(const char *path) override; |
||||
|
||||
// return total disk space in bytes, -1 on error
|
||||
int64_t disk_space(const char *path) override; |
||||
|
||||
// set modification time on a file
|
||||
bool set_mtime(const char *filename, const time_t mtime_sec) override; |
||||
|
||||
private: |
||||
// only allow up to 4 files at a time
|
||||
static constexpr uint8_t max_open_file = 4; |
||||
static constexpr uint8_t max_open_dir = 4; |
||||
struct rfile { |
||||
const uint8_t *data; |
||||
uint32_t size; |
||||
uint32_t ofs; |
||||
} file[max_open_file]; |
||||
|
||||
// allow up to 4 directory opens
|
||||
struct rdir { |
||||
char *path; |
||||
uint16_t ofs; |
||||
struct dirent de; |
||||
} dir[max_open_dir]; |
||||
}; |
||||
|
||||
#endif // HAVE_FILESYSTEM_SUPPORT
|
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
This program is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
/*
|
||||
ArduPilot filesystem backend interface. |
||||
*/ |
||||
#pragma once |
||||
|
||||
#include <stdint.h> |
||||
#include <AP_HAL/AP_HAL_Boards.h> |
||||
|
||||
#include "AP_Filesystem_Available.h" |
||||
|
||||
#if HAVE_FILESYSTEM_SUPPORT |
||||
class AP_Filesystem_Backend { |
||||
|
||||
public: |
||||
// functions that closely match the equivalent posix calls
|
||||
virtual int open(const char *fname, int flags) = 0; |
||||
virtual int close(int fd) = 0; |
||||
virtual ssize_t read(int fd, void *buf, size_t count) = 0; |
||||
virtual ssize_t write(int fd, const void *buf, size_t count) = 0; |
||||
virtual int fsync(int fd) = 0; |
||||
virtual off_t lseek(int fd, off_t offset, int whence) = 0; |
||||
virtual int stat(const char *pathname, struct stat *stbuf) = 0; |
||||
virtual int unlink(const char *pathname) = 0; |
||||
virtual int mkdir(const char *pathname) = 0; |
||||
virtual void *opendir(const char *pathname) = 0; |
||||
virtual struct dirent *readdir(void *dirp) = 0; |
||||
virtual int closedir(void *dirp) = 0; |
||||
|
||||
// return free disk space in bytes, -1 on error
|
||||
virtual int64_t disk_free(const char *path) = 0; |
||||
|
||||
// return total disk space in bytes, -1 on error
|
||||
virtual int64_t disk_space(const char *path) = 0; |
||||
|
||||
// set modification time on a file
|
||||
virtual bool set_mtime(const char *filename, const time_t mtime_sec) = 0; |
||||
}; |
||||
|
||||
#endif // HAVE_FILESYSTEM_SUPPORT
|
Loading…
Reference in new issue