1
mirror of https://github.com/flipperdevices/flipperzero-firmware.git synced 2025-12-12 04:41:26 +04:00

[FL-3927] FuriThread stdin (#3979)

* feat: FuriThread stdin
* ci: fix f18
* feat: stdio callback context

Co-authored-by: Georgii Surkov <37121527+gsurkov@users.noreply.github.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Anna Antonenko
2024-12-19 00:38:43 +04:00
committed by GitHub
parent 9917579619
commit 8d078e4b8c
13 changed files with 346 additions and 38 deletions

View File

@@ -0,0 +1,108 @@
#include <furi.h>
#include <errno.h>
#include <stdio.h>
#include "../test.h" // IWYU pragma: keep
#define TAG "StdioTest"
#define CONTEXT_MAGIC ((void*)0xDEADBEEF)
// stdin
static char mock_in[256];
static size_t mock_in_len, mock_in_pos;
static void set_mock_in(const char* str) {
size_t len = strlen(str);
strcpy(mock_in, str);
mock_in_len = len;
mock_in_pos = 0;
}
static size_t mock_in_cb(char* buffer, size_t size, FuriWait wait, void* context) {
UNUSED(wait);
furi_check(context == CONTEXT_MAGIC);
size_t remaining = mock_in_len - mock_in_pos;
size = MIN(remaining, size);
memcpy(buffer, mock_in + mock_in_pos, size);
mock_in_pos += size;
return size;
}
void test_stdin(void) {
FuriThreadStdinReadCallback in_cb = furi_thread_get_stdin_callback();
furi_thread_set_stdin_callback(mock_in_cb, CONTEXT_MAGIC);
char buf[256];
// plain in
set_mock_in("Hello, World!\n");
fgets(buf, sizeof(buf), stdin);
mu_assert_string_eq("Hello, World!\n", buf);
mu_assert_int_eq(EOF, getchar());
// ungetc
ungetc('i', stdin);
ungetc('H', stdin);
fgets(buf, sizeof(buf), stdin);
mu_assert_string_eq("Hi", buf);
mu_assert_int_eq(EOF, getchar());
// ungetc + plain in
set_mock_in(" World");
ungetc('i', stdin);
ungetc('H', stdin);
fgets(buf, sizeof(buf), stdin);
mu_assert_string_eq("Hi World", buf);
mu_assert_int_eq(EOF, getchar());
// partial plain in
set_mock_in("Hello, World!\n");
fgets(buf, strlen("Hello") + 1, stdin);
mu_assert_string_eq("Hello", buf);
mu_assert_int_eq(',', getchar());
fgets(buf, sizeof(buf), stdin);
mu_assert_string_eq(" World!\n", buf);
furi_thread_set_stdin_callback(in_cb, CONTEXT_MAGIC);
}
// stdout
static FuriString* mock_out;
FuriThreadStdoutWriteCallback original_out_cb;
static void mock_out_cb(const char* data, size_t size, void* context) {
furi_check(context == CONTEXT_MAGIC);
// there's no furi_string_cat_strn :(
for(size_t i = 0; i < size; i++) {
furi_string_push_back(mock_out, data[i]);
}
}
static void assert_and_clear_mock_out(const char* expected) {
// return the original stdout callback for the duration of the check
// if the check fails, we don't want the error to end up in our buffer,
// we want to be able to see it!
furi_thread_set_stdout_callback(original_out_cb, CONTEXT_MAGIC);
mu_assert_string_eq(expected, furi_string_get_cstr(mock_out));
furi_thread_set_stdout_callback(mock_out_cb, CONTEXT_MAGIC);
furi_string_reset(mock_out);
}
void test_stdout(void) {
original_out_cb = furi_thread_get_stdout_callback();
furi_thread_set_stdout_callback(mock_out_cb, CONTEXT_MAGIC);
mock_out = furi_string_alloc();
puts("Hello, World!");
assert_and_clear_mock_out("Hello, World!\n");
printf("He");
printf("llo!");
fflush(stdout);
assert_and_clear_mock_out("Hello!");
furi_string_free(mock_out);
furi_thread_set_stdout_callback(original_out_cb, CONTEXT_MAGIC);
}

View File

@@ -10,6 +10,8 @@ void test_furi_memmgr(void);
void test_furi_event_loop(void); void test_furi_event_loop(void);
void test_errno_saving(void); void test_errno_saving(void);
void test_furi_primitives(void); void test_furi_primitives(void);
void test_stdin(void);
void test_stdout(void);
static int foo = 0; static int foo = 0;
@@ -52,6 +54,11 @@ MU_TEST(mu_test_furi_primitives) {
test_furi_primitives(); test_furi_primitives();
} }
MU_TEST(mu_test_stdio) {
test_stdin();
test_stdout();
}
MU_TEST_SUITE(test_suite) { MU_TEST_SUITE(test_suite) {
MU_SUITE_CONFIGURE(&test_setup, &test_teardown); MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
MU_RUN_TEST(test_check); MU_RUN_TEST(test_check);
@@ -61,6 +68,7 @@ MU_TEST_SUITE(test_suite) {
MU_RUN_TEST(mu_test_furi_pubsub); MU_RUN_TEST(mu_test_furi_pubsub);
MU_RUN_TEST(mu_test_furi_memmgr); MU_RUN_TEST(mu_test_furi_memmgr);
MU_RUN_TEST(mu_test_furi_event_loop); MU_RUN_TEST(mu_test_furi_event_loop);
MU_RUN_TEST(mu_test_stdio);
MU_RUN_TEST(mu_test_errno_saving); MU_RUN_TEST(mu_test_errno_saving);
MU_RUN_TEST(mu_test_furi_primitives); MU_RUN_TEST(mu_test_furi_primitives);
} }

View File

@@ -431,9 +431,9 @@ void cli_session_open(Cli* cli, void* session) {
cli->session = session; cli->session = session;
if(cli->session != NULL) { if(cli->session != NULL) {
cli->session->init(); cli->session->init();
furi_thread_set_stdout_callback(cli->session->tx_stdout); furi_thread_set_stdout_callback(cli->session->tx_stdout, NULL);
} else { } else {
furi_thread_set_stdout_callback(NULL); furi_thread_set_stdout_callback(NULL, NULL);
} }
furi_semaphore_release(cli->idle_sem); furi_semaphore_release(cli->idle_sem);
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
@@ -447,7 +447,7 @@ void cli_session_close(Cli* cli) {
cli->session->deinit(); cli->session->deinit();
} }
cli->session = NULL; cli->session = NULL;
furi_thread_set_stdout_callback(NULL); furi_thread_set_stdout_callback(NULL, NULL);
furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk);
} }
@@ -461,9 +461,9 @@ int32_t cli_srv(void* p) {
furi_record_create(RECORD_CLI, cli); furi_record_create(RECORD_CLI, cli);
if(cli->session != NULL) { if(cli->session != NULL) {
furi_thread_set_stdout_callback(cli->session->tx_stdout); furi_thread_set_stdout_callback(cli->session->tx_stdout, NULL);
} else { } else {
furi_thread_set_stdout_callback(NULL); furi_thread_set_stdout_callback(NULL, NULL);
} }
if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) { if(furi_hal_rtc_get_boot_mode() == FuriHalRtcBootModeNormal) {

View File

@@ -28,8 +28,9 @@ struct CliSession {
void (*init)(void); void (*init)(void);
void (*deinit)(void); void (*deinit)(void);
size_t (*rx)(uint8_t* buffer, size_t size, uint32_t timeout); size_t (*rx)(uint8_t* buffer, size_t size, uint32_t timeout);
size_t (*rx_stdin)(uint8_t* buffer, size_t size, uint32_t timeout, void* context);
void (*tx)(const uint8_t* buffer, size_t size); void (*tx)(const uint8_t* buffer, size_t size);
void (*tx_stdout)(const char* data, size_t size); void (*tx_stdout)(const char* data, size_t size, void* context);
bool (*is_connected)(void); bool (*is_connected)(void);
}; };

View File

@@ -242,6 +242,11 @@ static size_t cli_vcp_rx(uint8_t* buffer, size_t size, uint32_t timeout) {
return rx_cnt; return rx_cnt;
} }
static size_t cli_vcp_rx_stdin(uint8_t* data, size_t size, uint32_t timeout, void* context) {
UNUSED(context);
return cli_vcp_rx(data, size, timeout);
}
static void cli_vcp_tx(const uint8_t* buffer, size_t size) { static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
furi_assert(vcp); furi_assert(vcp);
furi_assert(buffer); furi_assert(buffer);
@@ -267,7 +272,8 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) {
VCP_DEBUG("tx %u end", size); VCP_DEBUG("tx %u end", size);
} }
static void cli_vcp_tx_stdout(const char* data, size_t size) { static void cli_vcp_tx_stdout(const char* data, size_t size, void* context) {
UNUSED(context);
cli_vcp_tx((const uint8_t*)data, size); cli_vcp_tx((const uint8_t*)data, size);
} }
@@ -310,6 +316,7 @@ CliSession cli_vcp = {
cli_vcp_init, cli_vcp_init,
cli_vcp_deinit, cli_vcp_deinit,
cli_vcp_rx, cli_vcp_rx,
cli_vcp_rx_stdin,
cli_vcp_tx, cli_vcp_tx,
cli_vcp_tx_stdout, cli_vcp_tx_stdout,
cli_vcp_is_connected, cli_vcp_is_connected,

View File

@@ -129,12 +129,12 @@ void furi_string_swap(FuriString* string_1, FuriString* string_2);
/** Move string_2 content to string_1. /** Move string_2 content to string_1.
* *
* Set the string to the other one, and destroy the other one. * Copy data from one string to another and destroy the source.
* *
* @param string_1 The FuriString instance 1 * @param destination The destination FuriString
* @param string_2 The FuriString instance 2 * @param source The source FuriString
*/ */
void furi_string_move(FuriString* string_1, FuriString* string_2); void furi_string_move(FuriString* destination, FuriString* source);
/** Compute a hash for the string. /** Compute a hash for the string.
* *

View File

@@ -23,12 +23,17 @@
#define THREAD_MAX_STACK_SIZE (UINT16_MAX * sizeof(StackType_t)) #define THREAD_MAX_STACK_SIZE (UINT16_MAX * sizeof(StackType_t))
typedef struct FuriThreadStdout FuriThreadStdout; typedef struct {
struct FuriThreadStdout {
FuriThreadStdoutWriteCallback write_callback; FuriThreadStdoutWriteCallback write_callback;
FuriString* buffer; FuriString* buffer;
}; void* context;
} FuriThreadStdout;
typedef struct {
FuriThreadStdinReadCallback read_callback;
FuriString* unread_buffer; // <! stores data from `ungetc` and friends
void* context;
} FuriThreadStdin;
struct FuriThread { struct FuriThread {
StaticTask_t container; StaticTask_t container;
@@ -55,6 +60,7 @@ struct FuriThread {
size_t heap_size; size_t heap_size;
FuriThreadStdout output; FuriThreadStdout output;
FuriThreadStdin input;
// Keep all non-alignable byte types in one place, // Keep all non-alignable byte types in one place,
// this ensures that the size of this structure is minimal // this ensures that the size of this structure is minimal
@@ -136,6 +142,7 @@ static void furi_thread_body(void* context) {
static void furi_thread_init_common(FuriThread* thread) { static void furi_thread_init_common(FuriThread* thread) {
thread->output.buffer = furi_string_alloc(); thread->output.buffer = furi_string_alloc();
thread->input.unread_buffer = furi_string_alloc();
FuriThread* parent = NULL; FuriThread* parent = NULL;
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
@@ -245,6 +252,7 @@ void furi_thread_free(FuriThread* thread) {
} }
furi_string_free(thread->output.buffer); furi_string_free(thread->output.buffer);
furi_string_free(thread->input.unread_buffer);
free(thread); free(thread);
} }
@@ -710,13 +718,22 @@ uint32_t furi_thread_get_stack_space(FuriThreadId thread_id) {
static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size) { static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size) {
if(thread->output.write_callback != NULL) { if(thread->output.write_callback != NULL) {
thread->output.write_callback(data, size); thread->output.write_callback(data, size, thread->output.context);
} else { } else {
furi_log_tx((const uint8_t*)data, size); furi_log_tx((const uint8_t*)data, size);
} }
return size; return size;
} }
static size_t
__furi_thread_stdin_read(FuriThread* thread, char* data, size_t size, FuriWait timeout) {
if(thread->input.read_callback != NULL) {
return thread->input.read_callback(data, size, timeout, thread->input.context);
} else {
return 0;
}
}
static int32_t __furi_thread_stdout_flush(FuriThread* thread) { static int32_t __furi_thread_stdout_flush(FuriThread* thread) {
FuriString* buffer = thread->output.buffer; FuriString* buffer = thread->output.buffer;
size_t size = furi_string_size(buffer); size_t size = furi_string_size(buffer);
@@ -727,19 +744,33 @@ static int32_t __furi_thread_stdout_flush(FuriThread* thread) {
return 0; return 0;
} }
void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
__furi_thread_stdout_flush(thread);
thread->output.write_callback = callback;
}
FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(void) { FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(void) {
FuriThread* thread = furi_thread_get_current(); FuriThread* thread = furi_thread_get_current();
furi_check(thread); furi_check(thread);
return thread->output.write_callback; return thread->output.write_callback;
} }
FuriThreadStdinReadCallback furi_thread_get_stdin_callback(void) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
return thread->input.read_callback;
}
void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback, void* context) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
__furi_thread_stdout_flush(thread);
thread->output.write_callback = callback;
thread->output.context = context;
}
void furi_thread_set_stdin_callback(FuriThreadStdinReadCallback callback, void* context) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
thread->input.read_callback = callback;
thread->input.context = context;
}
size_t furi_thread_stdout_write(const char* data, size_t size) { size_t furi_thread_stdout_write(const char* data, size_t size) {
FuriThread* thread = furi_thread_get_current(); FuriThread* thread = furi_thread_get_current();
furi_check(thread); furi_check(thread);
@@ -772,6 +803,31 @@ int32_t furi_thread_stdout_flush(void) {
return __furi_thread_stdout_flush(thread); return __furi_thread_stdout_flush(thread);
} }
size_t furi_thread_stdin_read(char* buffer, size_t size, FuriWait timeout) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
size_t from_buffer = MIN(furi_string_size(thread->input.unread_buffer), size);
size_t from_input = size - from_buffer;
size_t from_input_actual =
__furi_thread_stdin_read(thread, buffer + from_buffer, from_input, timeout);
memcpy(buffer, furi_string_get_cstr(thread->input.unread_buffer), from_buffer);
furi_string_right(thread->input.unread_buffer, from_buffer);
return from_buffer + from_input_actual;
}
void furi_thread_stdin_unread(char* buffer, size_t size) {
FuriThread* thread = furi_thread_get_current();
furi_check(thread);
FuriString* new_buf = furi_string_alloc(); // there's no furi_string_alloc_set_strn :(
furi_string_set_strn(new_buf, buffer, size);
furi_string_cat(new_buf, thread->input.unread_buffer);
furi_string_free(thread->input.unread_buffer);
thread->input.unread_buffer = new_buf;
}
void furi_thread_suspend(FuriThreadId thread_id) { void furi_thread_suspend(FuriThreadId thread_id) {
furi_check(thread_id); furi_check(thread_id);

View File

@@ -74,8 +74,23 @@ typedef int32_t (*FuriThreadCallback)(void* context);
* *
* @param[in] data pointer to the data to be written to the standard out * @param[in] data pointer to the data to be written to the standard out
* @param[in] size size of the data in bytes * @param[in] size size of the data in bytes
* @param[in] context optional context
*/ */
typedef void (*FuriThreadStdoutWriteCallback)(const char* data, size_t size); typedef void (*FuriThreadStdoutWriteCallback)(const char* data, size_t size, void* context);
/**
* @brief Standard input callback function pointer type
*
* The function to be used as a standard input callback MUST follow this signature.
*
* @param[out] buffer buffer to read data into
* @param[in] size maximum number of bytes to read into the buffer
* @param[in] timeout how long to wait for (in ticks) before giving up
* @param[in] context optional context
* @returns number of bytes that was actually read into the buffer
*/
typedef size_t (
*FuriThreadStdinReadCallback)(char* buffer, size_t size, FuriWait timeout, void* context);
/** /**
* @brief State change callback function pointer type. * @brief State change callback function pointer type.
@@ -468,13 +483,30 @@ uint32_t furi_thread_get_stack_space(FuriThreadId thread_id);
*/ */
FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(void); FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(void);
/**
* @brief Get the standard input callback for the current thead.
*
* @return pointer to the standard in callback function
*/
FuriThreadStdinReadCallback furi_thread_get_stdin_callback(void);
/** Set standard output callback for the current thread. /** Set standard output callback for the current thread.
* *
* @param[in] callback pointer to the callback function or NULL to clear * @param[in] callback pointer to the callback function or NULL to clear
* @param[in] context context to be passed to the callback
*/ */
void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback); void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback, void* context);
/** Set standard input callback for the current thread.
*
* @param[in] callback pointer to the callback function or NULL to clear
* @param[in] context context to be passed to the callback
*/
void furi_thread_set_stdin_callback(FuriThreadStdinReadCallback callback, void* context);
/** Write data to buffered standard output. /** Write data to buffered standard output.
*
* @note You can also use the standard C `putc`, `puts`, `printf` and friends.
* *
* @param[in] data pointer to the data to be written * @param[in] data pointer to the data to be written
* @param[in] size data size in bytes * @param[in] size data size in bytes
@@ -489,6 +521,29 @@ size_t furi_thread_stdout_write(const char* data, size_t size);
*/ */
int32_t furi_thread_stdout_flush(void); int32_t furi_thread_stdout_flush(void);
/** Read data from the standard input
*
* @note You can also use the standard C `getc`, `gets` and friends.
*
* @param[in] buffer pointer to the buffer to read data into
* @param[in] size how many bytes to read into the buffer
* @param[in] timeout how long to wait for (in ticks) before giving up
* @return number of bytes that was actually read
*/
size_t furi_thread_stdin_read(char* buffer, size_t size, FuriWait timeout);
/** Puts data back into the standard input buffer
*
* `furi_thread_stdin_read` will return the bytes in the same order that they
* were supplied to this function.
*
* @note You can also use the standard C `ungetc`.
*
* @param[in] buffer pointer to the buffer to get data from
* @param[in] size how many bytes to read from the buffer
*/
void furi_thread_stdin_unread(char* buffer, size_t size);
/** /**
* @brief Suspend a thread. * @brief Suspend a thread.
* *

View File

@@ -44,18 +44,24 @@ wrapped_fn_list = [
"vsiprintf", "vsiprintf",
"vsniprintf", "vsniprintf",
# #
# Scanf is not implemented 4 now # standard input
#
"fgetc",
"getc",
"getchar",
"fgets",
"ungetc",
#
# standard input, but unimplemented
#
"gets",
#
# scanf, not implemented for now
# #
# "fscanf", # "fscanf",
# "scanf", # "scanf",
# "sscanf", # "sscanf",
# "vsprintf", # "vsprintf",
# "fgetc",
# "fgets",
# "getc",
# "getchar",
# "gets",
# "ungetc",
# "vfscanf", # "vfscanf",
# "vscanf", # "vscanf",
# "vsscanf", # "vsscanf",

View File

@@ -51,11 +51,54 @@ int __wrap_snprintf(char* str, size_t size, const char* format, ...) {
} }
int __wrap_fflush(FILE* stream) { int __wrap_fflush(FILE* stream) {
UNUSED(stream); if(stream == stdout) furi_thread_stdout_flush();
furi_thread_stdout_flush();
return 0; return 0;
} }
int __wrap_fgetc(FILE* stream) {
if(stream != stdin) return EOF;
char c;
if(furi_thread_stdin_read(&c, 1, FuriWaitForever) == 0) return EOF;
return c;
}
int __wrap_getc(FILE* stream) {
return __wrap_fgetc(stream);
}
int __wrap_getchar(void) {
return __wrap_fgetc(stdin);
}
char* __wrap_fgets(char* str, size_t n, FILE* stream) {
// leave space for the zero terminator
furi_check(n >= 1);
n--;
if(stream != stdin) {
*str = '\0';
return str;
}
// read characters
int c;
do {
c = __wrap_fgetc(stdin);
if(c > 0) *(str++) = c;
} while(c != EOF && c != '\n' && --n);
// place zero terminator
*str = '\0';
return str;
}
int __wrap_ungetc(int ch, FILE* stream) {
char c = ch;
if(stream != stdin) return EOF;
furi_thread_stdin_unread(&c, 1);
return ch;
}
__attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e) { __attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e) {
UNUSED(file); UNUSED(file);
UNUSED(line); UNUSED(line);

View File

@@ -16,6 +16,12 @@ int __wrap_putc(int ch, FILE* stream);
int __wrap_snprintf(char* str, size_t size, const char* format, ...); int __wrap_snprintf(char* str, size_t size, const char* format, ...);
int __wrap_fflush(FILE* stream); int __wrap_fflush(FILE* stream);
int __wrap_fgetc(FILE* stream);
int __wrap_getc(FILE* stream);
int __wrap_getchar(void);
char* __wrap_fgets(char* str, size_t n, FILE* stream);
int __wrap_ungetc(int ch, FILE* stream);
__attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e); __attribute__((__noreturn__)) void __wrap___assert(const char* file, int line, const char* e);
__attribute__((__noreturn__)) void __attribute__((__noreturn__)) void

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,78.1,, Version,+,79.0,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli.h,,
@@ -371,11 +371,16 @@ Function,-,__utoa,char*,"unsigned, char*, int"
Function,+,__wrap___assert,void,"const char*, int, const char*" Function,+,__wrap___assert,void,"const char*, int, const char*"
Function,+,__wrap___assert_func,void,"const char*, int, const char*, const char*" Function,+,__wrap___assert_func,void,"const char*, int, const char*, const char*"
Function,+,__wrap_fflush,int,FILE* Function,+,__wrap_fflush,int,FILE*
Function,+,__wrap_fgetc,int,FILE*
Function,+,__wrap_fgets,char*,"char*, size_t, FILE*"
Function,+,__wrap_getc,int,FILE*
Function,+,__wrap_getchar,int,
Function,+,__wrap_printf,int,"const char*, ..." Function,+,__wrap_printf,int,"const char*, ..."
Function,+,__wrap_putc,int,"int, FILE*" Function,+,__wrap_putc,int,"int, FILE*"
Function,+,__wrap_putchar,int,int Function,+,__wrap_putchar,int,int
Function,+,__wrap_puts,int,const char* Function,+,__wrap_puts,int,const char*
Function,+,__wrap_snprintf,int,"char*, size_t, const char*, ..." Function,+,__wrap_snprintf,int,"char*, size_t, const char*, ..."
Function,+,__wrap_ungetc,int,"int, FILE*"
Function,+,__wrap_vsnprintf,int,"char*, size_t, const char*, va_list" Function,+,__wrap_vsnprintf,int,"char*, size_t, const char*, va_list"
Function,-,_asiprintf_r,int,"_reent*, char**, const char*, ..." Function,-,_asiprintf_r,int,"_reent*, char**, const char*, ..."
Function,-,_asniprintf_r,char*,"_reent*, char*, size_t*, const char*, ..." Function,-,_asniprintf_r,char*,"_reent*, char*, size_t*, const char*, ..."
@@ -1654,6 +1659,7 @@ Function,+,furi_thread_get_return_code,int32_t,FuriThread*
Function,+,furi_thread_get_signal_callback,FuriThreadSignalCallback,const FuriThread* Function,+,furi_thread_get_signal_callback,FuriThreadSignalCallback,const FuriThread*
Function,+,furi_thread_get_stack_space,uint32_t,FuriThreadId Function,+,furi_thread_get_stack_space,uint32_t,FuriThreadId
Function,+,furi_thread_get_state,FuriThreadState,FuriThread* Function,+,furi_thread_get_state,FuriThreadState,FuriThread*
Function,+,furi_thread_get_stdin_callback,FuriThreadStdinReadCallback,
Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback, Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback,
Function,+,furi_thread_is_suspended,_Bool,FuriThreadId Function,+,furi_thread_is_suspended,_Bool,FuriThreadId
Function,+,furi_thread_join,_Bool,FuriThread* Function,+,furi_thread_join,_Bool,FuriThread*
@@ -1674,9 +1680,12 @@ Function,+,furi_thread_set_signal_callback,void,"FuriThread*, FuriThreadSignalCa
Function,+,furi_thread_set_stack_size,void,"FuriThread*, size_t" Function,+,furi_thread_set_stack_size,void,"FuriThread*, size_t"
Function,+,furi_thread_set_state_callback,void,"FuriThread*, FuriThreadStateCallback" Function,+,furi_thread_set_state_callback,void,"FuriThread*, FuriThreadStateCallback"
Function,+,furi_thread_set_state_context,void,"FuriThread*, void*" Function,+,furi_thread_set_state_context,void,"FuriThread*, void*"
Function,+,furi_thread_set_stdout_callback,void,FuriThreadStdoutWriteCallback Function,+,furi_thread_set_stdin_callback,void,"FuriThreadStdinReadCallback, void*"
Function,+,furi_thread_set_stdout_callback,void,"FuriThreadStdoutWriteCallback, void*"
Function,+,furi_thread_signal,_Bool,"const FuriThread*, uint32_t, void*" Function,+,furi_thread_signal,_Bool,"const FuriThread*, uint32_t, void*"
Function,+,furi_thread_start,void,FuriThread* Function,+,furi_thread_start,void,FuriThread*
Function,+,furi_thread_stdin_read,size_t,"char*, size_t, FuriWait"
Function,+,furi_thread_stdin_unread,void,"char*, size_t"
Function,+,furi_thread_stdout_flush,int32_t, Function,+,furi_thread_stdout_flush,int32_t,
Function,+,furi_thread_stdout_write,size_t,"const char*, size_t" Function,+,furi_thread_stdout_write,size_t,"const char*, size_t"
Function,+,furi_thread_suspend,void,FuriThreadId Function,+,furi_thread_suspend,void,FuriThreadId
1 entry status name type params
2 Version + 78.1 79.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/bt/bt_service/bt_keys_storage.h
5 Header + applications/services/cli/cli.h
371 Function + __wrap___assert void const char*, int, const char*
372 Function + __wrap___assert_func void const char*, int, const char*, const char*
373 Function + __wrap_fflush int FILE*
374 Function + __wrap_fgetc int FILE*
375 Function + __wrap_fgets char* char*, size_t, FILE*
376 Function + __wrap_getc int FILE*
377 Function + __wrap_getchar int
378 Function + __wrap_printf int const char*, ...
379 Function + __wrap_putc int int, FILE*
380 Function + __wrap_putchar int int
381 Function + __wrap_puts int const char*
382 Function + __wrap_snprintf int char*, size_t, const char*, ...
383 Function + __wrap_ungetc int int, FILE*
384 Function + __wrap_vsnprintf int char*, size_t, const char*, va_list
385 Function - _asiprintf_r int _reent*, char**, const char*, ...
386 Function - _asniprintf_r char* _reent*, char*, size_t*, const char*, ...
1659 Function + furi_thread_get_signal_callback FuriThreadSignalCallback const FuriThread*
1660 Function + furi_thread_get_stack_space uint32_t FuriThreadId
1661 Function + furi_thread_get_state FuriThreadState FuriThread*
1662 Function + furi_thread_get_stdin_callback FuriThreadStdinReadCallback
1663 Function + furi_thread_get_stdout_callback FuriThreadStdoutWriteCallback
1664 Function + furi_thread_is_suspended _Bool FuriThreadId
1665 Function + furi_thread_join _Bool FuriThread*
1680 Function + furi_thread_set_stack_size void FuriThread*, size_t
1681 Function + furi_thread_set_state_callback void FuriThread*, FuriThreadStateCallback
1682 Function + furi_thread_set_state_context void FuriThread*, void*
1683 Function + furi_thread_set_stdout_callback furi_thread_set_stdin_callback void FuriThreadStdoutWriteCallback FuriThreadStdinReadCallback, void*
1684 Function + furi_thread_set_stdout_callback void FuriThreadStdoutWriteCallback, void*
1685 Function + furi_thread_signal _Bool const FuriThread*, uint32_t, void*
1686 Function + furi_thread_start void FuriThread*
1687 Function + furi_thread_stdin_read size_t char*, size_t, FuriWait
1688 Function + furi_thread_stdin_unread void char*, size_t
1689 Function + furi_thread_stdout_flush int32_t
1690 Function + furi_thread_stdout_write size_t const char*, size_t
1691 Function + furi_thread_suspend void FuriThreadId

View File

@@ -1,5 +1,5 @@
entry,status,name,type,params entry,status,name,type,params
Version,+,78.1,, Version,+,79.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,, Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
@@ -448,11 +448,16 @@ Function,-,__utoa,char*,"unsigned, char*, int"
Function,+,__wrap___assert,void,"const char*, int, const char*" Function,+,__wrap___assert,void,"const char*, int, const char*"
Function,+,__wrap___assert_func,void,"const char*, int, const char*, const char*" Function,+,__wrap___assert_func,void,"const char*, int, const char*, const char*"
Function,+,__wrap_fflush,int,FILE* Function,+,__wrap_fflush,int,FILE*
Function,+,__wrap_fgetc,int,FILE*
Function,+,__wrap_fgets,char*,"char*, size_t, FILE*"
Function,+,__wrap_getc,int,FILE*
Function,+,__wrap_getchar,int,
Function,+,__wrap_printf,int,"const char*, ..." Function,+,__wrap_printf,int,"const char*, ..."
Function,+,__wrap_putc,int,"int, FILE*" Function,+,__wrap_putc,int,"int, FILE*"
Function,+,__wrap_putchar,int,int Function,+,__wrap_putchar,int,int
Function,+,__wrap_puts,int,const char* Function,+,__wrap_puts,int,const char*
Function,+,__wrap_snprintf,int,"char*, size_t, const char*, ..." Function,+,__wrap_snprintf,int,"char*, size_t, const char*, ..."
Function,+,__wrap_ungetc,int,"int, FILE*"
Function,+,__wrap_vsnprintf,int,"char*, size_t, const char*, va_list" Function,+,__wrap_vsnprintf,int,"char*, size_t, const char*, va_list"
Function,-,_asiprintf_r,int,"_reent*, char**, const char*, ..." Function,-,_asiprintf_r,int,"_reent*, char**, const char*, ..."
Function,-,_asniprintf_r,char*,"_reent*, char*, size_t*, const char*, ..." Function,-,_asniprintf_r,char*,"_reent*, char*, size_t*, const char*, ..."
@@ -1873,6 +1878,7 @@ Function,+,furi_thread_get_return_code,int32_t,FuriThread*
Function,+,furi_thread_get_signal_callback,FuriThreadSignalCallback,const FuriThread* Function,+,furi_thread_get_signal_callback,FuriThreadSignalCallback,const FuriThread*
Function,+,furi_thread_get_stack_space,uint32_t,FuriThreadId Function,+,furi_thread_get_stack_space,uint32_t,FuriThreadId
Function,+,furi_thread_get_state,FuriThreadState,FuriThread* Function,+,furi_thread_get_state,FuriThreadState,FuriThread*
Function,+,furi_thread_get_stdin_callback,FuriThreadStdinReadCallback,
Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback, Function,+,furi_thread_get_stdout_callback,FuriThreadStdoutWriteCallback,
Function,+,furi_thread_is_suspended,_Bool,FuriThreadId Function,+,furi_thread_is_suspended,_Bool,FuriThreadId
Function,+,furi_thread_join,_Bool,FuriThread* Function,+,furi_thread_join,_Bool,FuriThread*
@@ -1893,9 +1899,12 @@ Function,+,furi_thread_set_signal_callback,void,"FuriThread*, FuriThreadSignalCa
Function,+,furi_thread_set_stack_size,void,"FuriThread*, size_t" Function,+,furi_thread_set_stack_size,void,"FuriThread*, size_t"
Function,+,furi_thread_set_state_callback,void,"FuriThread*, FuriThreadStateCallback" Function,+,furi_thread_set_state_callback,void,"FuriThread*, FuriThreadStateCallback"
Function,+,furi_thread_set_state_context,void,"FuriThread*, void*" Function,+,furi_thread_set_state_context,void,"FuriThread*, void*"
Function,+,furi_thread_set_stdout_callback,void,FuriThreadStdoutWriteCallback Function,+,furi_thread_set_stdin_callback,void,"FuriThreadStdinReadCallback, void*"
Function,+,furi_thread_set_stdout_callback,void,"FuriThreadStdoutWriteCallback, void*"
Function,+,furi_thread_signal,_Bool,"const FuriThread*, uint32_t, void*" Function,+,furi_thread_signal,_Bool,"const FuriThread*, uint32_t, void*"
Function,+,furi_thread_start,void,FuriThread* Function,+,furi_thread_start,void,FuriThread*
Function,+,furi_thread_stdin_read,size_t,"char*, size_t, FuriWait"
Function,+,furi_thread_stdin_unread,void,"char*, size_t"
Function,+,furi_thread_stdout_flush,int32_t, Function,+,furi_thread_stdout_flush,int32_t,
Function,+,furi_thread_stdout_write,size_t,"const char*, size_t" Function,+,furi_thread_stdout_write,size_t,"const char*, size_t"
Function,+,furi_thread_suspend,void,FuriThreadId Function,+,furi_thread_suspend,void,FuriThreadId
1 entry status name type params
2 Version + 78.1 79.0
3 Header + applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h
4 Header + applications/services/bt/bt_service/bt.h
5 Header + applications/services/bt/bt_service/bt_keys_storage.h
448 Function + __wrap___assert void const char*, int, const char*
449 Function + __wrap___assert_func void const char*, int, const char*, const char*
450 Function + __wrap_fflush int FILE*
451 Function + __wrap_fgetc int FILE*
452 Function + __wrap_fgets char* char*, size_t, FILE*
453 Function + __wrap_getc int FILE*
454 Function + __wrap_getchar int
455 Function + __wrap_printf int const char*, ...
456 Function + __wrap_putc int int, FILE*
457 Function + __wrap_putchar int int
458 Function + __wrap_puts int const char*
459 Function + __wrap_snprintf int char*, size_t, const char*, ...
460 Function + __wrap_ungetc int int, FILE*
461 Function + __wrap_vsnprintf int char*, size_t, const char*, va_list
462 Function - _asiprintf_r int _reent*, char**, const char*, ...
463 Function - _asniprintf_r char* _reent*, char*, size_t*, const char*, ...
1878 Function + furi_thread_get_signal_callback FuriThreadSignalCallback const FuriThread*
1879 Function + furi_thread_get_stack_space uint32_t FuriThreadId
1880 Function + furi_thread_get_state FuriThreadState FuriThread*
1881 Function + furi_thread_get_stdin_callback FuriThreadStdinReadCallback
1882 Function + furi_thread_get_stdout_callback FuriThreadStdoutWriteCallback
1883 Function + furi_thread_is_suspended _Bool FuriThreadId
1884 Function + furi_thread_join _Bool FuriThread*
1899 Function + furi_thread_set_stack_size void FuriThread*, size_t
1900 Function + furi_thread_set_state_callback void FuriThread*, FuriThreadStateCallback
1901 Function + furi_thread_set_state_context void FuriThread*, void*
1902 Function + furi_thread_set_stdout_callback furi_thread_set_stdin_callback void FuriThreadStdoutWriteCallback FuriThreadStdinReadCallback, void*
1903 Function + furi_thread_set_stdout_callback void FuriThreadStdoutWriteCallback, void*
1904 Function + furi_thread_signal _Bool const FuriThread*, uint32_t, void*
1905 Function + furi_thread_start void FuriThread*
1906 Function + furi_thread_stdin_read size_t char*, size_t, FuriWait
1907 Function + furi_thread_stdin_unread void char*, size_t
1908 Function + furi_thread_stdout_flush int32_t
1909 Function + furi_thread_stdout_write size_t const char*, size_t
1910 Function + furi_thread_suspend void FuriThreadId