Files
arcs/arcs-sdk/components/tinyusb-appclass/adb/adb_sync_ext_disk.c
2026-08-13 16:50:52 +08:00

193 lines
4.4 KiB
C

#include "disk/disk_access.h"
#include "adb_utils.h"
#include "adb_sync_ext_disk.h"
#include "stdint.h"
#include "string.h"
#include "stdlib.h"
struct adb_sync_ext_disk_ctx *adb_sync_ext_disk_ctx_init(const char *name, uint32_t start_addr)
{
int r;
if (name == NULL) {
return NULL;
}
struct adb_sync_ext_disk_ctx *ctx = ADB_MALLOC(sizeof(struct adb_sync_ext_disk_ctx));
if (ctx == NULL) {
ADB_LOGE("adb sync ext disk context malloc error");
return NULL;
}
ctx->name = name;
r = disk_access_ioctl(ctx->name, DISK_IOCTL_GET_SECTOR_SIZE, &ctx->sec_size);
if (r) {
ADB_LOGE("get disk sector size error, disk name:%s\n", ctx->name);
ADB_FREE(ctx);
return NULL;
}
if (start_addr % ctx->sec_size != 0) {
ADB_LOGE("start_addr is not align with sec_size, start_addr:0x%x, sec_size:%d\n", start_addr, ctx->sec_size);
ADB_FREE(ctx);
return NULL;
}
ctx->buf = ADB_MALLOC(ctx->sec_size);
if (ctx->buf == NULL) {
ADB_LOGE("adb sync ext disk buffer malloc error");
ADB_FREE(ctx);
return NULL;
}
ctx->buf_idx = 0;
ctx->curr_sec = start_addr / ctx->sec_size;
ADB_LOGI("adb sync ext disk init, name:%s, sec_size:%d, start_sec:%d\n", name, ctx->sec_size, ctx->curr_sec);
return ctx;
}
static int adb_sync_ext_disk_flush(struct adb_sync_ext_disk_ctx *ctx)
{
int r;
if (ctx->buf_idx == 0) {
return 0;
}
r = disk_access_write(ctx->name, ctx->buf, ctx->curr_sec, 1);
if (r) {
return r;
}
if (ctx->buf_idx == ctx->sec_size) {
ctx->curr_sec += 1;
}
ctx->buf_idx = 0;
return 0;
}
void adb_sync_ext_disk_ctx_free(struct adb_sync_ext_disk_ctx *ctx)
{
if (ctx) {
adb_sync_ext_disk_flush(ctx);
ADB_FREE(ctx->buf);
ADB_FREE(ctx);
}
}
static int adb_sync_ext_disk_write_align_start_sector(struct adb_sync_ext_disk_ctx *ctx, const uint8_t *data, uint32_t len)
{
int r;
int n;
n = len / ctx->sec_size;
if (n) {
r = disk_access_write(ctx->name, data, ctx->curr_sec, n);
if (r) {
return r;
}
ctx->curr_sec += n;
data += n * ctx->sec_size;
}
n = len % ctx->sec_size;
if (n) {
memcpy(ctx->buf, data, n);
ctx->buf_idx = n;
}
return 0;
}
int adb_sync_ext_disk_write(struct adb_sync_ext_disk_ctx *ctx, const uint8_t *data, uint32_t len)
{
int r;
int n;
if (ctx == NULL || data == NULL || len == 0) {
return -1;
}
if (ctx->buf_idx == 0) {
adb_sync_ext_disk_write_align_start_sector(ctx, data, len);
} else {
if (ctx->buf_idx == ctx->sec_size) {
adb_sync_ext_disk_flush(ctx);
}
int cpy_len = len <= ctx->sec_size - ctx->buf_idx ? len : ctx->sec_size - ctx->buf_idx;
memcpy(ctx->buf + ctx->buf_idx, data, cpy_len);
ctx->buf_idx += cpy_len;
if (ctx->buf_idx == ctx->sec_size) {
adb_sync_ext_disk_flush(ctx);
}
adb_sync_ext_disk_write_align_start_sector(ctx, data + cpy_len, len - cpy_len);
}
return 0;
}
int adb_sync_ext_disk_read(struct adb_sync_ext_disk_ctx *ctx, uint8_t *data, uint32_t len)
{
int r;
int cnt;
if (ctx == NULL || data == NULL || len == 0) {
return -1;
}
cnt = (len / ctx->sec_size) + ((len % ctx->sec_size) ? 1 : 0);
r = disk_access_read(ctx->name, data, ctx->curr_sec, cnt);
if (r) {
return r;
}
ctx->curr_sec += cnt;
return len;
}
bool adb_sync_is_ext_disk_access(const char *path)
{
return strncmp(path, ADB_SYNC_EXT_MOUNT_POINT, strlen(ADB_SYNC_EXT_MOUNT_POINT)) == 0;
}
int adb_sync_ext_disk_get_info_by_path(char *path, char **name, uint32_t *addr, uint32_t *size)
{
/* /RAW/name/addr/size */
char *p = strstr(path, ADB_SYNC_EXT_MOUNT_POINT);
char *token;
char *saveptr;
if (p != path) {
return -1;
}
p += strlen(ADB_SYNC_EXT_MOUNT_POINT);
*size = 0;
*addr = 0;
token = strtok_r(p, "/", &saveptr);
if (token == NULL) {
return -1;
}
*name = token;
token = strtok_r(NULL, "/", &saveptr);
if (token == NULL) {
return -1;
}
*addr = strtol(token, NULL, 16);
token = strtok_r(NULL, "/", &saveptr);
if (token == NULL) {
return -1;
}
*size = strtol(token, NULL, 16);
return 0;
}