M image/user/db/settings_v2_002.sql => image/user/db/settings_v2_002.sql +1 -1
@@ 13,7 13,7 @@ INSERT OR IGNORE INTO settings_tab (path, value) VALUES
('gs_lock_pass_hash', '3333'),
('gs_lock_time', '30000'),
('gs_display_language', 'English'),
- ('gs_input_language', 'English');
+ ('gs_input_language', 'English'),
('bt_state', '0'),
('bt_device_visibility', '0'),
('bt_device_name', 'PurePhone'),
M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.c +3 -21
@@ 57,15 57,6 @@
inline static status_t MMC_SelectCard(mmc_card_t *card, bool isSelected);
/*!
- * @brief Wait write process complete.
- *
- * @param card Card descriptor.
- * @retval kStatus_Timeout Operation timeout.
- * @retval kStatus_Success Operate successfully.
- */
-static status_t MMC_WaitWriteComplete(mmc_card_t *card);
-
-/*!
* @brief Send SET_BLOCK_COUNT command.
*
* @param card Card descriptor.
@@ 149,15 140,6 @@ static void MMC_DecodeCsd(mmc_card_t *card, uint32_t *rawCsd);
static void MMC_SetMaxFrequency(mmc_card_t *card);
/*!
- * @brief Set erase unit size of the card
- *
- * @param card Card descriptor.
- * @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure Extended CSD failed.
- * @retval kStatus_Success Operate successfully.
- */
-static status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card);
-
-/*!
* @brief Send SWITCH command to set the specific byte in Extended CSD.
*
* Example:
@@ 524,7 506,7 @@ static status_t MMC_Transfer(mmc_card_t *card, SDMMCHOST_TRANSFER *content, uint
return error;
}
-static status_t MMC_WaitWriteComplete(mmc_card_t *card)
+status_t MMC_WaitWriteComplete(mmc_card_t *card)
{
assert(card);
@@ 825,8 807,8 @@ static void MMC_SetMaxFrequency(mmc_card_t *card)
card->busClock_Hz = SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, maxBusClock_Hz);
}
-static status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card) __attribute__((used));
-static status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card)
+status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card) __attribute__((used));
+status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card)
{
assert(card);
M module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h => module-bsp/board/rt1051/bsp/eMMC/fsl_mmc.h +18 -0
@@ 338,6 338,24 @@ extern "C"
*/
status_t MMC_SetGeneralPurposePartitioning(mmc_card_t *card, mmc_access_partition_t partition, uint32_t size);
+ /*!
+ * @brief Wait write process complete.
+ *
+ * @param card Card descriptor.
+ * @retval kStatus_Timeout Operation timeout.
+ * @retval kStatus_Success Operate successfully.
+ */
+ status_t MMC_WaitWriteComplete(mmc_card_t *card);
+
+ /*!
+ * @brief Set erase unit size of the card
+ *
+ * @param card Card descriptor.
+ * @retval kStatus_SDMMC_ConfigureExtendedCsdFailed Configure Extended CSD failed.
+ * @retval kStatus_Success Operate successfully.
+ */
+ status_t MMC_SetMaxEraseUnitSize(mmc_card_t *card);
+
/* @} */
#if defined(__cplusplus)
}
A module-vfs/board/rt1051/purefs/include/purefs/blkdev/disk_emmc.hpp => module-vfs/board/rt1051/purefs/include/purefs/blkdev/disk_emmc.hpp +42 -0
@@ 0,0 1,42 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <purefs/blkdev/disk.hpp>
+#include <bsp/common.hpp>
+
+#include "board/rt1051/bsp/eMMC/fsl_mmc.h"
+
+#include <mutex.hpp>
+
+#if !defined(TARGET_RT1051)
+static_assert(false, "Unsupported target.");
+#endif
+
+namespace purefs::blkdev
+{
+ class disk_emmc final : public disk
+ {
+ public:
+ static constexpr status_t statusBlkDevSuccess = 0;
+ static constexpr status_t statusBlkDevFail = -1;
+
+ disk_emmc();
+
+ auto probe(unsigned flags) -> int override;
+ auto cleanup() -> int override;
+ auto write(const void *buf, sector_t lba, std::size_t count) -> int override;
+ auto read(void *buf, sector_t lba, std::size_t count) -> int override;
+ auto sync() -> int override;
+ auto status() const -> media_status override;
+ auto get_info(info_type what) const -> scount_t override;
+ auto erase(sector_t lba, std::size_t count) -> int override;
+
+ private:
+ status_t initStatus = kStatus_Success;
+
+ mmc_card_t mmcCard;
+ mutable cpp_freertos::MutexRecursive mutex;
+ };
+} // namespace purefs::blkdev
A module-vfs/board/rt1051/purefs/src/blkdev/disk_emmc.cpp => module-vfs/board/rt1051/purefs/src/blkdev/disk_emmc.cpp +130 -0
@@ 0,0 1,130 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <purefs/blkdev/disk_emmc.hpp>
+#include <unistd.h>
+#include <cstring>
+#include <task.h>
+
+namespace purefs::blkdev
+{
+ disk_emmc::disk_emmc()
+ {
+ mmcCard.busWidth = kMMC_DataBusWidth8bit;
+ mmcCard.busTiming = kMMC_HighSpeedTiming;
+ mmcCard.enablePreDefinedBlockCount = true;
+ mmcCard.host.base = USDHC2;
+ mmcCard.host.sourceClock_Hz = GetPerphSourceClock(PerphClock_USDHC2);
+ }
+
+ auto disk_emmc::probe(unsigned int flags) -> int
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ auto err = MMC_Init(&mmcCard);
+ if (err != kStatus_Success) {
+ initStatus = err;
+ return initStatus;
+ }
+ err = MMC_SetMaxEraseUnitSize(&mmcCard);
+ if (err != kStatus_Success) {
+ initStatus = err;
+ return initStatus;
+ }
+ return statusBlkDevSuccess;
+ }
+
+ auto disk_emmc::cleanup() -> int
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ if (!mmcCard.isHostReady) {
+ return statusBlkDevFail;
+ }
+ MMC_Deinit(&mmcCard);
+ return statusBlkDevSuccess;
+ }
+
+ auto disk_emmc::write(const void *buf, sector_t lba, std::size_t count) -> int
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ if (!mmcCard.isHostReady || buf == nullptr) {
+ return statusBlkDevFail;
+ }
+ auto err = MMC_WriteBlocks(&mmcCard, static_cast<const uint8_t *>(buf), lba, count);
+ if (err != kStatus_Success) {
+ return err;
+ }
+ return statusBlkDevSuccess;
+ }
+
+ auto disk_emmc::erase(sector_t lba, std::size_t count) -> int
+ {
+ // temporarily commented out until erase is tested
+ /* cpp_freertos::LockGuard lock(mutex);
+ if (!mmcCard.isHostReady) {
+ return statusBlkDevFail;
+ }
+
+ auto err = MMC_EraseGroups(&mmcCard, lba, lba + count);
+ if (err != kStatus_Success) {
+ return err;
+ } */
+ return statusBlkDevSuccess;
+ }
+ auto disk_emmc::read(void *buf, sector_t lba, std::size_t count) -> int
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ if (!mmcCard.isHostReady || buf == nullptr) {
+ return statusBlkDevFail;
+ }
+ auto err = MMC_ReadBlocks(&mmcCard, static_cast<uint8_t *>(buf), lba, count);
+ if (err != kStatus_Success) {
+ return err;
+ }
+ return statusBlkDevSuccess;
+ }
+ auto disk_emmc::sync() -> int
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ if (!mmcCard.isHostReady) {
+ return statusBlkDevFail;
+ }
+ // Wait for the card's buffer to become empty
+ while ((GET_SDMMCHOST_STATUS(mmcCard.host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) {
+ taskYIELD();
+ }
+
+ if (kStatus_Success != MMC_WaitWriteComplete(&mmcCard)) {
+ return kStatus_SDMMC_WaitWriteCompleteFailed;
+ }
+ return statusBlkDevSuccess;
+ }
+ auto disk_emmc::status() const -> media_status
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ if (initStatus != kStatus_Success) {
+ return media_status::error;
+ }
+ if (!mmcCard.isHostReady) {
+ return media_status::uninit;
+ }
+ if ((mmcCard.csd.flags & kMMC_CsdPermanentWriteProtectFlag) ||
+ (mmcCard.csd.flags & kMMC_CsdTemporaryWriteProtectFlag)) {
+ return media_status::wprotect;
+ }
+ return media_status::healthly;
+ }
+
+ auto disk_emmc::get_info(info_type what) const -> scount_t
+ {
+ cpp_freertos::LockGuard lock(mutex);
+ switch (what) {
+ case info_type::sector_size:
+ return mmcCard.blockSize;
+ case info_type::sector_count:
+ return mmcCard.userPartitionBlocks;
+ case info_type::erase_block:
+ return mmcCard.eraseGroupBlocks;
+ }
+ return -1;
+ }
+} // namespace purefs::blkdev
M module-vfs/board/rt1051/purefs/src/vfs_subsystem_internal.cpp => module-vfs/board/rt1051/purefs/src/vfs_subsystem_internal.cpp +2 -2
@@ 3,12 3,12 @@
#include <purefs/vfs_subsystem_internal.hpp>
#include <purefs/blkdev/disk_manager.hpp>
+#include <purefs/blkdev/disk_emmc.hpp>
namespace purefs::subsystem::internal
{
auto create_default_block_device() -> std::shared_ptr<blkdev::disk>
{
- // TODO: implement for rt1051
- return nullptr;
+ return std::make_shared<purefs::blkdev::disk_emmc>();
}
} // namespace purefs::subsystem::internal
M module-vfs/include/internal/purefs/blkdev/disk_handle.hpp => module-vfs/include/internal/purefs/blkdev/disk_handle.hpp +1 -1
@@ 30,7 30,7 @@ namespace purefs::blkdev::internal
{
return m_partition;
}
- auto has_partition() const noexcept
+ auto has_partition() const noexcept -> bool
{
return m_partition != no_parition;
}
M module-vfs/src/newlib/vfs_io_syscalls.cpp => module-vfs/src/newlib/vfs_io_syscalls.cpp +1 -1
@@ 120,7 120,7 @@ namespace vfsn::internal::syscalls
}
const auto ret = vfs->getcwd();
const auto slen = ret.copy(buf, size);
- if (size < slen) {
+ if (size >= slen) {
buf[slen] = '\0';
}
return buf;
M module-vfs/src/purefs/blkdev/disk_manager.cpp => module-vfs/src/purefs/blkdev/disk_manager.cpp +2 -2
@@ 36,7 36,7 @@ namespace purefs::blkdev
cpp_freertos::LockGuard _lck(*m_lock);
const auto ret = m_dev_map.find(std::string(device_name));
if (ret != std::end(m_dev_map)) {
- LOG_ERROR("Disc: %.*s already registered.", int(device_name.length()), device_name.data());
+ LOG_ERROR("Disc: %s already registered.", std::string(device_name).c_str());
return -EEXIST;
}
else {
@@ 54,7 54,7 @@ namespace purefs::blkdev
cpp_freertos::LockGuard _lck(*m_lock);
auto it = m_dev_map.find(std::string(device_name));
if (it == std::end(m_dev_map)) {
- LOG_ERROR("Disc: %.*s doesn't exists in manager.", int(device_name.length()), device_name.data());
+ LOG_ERROR("Disc: %s doesn't exists in manager.", std::string(device_name).c_str());
return -ENOENT;
}
auto ret = it->second->cleanup();
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +6 -6
@@ 36,7 36,7 @@ namespace purefs::fs
cpp_freertos::LockGuard _lck(*m_lock);
const auto it = m_fstypes.find(std::string(fsname));
if (it != std::end(m_fstypes)) {
- LOG_ERROR("Disc: %.*s already registered.", int(fsname.length()), fsname.data());
+ LOG_ERROR("Disc: %s already registered.", std::string(fsname).c_str());
return -EEXIST;
}
else {
@@ 59,7 59,7 @@ namespace purefs::fs
return -ENOENT;
}
if (it->second->mount_count() > 0) {
- LOG_ERROR("VFS: fileystem %.*s is already used", int(fsname.length()), fsname.data());
+ LOG_ERROR("VFS: fileystem %s is already used", std::string(fsname).c_str());
return -EBUSY;
}
m_fstypes.erase(it);
@@ 89,13 89,13 @@ namespace purefs::fs
return {};
}
else {
- LOG_ERROR("VFS: mount point already exists %.*s", int(target.length()), target.data());
+ LOG_ERROR("VFS: mount point already exists %s", std::string(target).c_str());
return -EBUSY;
}
}
const auto mpp = m_partitions.find(std::string(dev_or_part));
if (mpp != std::end(m_partitions)) {
- LOG_ERROR("VFS: partition already used %.*s", int(dev_or_part.length()), dev_or_part.data());
+ LOG_ERROR("VFS: partition already used %s", std::string(dev_or_part).c_str());
return -EBUSY;
}
std::string filesystem_type;
@@ 111,7 111,7 @@ namespace purefs::fs
}
const auto vsi = m_fstypes.find(filesystem_type);
if (vsi == std::end(m_fstypes)) {
- LOG_ERROR("VFS: requested filesystem %s not registered", filesystem_type.c_str());
+ LOG_ERROR("VFS: requested filesystem %s not registered", std::string(fs_type).c_str());
return -ENODEV;
}
// Trying to open disk or part by manager
@@ 138,7 138,7 @@ namespace purefs::fs
}
}
else {
- LOG_ERROR("Device or partition %.*s doesn't exists", int(dev_or_part.size()), dev_or_part.data());
+ LOG_ERROR("Device or partition %s doesn't exists", std::string(dev_or_part).c_str());
return -ENXIO;
}
}
M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +29 -2
@@ 9,109 9,131 @@
#include <purefs/fs/thread_local_cwd.hpp>
#include <fcntl.h>
+#include <mutex.hpp>
+
namespace purefs::fs
{
auto filesystem::stat_vfs(std::string_view path, struct ::statvfs &stat) const noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::ro, &filesystem_operations::stat_vfs, path, stat);
}
auto filesystem::stat(std::string_view file, struct stat &st) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::ro, &filesystem_operations::stat, file, st);
}
auto filesystem::unlink(std::string_view name) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::rw, &filesystem_operations::unlink, name);
}
auto filesystem::mkdir(std::string_view path, int mode) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::rw, &filesystem_operations::mkdir, path, mode);
}
auto filesystem::ioctl(std::string_view path, int cmd, void *arg) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::ro, &filesystem_operations::ioctl, path, cmd, arg);
}
auto filesystem::utimens(std::string_view path, std::array<timespec, 2> &tv) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::ro, &filesystem_operations::utimens, path, tv);
}
auto filesystem::flock(int fd, int cmd) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::flock, fd, cmd);
}
auto filesystem::isatty(int fd) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::isatty, fd);
}
auto filesystem::chmod(std::string_view path, mode_t mode) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(iaccess::rw, &filesystem_operations::chmod, path, mode);
}
auto filesystem::write(int fd, const char *ptr, size_t len) noexcept -> ssize_t
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::write, fd, ptr, len);
}
auto filesystem::read(int fd, char *ptr, size_t len) noexcept -> ssize_t
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::read, fd, ptr, len);
}
auto filesystem::seek(int fd, off_t pos, int dir) noexcept -> off_t
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::seek, fd, pos, dir);
}
auto filesystem::fstat(int fd, struct stat &st) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::fstat, fd, st);
}
auto filesystem::ftruncate(int fd, off_t len) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::ftruncate, fd, len);
}
auto filesystem::fsync(int fd) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::fsync, fd);
}
auto filesystem::fchmod(int fd, mode_t mode) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::fchmod, fd, mode);
}
auto filesystem::symlink(std::string_view existing, std::string_view newlink) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops_same_mp(&filesystem_operations::symlink, existing, newlink);
}
auto filesystem::link(std::string_view existing, std::string_view newlink) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops_same_mp(&filesystem_operations::link, existing, newlink);
}
auto filesystem::rename(std::string_view oldname, std::string_view newname) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops_same_mp(&filesystem_operations::rename, oldname, newname);
}
auto filesystem::open(std::string_view path, int flags, int mode) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
const auto abspath = absolute_path(path);
auto [mountp, pathpos] = find_mount_point(abspath);
if (!mountp) {
- LOG_ERROR("VFS: Unable to find mount point: %.*s", int(path.size()), path.data());
+ LOG_ERROR("VFS: Unable to find mount point: %s", std::string(path).c_str());
return -ENOENT;
}
auto fsops = mountp->fs_ops();
@@ 139,6 161,7 @@ namespace purefs::fs
auto filesystem::close(int fd) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
auto ret = invoke_fops(&filesystem_operations::close, fd);
if (!ret) {
ret = (remove_filehandle(fd)) ? (0) : (-EBADF);
@@ 148,10 171,11 @@ namespace purefs::fs
auto filesystem::diropen(std::string_view path) noexcept -> fsdir
{
+ cpp_freertos::LockGuard lock(*m_lock);
const auto abspath = absolute_path(path);
auto [mountp, pathpos] = find_mount_point(abspath);
if (!mountp) {
- LOG_ERROR("VFS: Unable to find mount point: %.*s", int(path.size()), path.data());
+ LOG_ERROR("VFS: Unable to find mount point: %s", std::string(path).c_str());
return std::make_shared<internal::directory_handle>(nullptr, -ENOENT);
}
auto fsops = mountp->fs_ops();
@@ 171,11 195,13 @@ namespace purefs::fs
auto filesystem::dirreset(fsdir dirstate) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
return invoke_fops(&filesystem_operations::dirreset, dirstate);
}
auto filesystem::dirnext(fsdir dirstate, std::string &filename, struct stat &filestat) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
if (!dirstate) {
LOG_ERROR("No directory handle");
return -ENXIO;
@@ 185,6 211,7 @@ namespace purefs::fs
auto filesystem::dirclose(fsdir dirstate) noexcept -> int
{
+ cpp_freertos::LockGuard lock(*m_lock);
if (!dirstate) {
LOG_ERROR("No directory handle");
return -ENXIO;
M module-vfs/targets/Target_RT1051.cmake => module-vfs/targets/Target_RT1051.cmake +5 -3
@@ 1,12 1,14 @@
set(BOARD_SOURCES ${BOARD_SOURCES}
- src/newlib/vfs_io_syscalls.cpp
- board/rt1051/purefs/src/fs/thread_local_cwd.cpp
- board/rt1051/purefs/src/vfs_subsystem_internal.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/blkdev/disk_emmc.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/fs/thread_local_cwd.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/vfs_subsystem_internal.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/newlib/vfs_io_syscalls.cpp
CACHE INTERNAL ""
)
set(BOARD_DIR_INCLUDES ${BOARD_DIR_INCLUDES}
${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051
+ ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/include/
CACHE INTERNAL ""
)