Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Filesystem/AP_Filesystem_Sys.cpp
Views: 1798
// 2 or 3 structures, select one that is before target point, closest to target12/*3This program is free software: you can redistribute it and/or modify4it under the terms of the GNU General Public License as published by5the Free Software Foundation, either version 3 of the License, or6(at your option) any later version.78This program is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11GNU General Public License for more details.1213You should have received a copy of the GNU General Public License14along with this program. If not, see <http://www.gnu.org/licenses/>.15*/16/*17ArduPilot filesystem interface for system information18*/19#include "AP_Filesystem.h"20#include "AP_Filesystem_Sys.h"2122#if AP_FILESYSTEM_SYS_ENABLED2324#include <AP_Math/AP_Math.h>25#include <AP_CANManager/AP_CANManager.h>26#include <AP_Scheduler/AP_Scheduler.h>27#include <AP_Common/ExpandingString.h>2829extern const AP_HAL::HAL& hal;3031struct SysFileList {32const char* name;33};3435static const SysFileList sysfs_file_list[] = {36{"threads.txt"},37{"tasks.txt"},38{"dma.txt"},39{"memory.txt"},40{"uarts.txt"},41{"timers.txt"},42#if HAL_MAX_CAN_PROTOCOL_DRIVERS43{"can_log.txt"},44#endif45#if HAL_NUM_CAN_IFACES > 046{"can0_stats.txt"},47{"can1_stats.txt"},48#endif49#if !defined(HAL_BOOTLOADER_BUILD) && (defined(STM32F7) || defined(STM32H7))50{"persistent.parm"},51#endif52{"crash_dump.bin"},53{"storage.bin"},54#if AP_FILESYSTEM_SYS_FLASH_ENABLED55{"flash.bin"},56#endif57};5859int8_t AP_Filesystem_Sys::file_in_sysfs(const char *fname) {60for (uint8_t i = 0; i < ARRAY_SIZE(sysfs_file_list); i++) {61if (strcmp(fname, sysfs_file_list[i].name) == 0) {62return i;63}64}65return -1;66}6768int AP_Filesystem_Sys::open(const char *fname, int flags, bool allow_absolute_paths)69{70if ((flags & O_ACCMODE) != O_RDONLY) {71errno = EROFS;72return -1;73}74uint8_t idx;75for (idx=0; idx<max_open_file; idx++) {76if (!file[idx].open) {77break;78}79}80if (idx == max_open_file) {81errno = ENFILE;82return -1;83}84struct rfile &r = file[idx];85r.str = NEW_NOTHROW ExpandingString;86if (r.str == nullptr) {87errno = ENOMEM;88return -1;89}9091// This ensure that whenever new sys file is added its also added to list above92int8_t pos = file_in_sysfs(fname);93if (pos < 0) {94delete r.str;95r.str = nullptr;96errno = ENOENT;97return -1;98}99100if (strcmp(fname, "threads.txt") == 0) {101hal.util->thread_info(*r.str);102}103#if AP_SCHEDULER_ENABLED104if (strcmp(fname, "tasks.txt") == 0) {105AP::scheduler().task_info(*r.str);106}107#endif108if (strcmp(fname, "dma.txt") == 0) {109hal.util->dma_info(*r.str);110}111if (strcmp(fname, "memory.txt") == 0) {112hal.util->mem_info(*r.str);113}114#if HAL_UART_STATS_ENABLED115if (strcmp(fname, "uarts.txt") == 0) {116hal.util->uart_info(*r.str);117}118#endif119if (strcmp(fname, "timers.txt") == 0) {120hal.util->timer_info(*r.str);121}122#if HAL_CANMANAGER_ENABLED123if (strcmp(fname, "can_log.txt") == 0) {124AP::can().log_retrieve(*r.str);125}126#endif127#if HAL_NUM_CAN_IFACES > 0128int8_t can_stats_num = -1;129if (strcmp(fname, "can0_stats.txt") == 0) {130can_stats_num = 0;131} else if (strcmp(fname, "can1_stats.txt") == 0) {132can_stats_num = 1;133}134if (can_stats_num != -1 && can_stats_num < HAL_NUM_CAN_IFACES) {135if (hal.can[can_stats_num] != nullptr) {136hal.can[can_stats_num]->get_stats(*r.str);137}138}139#endif140if (strcmp(fname, "persistent.parm") == 0) {141hal.util->load_persistent_params(*r.str);142}143#if AP_CRASHDUMP_ENABLED144if (strcmp(fname, "crash_dump.bin") == 0) {145r.str->set_buffer((char*)hal.util->last_crash_dump_ptr(), hal.util->last_crash_dump_size(), hal.util->last_crash_dump_size());146}147#endif148if (strcmp(fname, "storage.bin") == 0) {149// we don't want to store the contents of storage.bin150// we read directly from the storage driver151void *ptr = nullptr;152size_t size = 0;153if (hal.storage->get_storage_ptr(ptr, size)) {154r.str->set_buffer((char*)ptr, size, size);155}156}157#if AP_FILESYSTEM_SYS_FLASH_ENABLED158if (strcmp(fname, "flash.bin") == 0) {159void *ptr = (void*)0x08000000;160const size_t size = BOARD_FLASH_SIZE*1024;161r.str->set_buffer((char*)ptr, size, size);162}163#endif164165if (r.str->get_length() == 0) {166errno = r.str->has_failed_allocation()?ENOMEM:ENOENT;167delete r.str;168r.str = nullptr;169return -1;170}171r.file_ofs = 0;172r.open = true;173return idx;174}175176int AP_Filesystem_Sys::close(int fd)177{178if (fd < 0 || fd >= max_open_file || !file[fd].open) {179errno = EBADF;180return -1;181}182struct rfile &r = file[fd];183r.open = false;184delete r.str;185r.str = nullptr;186return 0;187}188189int32_t AP_Filesystem_Sys::read(int fd, void *buf, uint32_t count)190{191if (fd < 0 || fd >= max_open_file || !file[fd].open) {192errno = EBADF;193return -1;194}195struct rfile &r = file[fd];196count = MIN(count, r.str->get_length() - r.file_ofs);197memcpy(buf, &r.str->get_string()[r.file_ofs], count);198199r.file_ofs += count;200return count;201}202203int32_t AP_Filesystem_Sys::lseek(int fd, int32_t offset, int seek_from)204{205if (fd < 0 || fd >= max_open_file || !file[fd].open) {206errno = EBADF;207return -1;208}209struct rfile &r = file[fd];210switch (seek_from) {211case SEEK_SET:212r.file_ofs = MIN(offset, int32_t(r.str->get_length()));213break;214case SEEK_CUR:215r.file_ofs = MIN(r.str->get_length(), offset+r.file_ofs);216break;217case SEEK_END:218errno = EINVAL;219return -1;220}221return r.file_ofs;222}223224void *AP_Filesystem_Sys::opendir(const char *pathname)225{226if (strlen(pathname) > 0) {227// no sub directories228errno = ENOENT;229return nullptr;230}231DirReadTracker *dtracker = NEW_NOTHROW DirReadTracker;232if (dtracker == nullptr) {233errno = ENOMEM;234return nullptr;235}236return dtracker;237}238239struct dirent *AP_Filesystem_Sys::readdir(void *dirp)240{241DirReadTracker* dtracker = ((DirReadTracker*)dirp);242if (dtracker->file_offset >= ARRAY_SIZE(sysfs_file_list)) {243// we have reached end of list244return nullptr;245}246#if AP_FILESYSTEM_HAVE_DIRENT_DTYPE247dtracker->curr_file.d_type = DT_REG;248#endif249size_t max_length = ARRAY_SIZE(dtracker->curr_file.d_name);250strncpy_noterm(dtracker->curr_file.d_name, sysfs_file_list[dtracker->file_offset].name, max_length);251dtracker->file_offset++;252return &dtracker->curr_file;253}254255int AP_Filesystem_Sys::closedir(void *dirp)256{257if (dirp == nullptr) {258errno = EINVAL;259return -1;260}261delete (DirReadTracker*)dirp;262return 0;263}264265int AP_Filesystem_Sys::stat(const char *pathname, struct stat *stbuf)266{267if (pathname == nullptr || stbuf == nullptr || (strlen(pathname) == 0)) {268errno = EINVAL;269return -1;270}271memset(stbuf, 0, sizeof(*stbuf));272if (strlen(pathname) == 1 && pathname[0] == '/') {273stbuf->st_size = 0; // just a placeholder value274return 0;275}276const char *pathname_noslash = pathname;277if (pathname[0] == '/') {278pathname_noslash = &pathname[1];279}280int8_t pos = file_in_sysfs(pathname_noslash);281if (pos < 0) {282errno = ENOENT;283return -1;284}285// give a fixed size for stat. It is too expensive to286// read every file for a directory listing287if (strcmp(pathname_noslash, "storage.bin") == 0) {288stbuf->st_size = HAL_STORAGE_SIZE;289#if AP_CRASHDUMP_ENABLED290} else if (strcmp(pathname_noslash, "crash_dump.bin") == 0) {291stbuf->st_size = hal.util->last_crash_dump_size();292#endif293} else {294stbuf->st_size = 100000;295}296return 0;297}298299#endif // AP_FILESYSTEM_SYS_ENABLED300301302