Merge branch 'fz-dev' into dev

This commit is contained in:
MX
2023-03-20 20:04:22 +03:00
73 changed files with 333 additions and 246 deletions

View File

@@ -4,6 +4,7 @@ App(
apptype=FlipperAppType.METAPACKAGE,
provides=[
"gpio",
"onewire",
"ibutton",
"infrared",
"lfrfid",

View File

@@ -1,16 +1,17 @@
#include "fap_loader_app.h"
#include <furi.h>
#include <gui/gui.h>
#include <assets_icons.h>
#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <storage/storage.h>
#include <gui/modules/loading.h>
#include <dialogs/dialogs.h>
#include <toolbox/path.h>
#include <flipper_application/flipper_application.h>
#include <loader/firmware_api/firmware_api.h>
#include "fap_loader_app.h"
#define TAG "fap_loader_app"
#define TAG "FapLoader"
struct FapLoader {
FlipperApplication* app;
@@ -22,6 +23,8 @@ struct FapLoader {
Loading* loading;
};
volatile bool fap_loader_debug_active = false;
bool fap_loader_load_name_and_icon(
FuriString* path,
Storage* storage,
@@ -107,6 +110,14 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
FuriThread* thread = flipper_application_spawn(loader->app, NULL);
/* This flag is set by the debugger - to break on app start */
if(fap_loader_debug_active) {
FURI_LOG_W(TAG, "Triggering BP for debugger");
/* After hitting this, you can set breakpoints in your .fap's code
* Note that you have to toggle breakpoints that were set before */
__asm volatile("bkpt 0");
}
FuriString* app_name = furi_string_alloc();
path_extract_filename_no_ext(furi_string_get_cstr(loader->fap_path), app_name);
furi_thread_set_appid(thread, furi_string_get_cstr(app_name));

View File

@@ -4,25 +4,20 @@
#include <cli/cli.h>
#include <toolbox/args.h>
#include <one_wire/one_wire_host.h>
#include <one_wire/ibutton/ibutton_key.h>
#include <one_wire/ibutton/ibutton_worker.h>
#include <one_wire/ibutton/ibutton_protocols.h>
#include <ibutton/ibutton_key.h>
#include <ibutton/ibutton_worker.h>
#include <ibutton/ibutton_protocols.h>
static void ibutton_cli(Cli* cli, FuriString* args, void* context);
static void onewire_cli(Cli* cli, FuriString* args, void* context);
// app cli function
void ibutton_on_system_start() {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli);
cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli);
furi_record_close(RECORD_CLI);
#else
UNUSED(ibutton_cli);
UNUSED(onewire_cli);
#endif
}
@@ -257,56 +252,3 @@ void ibutton_cli(Cli* cli, FuriString* args, void* context) {
furi_string_free(cmd);
}
static void onewire_cli_print_usage() {
printf("Usage:\r\n");
printf("onewire search\r\n");
};
static void onewire_cli_search(Cli* cli) {
UNUSED(cli);
OneWireHost* onewire = onewire_host_alloc(&ibutton_gpio);
uint8_t address[8];
bool done = false;
printf("Search started\r\n");
onewire_host_start(onewire);
furi_hal_power_enable_otg();
while(!done) {
if(onewire_host_search(onewire, address, OneWireHostSearchModeNormal) != 1) {
printf("Search finished\r\n");
onewire_host_reset_search(onewire);
done = true;
} else {
printf("Found: ");
for(uint8_t i = 0; i < 8; i++) {
printf("%02X", address[i]);
}
printf("\r\n");
}
furi_delay_ms(100);
}
furi_hal_power_disable_otg();
onewire_host_free(onewire);
}
void onewire_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
FuriString* cmd;
cmd = furi_string_alloc();
if(!args_read_string_and_trim(args, cmd)) {
furi_string_free(cmd);
onewire_cli_print_usage();
return;
}
if(furi_string_cmp_str(cmd, "search") == 0) {
onewire_cli_search(cli);
}
furi_string_free(cmd);
}

View File

@@ -7,8 +7,8 @@
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include <one_wire/ibutton/ibutton_worker.h>
#include <one_wire/ibutton/ibutton_protocols.h>
#include <ibutton/ibutton_worker.h>
#include <ibutton/ibutton_protocols.h>
#include <rpc/rpc_app.h>
#include <storage/storage.h>

View File

@@ -0,0 +1,14 @@
App(
appid="onewire",
name="1-Wire",
apptype=FlipperAppType.METAPACKAGE,
provides=["onewire_start"],
)
App(
appid="onewire_start",
apptype=FlipperAppType.STARTUP,
entry_point="onewire_on_system_start",
requires=["onewire"],
order=60,
)

View File

@@ -0,0 +1,72 @@
#include <furi.h>
#include <furi_hal.h>
#include <cli/cli.h>
#include <toolbox/args.h>
#include <one_wire/one_wire_host.h>
static void onewire_cli(Cli* cli, FuriString* args, void* context);
void onewire_on_system_start() {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);
cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli);
furi_record_close(RECORD_CLI);
#else
UNUSED(onewire_cli);
#endif
}
static void onewire_cli_print_usage() {
printf("Usage:\r\n");
printf("onewire search\r\n");
};
static void onewire_cli_search(Cli* cli) {
UNUSED(cli);
OneWireHost* onewire = onewire_host_alloc(&ibutton_gpio);
uint8_t address[8];
bool done = false;
printf("Search started\r\n");
onewire_host_start(onewire);
furi_hal_power_enable_otg();
while(!done) {
if(onewire_host_search(onewire, address, OneWireHostSearchModeNormal) != 1) {
printf("Search finished\r\n");
onewire_host_reset_search(onewire);
done = true;
} else {
printf("Found: ");
for(uint8_t i = 0; i < 8; i++) {
printf("%02X", address[i]);
}
printf("\r\n");
}
furi_delay_ms(100);
}
furi_hal_power_disable_otg();
onewire_host_free(onewire);
}
void onewire_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(context);
FuriString* cmd;
cmd = furi_string_alloc();
if(!args_read_string_and_trim(args, cmd)) {
furi_string_free(cmd);
onewire_cli_print_usage();
return;
}
if(furi_string_cmp_str(cmd, "search") == 0) {
onewire_cli_search(cli);
}
furi_string_free(cmd);
}

View File

@@ -77,7 +77,7 @@ static void storage_path_change_to_real_storage(FuriString* path, StorageType re
}
}
FS_Error storage_get_data(Storage* app, FuriString* path, StorageData** storage) {
static FS_Error storage_get_data(Storage* app, FuriString* path, StorageData** storage) {
StorageType type = storage_get_type_by_path(path);
if(storage_type_is_valid(type)) {

View File

@@ -618,6 +618,8 @@ static const FS_Api fs_api = {
};
void storage_ext_init(StorageData* storage) {
fatfs_init();
SDData* sd_data = malloc(sizeof(SDData));
sd_data->fs = &fatfs_object;
sd_data->path = "0:/";

View File

@@ -2,7 +2,6 @@ from dataclasses import dataclass
from typing import Optional, Tuple, Dict, ClassVar
import struct
import posixpath
import os
import zlib
import gdb
@@ -66,9 +65,9 @@ class AppState:
def get_gdb_unload_command(self) -> str:
return f"remove-symbol-file -a 0x{self.text_address:08x}"
def is_loaded_in_gdb(self, gdb_app) -> bool:
# Avoid constructing full app wrapper for comparison
return self.entry_address == int(gdb_app["state"]["entry"])
@staticmethod
def get_gdb_app_ep(app) -> int:
return int(app["state"]["entry"])
@staticmethod
def parse_debug_link_data(section_data: bytes) -> Tuple[str, int]:
@@ -79,10 +78,10 @@ class AppState:
crc32 = struct.unpack("<I", section_data[-4:])[0]
return (elf_name, crc32)
@staticmethod
def from_gdb(gdb_app: "AppState") -> "AppState":
@classmethod
def from_gdb(cls, gdb_app: "AppState") -> "AppState":
state = AppState(str(gdb_app["manifest"]["name"].string()))
state.entry_address = int(gdb_app["state"]["entry"])
state.entry_address = cls.get_gdb_app_ep(gdb_app)
app_state = gdb_app["state"]
if debug_link_size := int(app_state["debug_link_info"]["debug_link_size"]):
@@ -123,59 +122,83 @@ class SetFapDebugElfRoot(gdb.Command):
try:
global helper
print(f"Set '{arg}' as debug info lookup path for Flipper external apps")
helper.attach_fw()
helper.attach_to_fw()
gdb.events.stop.connect(helper.handle_stop)
gdb.events.exited.connect(helper.handle_exit)
except gdb.error as e:
print(f"Support for Flipper external apps debug is not available: {e}")
SetFapDebugElfRoot()
class FlipperAppDebugHelper:
class FlipperAppStateHelper:
def __init__(self):
self.app_ptr = None
self.app_type_ptr = None
self.current_app: AppState = None
self.app_list_ptr = None
self.app_list_entry_type = None
self._current_apps: list[AppState] = []
def attach_fw(self) -> None:
self.app_ptr = gdb.lookup_global_symbol("last_loaded_app")
self.app_type_ptr = gdb.lookup_type("FlipperApplication").pointer()
self._check_app_state()
def _walk_app_list(self, list_head):
while list_head:
if app := list_head["data"]:
yield app.dereference()
list_head = list_head["next"]
def _check_app_state(self) -> None:
app_ptr_value = self.app_ptr.value()
if not app_ptr_value and self.current_app:
# There is an ELF loaded in GDB, but nothing is running on the device
self._unload_debug_elf()
elif app_ptr_value:
# There is an app running on the device
loaded_app = app_ptr_value.cast(self.app_type_ptr).dereference()
if self.current_app and not self.current_app.is_loaded_in_gdb(loaded_app):
# Currently loaded ELF is not the one running on the device
self._unload_debug_elf()
if not self.current_app:
# Load ELF for the app running on the device
self._load_debug_elf(loaded_app)
def _unload_debug_elf(self) -> None:
def _exec_gdb_command(self, command: str) -> bool:
try:
gdb.execute(self.current_app.get_gdb_unload_command())
gdb.execute(command)
return True
except gdb.error as e:
print(f"Failed to unload debug ELF: {e} (might not be an error)")
self.current_app = None
print(f"Failed to execute GDB command '{command}': {e}")
return False
def _load_debug_elf(self, app_object) -> None:
self.current_app = AppState.from_gdb(app_object)
def _sync_apps(self) -> None:
self.set_debug_mode(True)
if not (app_list := self.app_list_ptr.value()):
print("Reset app loader state")
for app in self._current_apps:
self._exec_gdb_command(app.get_gdb_unload_command())
self._current_apps = []
return
if self.current_app.is_debug_available():
gdb.execute(self.current_app.get_gdb_load_command())
loaded_apps: dict[int, gdb.Value] = dict(
(AppState.get_gdb_app_ep(app), app)
for app in self._walk_app_list(app_list[0])
)
for app in self._current_apps.copy():
if app.entry_address not in loaded_apps:
print(f"Application {app.name} is no longer loaded")
if not self._exec_gdb_command(app.get_gdb_unload_command()):
print(f"Failed to unload debug info for {app.name}")
self._current_apps.remove(app)
for entry_point, app in loaded_apps.items():
if entry_point not in set(app.entry_address for app in self._current_apps):
new_app_state = AppState.from_gdb(app)
print(f"New application loaded. Adding debug info")
if self._exec_gdb_command(new_app_state.get_gdb_load_command()):
self._current_apps.append(new_app_state)
else:
print(f"Failed to load debug info for {new_app_state}")
def attach_to_fw(self) -> None:
print("Attaching to Flipper firmware")
self.app_list_ptr = gdb.lookup_global_symbol(
"flipper_application_loaded_app_list"
)
self.app_type_ptr = gdb.lookup_type("FlipperApplication").pointer()
self.app_list_entry_type = gdb.lookup_type("struct FlipperApplicationList_s")
def handle_stop(self, event) -> None:
self._check_app_state()
self._sync_apps()
def handle_exit(self, event) -> None:
self.set_debug_mode(False)
def set_debug_mode(self, mode: bool) -> None:
gdb.execute(f"set variable fap_loader_debug_active = {int(mode)}")
helper = FlipperAppDebugHelper()
# Init additional 'fap-set-debug-elf-root' command and set up hooks
SetFapDebugElfRoot()
helper = FlipperAppStateHelper()
print("Support for Flipper external apps debug is loaded")

View File

@@ -32,6 +32,8 @@ Images and animated icons should follow the same [naming convention](../assets/R
With it, you can debug FAPs as if they were a part of the main firmware — inspect variables, set breakpoints, step through the code, etc.
If debugging session is active, firmware will trigger a breakpoint after loading a FAP it into memory, but before running any code from it. This allows you to set breakpoints in the FAP's code. Note that any breakpoints set before the FAP is loaded may need re-setting after the FAP is actually loaded, since before loading it debugger cannot know the exact address of the FAP's code.
### Setting up debugging environment
The debugging support script looks up debugging information in the latest firmware build directory (`build/latest`). That directory is symlinked by `fbt` to the latest firmware configuration (Debug or Release) build directory when you run `./fbt` for the chosen configuration. See [fbt docs](./fbt.md#nb) for details.

View File

@@ -151,6 +151,10 @@ Header,+,lib/mlib/m-list.h,,
Header,+,lib/mlib/m-rbtree.h,,
Header,+,lib/mlib/m-tuple.h,,
Header,+,lib/mlib/m-variant.h,,
Header,+,lib/one_wire/maxim_crc.h,,
Header,+,lib/one_wire/one_wire_host.h,,
Header,+,lib/one_wire/one_wire_host_timing.h,,
Header,+,lib/one_wire/one_wire_slave.h,,
Header,+,lib/print/wrappers.h,,
Header,+,lib/toolbox/args.h,,
Header,+,lib/toolbox/crc32_calc.h,,
@@ -1394,6 +1398,7 @@ Function,+,manchester_advance,_Bool,"ManchesterState, ManchesterEvent, Mancheste
Function,+,manchester_encoder_advance,_Bool,"ManchesterEncoderState*, const _Bool, ManchesterEncoderResult*"
Function,+,manchester_encoder_finish,ManchesterEncoderResult,ManchesterEncoderState*
Function,+,manchester_encoder_reset,void,ManchesterEncoderState*
Function,+,maxim_crc8,uint8_t,"const uint8_t*, const uint8_t, const uint8_t"
Function,-,mbedtls_des3_crypt_cbc,int,"mbedtls_des3_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*"
Function,-,mbedtls_des3_crypt_ecb,int,"mbedtls_des3_context*, const unsigned char[8], unsigned char[8]"
Function,-,mbedtls_des3_free,void,mbedtls_des3_context*
@@ -1472,6 +1477,32 @@ Function,+,notification_message,void,"NotificationApp*, const NotificationSequen
Function,+,notification_message_block,void,"NotificationApp*, const NotificationSequence*"
Function,-,nrand48,long,unsigned short[3]
Function,-,on_exit,int,"void (*)(int, void*), void*"
Function,+,onewire_host_alloc,OneWireHost*,const GpioPin*
Function,+,onewire_host_free,void,OneWireHost*
Function,+,onewire_host_read,uint8_t,OneWireHost*
Function,+,onewire_host_read_bit,_Bool,OneWireHost*
Function,+,onewire_host_read_bytes,void,"OneWireHost*, uint8_t*, uint16_t"
Function,+,onewire_host_reset,_Bool,OneWireHost*
Function,+,onewire_host_reset_search,void,OneWireHost*
Function,+,onewire_host_search,uint8_t,"OneWireHost*, uint8_t*, OneWireHostSearchMode"
Function,+,onewire_host_skip,void,OneWireHost*
Function,+,onewire_host_start,void,OneWireHost*
Function,+,onewire_host_stop,void,OneWireHost*
Function,+,onewire_host_target_search,void,"OneWireHost*, uint8_t"
Function,+,onewire_host_write,void,"OneWireHost*, uint8_t"
Function,+,onewire_host_write_bit,void,"OneWireHost*, _Bool"
Function,+,onewire_host_write_bytes,void,"OneWireHost*, const uint8_t*, uint16_t"
Function,+,onewire_slave_alloc,OneWireSlave*,const GpioPin*
Function,+,onewire_slave_free,void,OneWireSlave*
Function,+,onewire_slave_receive,_Bool,"OneWireSlave*, uint8_t*, size_t"
Function,+,onewire_slave_receive_bit,_Bool,OneWireSlave*
Function,+,onewire_slave_send,_Bool,"OneWireSlave*, const uint8_t*, size_t"
Function,+,onewire_slave_send_bit,_Bool,"OneWireSlave*, _Bool"
Function,+,onewire_slave_set_command_callback,void,"OneWireSlave*, OneWireSlaveCommandCallback, void*"
Function,+,onewire_slave_set_reset_callback,void,"OneWireSlave*, OneWireSlaveResetCallback, void*"
Function,+,onewire_slave_set_result_callback,void,"OneWireSlave*, OneWireSlaveResultCallback, void*"
Function,+,onewire_slave_start,void,OneWireSlave*
Function,+,onewire_slave_stop,void,OneWireSlave*
Function,-,open_memstream,FILE*,"char**, size_t*"
Function,+,path_append,void,"FuriString*, const char*"
Function,+,path_concat,void,"const char*, const char*, FuriString*"
1 entry status name type params
151 Header + lib/mlib/m-rbtree.h
152 Header + lib/mlib/m-tuple.h
153 Header + lib/mlib/m-variant.h
154 Header + lib/one_wire/maxim_crc.h
155 Header + lib/one_wire/one_wire_host.h
156 Header + lib/one_wire/one_wire_host_timing.h
157 Header + lib/one_wire/one_wire_slave.h
158 Header + lib/print/wrappers.h
159 Header + lib/toolbox/args.h
160 Header + lib/toolbox/crc32_calc.h
1398 Function + manchester_encoder_advance _Bool ManchesterEncoderState*, const _Bool, ManchesterEncoderResult*
1399 Function + manchester_encoder_finish ManchesterEncoderResult ManchesterEncoderState*
1400 Function + manchester_encoder_reset void ManchesterEncoderState*
1401 Function + maxim_crc8 uint8_t const uint8_t*, const uint8_t, const uint8_t
1402 Function - mbedtls_des3_crypt_cbc int mbedtls_des3_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*
1403 Function - mbedtls_des3_crypt_ecb int mbedtls_des3_context*, const unsigned char[8], unsigned char[8]
1404 Function - mbedtls_des3_free void mbedtls_des3_context*
1477 Function + notification_message_block void NotificationApp*, const NotificationSequence*
1478 Function - nrand48 long unsigned short[3]
1479 Function - on_exit int void (*)(int, void*), void*
1480 Function + onewire_host_alloc OneWireHost* const GpioPin*
1481 Function + onewire_host_free void OneWireHost*
1482 Function + onewire_host_read uint8_t OneWireHost*
1483 Function + onewire_host_read_bit _Bool OneWireHost*
1484 Function + onewire_host_read_bytes void OneWireHost*, uint8_t*, uint16_t
1485 Function + onewire_host_reset _Bool OneWireHost*
1486 Function + onewire_host_reset_search void OneWireHost*
1487 Function + onewire_host_search uint8_t OneWireHost*, uint8_t*, OneWireHostSearchMode
1488 Function + onewire_host_skip void OneWireHost*
1489 Function + onewire_host_start void OneWireHost*
1490 Function + onewire_host_stop void OneWireHost*
1491 Function + onewire_host_target_search void OneWireHost*, uint8_t
1492 Function + onewire_host_write void OneWireHost*, uint8_t
1493 Function + onewire_host_write_bit void OneWireHost*, _Bool
1494 Function + onewire_host_write_bytes void OneWireHost*, const uint8_t*, uint16_t
1495 Function + onewire_slave_alloc OneWireSlave* const GpioPin*
1496 Function + onewire_slave_free void OneWireSlave*
1497 Function + onewire_slave_receive _Bool OneWireSlave*, uint8_t*, size_t
1498 Function + onewire_slave_receive_bit _Bool OneWireSlave*
1499 Function + onewire_slave_send _Bool OneWireSlave*, const uint8_t*, size_t
1500 Function + onewire_slave_send_bit _Bool OneWireSlave*, _Bool
1501 Function + onewire_slave_set_command_callback void OneWireSlave*, OneWireSlaveCommandCallback, void*
1502 Function + onewire_slave_set_reset_callback void OneWireSlave*, OneWireSlaveResetCallback, void*
1503 Function + onewire_slave_set_result_callback void OneWireSlave*, OneWireSlaveResultCallback, void*
1504 Function + onewire_slave_start void OneWireSlave*
1505 Function + onewire_slave_stop void OneWireSlave*
1506 Function - open_memstream FILE* char**, size_t*
1507 Function + path_append void FuriString*, const char*
1508 Function + path_concat void const char*, const char*, FuriString*

View File

@@ -3,8 +3,6 @@
#include <stm32wbxx_ll_cortex.h>
#include <fatfs.h>
#define TAG "FuriHal"
void furi_hal_init_early() {
@@ -74,10 +72,6 @@ void furi_hal_init() {
#endif
furi_hal_bt_init();
furi_hal_compress_icon_init();
// FatFS driver initialization
fatfs_init();
FURI_LOG_I(TAG, "FATFS OK");
}
void furi_hal_switch(void* address) {

View File

@@ -24,6 +24,7 @@
"usb_stm32",
"appframe",
"assets",
"one_wire",
"misc",
"flipper_application",
"flipperformat",
@@ -45,11 +46,11 @@
"furi_hal_subghz_configs.h"
],
"excluded_modules": [
"one_wire",
"nfc",
"lfrfid",
"subghz",
"ibutton",
"infrared",
"st25rfal002"
]
}
}

View File

@@ -121,6 +121,9 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,,
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
Header,+,lib/flipper_format/flipper_format.h,,
Header,+,lib/flipper_format/flipper_format_i.h,,
Header,+,lib/ibutton/ibutton_key.h,,
Header,+,lib/ibutton/ibutton_protocols.h,,
Header,+,lib/ibutton/ibutton_worker.h,,
Header,+,lib/infrared/encoder_decoder/infrared.h,,
Header,+,lib/infrared/worker/infrared_transmit.h,,
Header,+,lib/infrared/worker/infrared_worker.h,,
@@ -170,9 +173,6 @@ Header,+,lib/mlib/m-rbtree.h,,
Header,+,lib/mlib/m-tuple.h,,
Header,+,lib/mlib/m-variant.h,,
Header,+,lib/nfc/nfc_device.h,,
Header,+,lib/one_wire/ibutton/ibutton_key.h,,
Header,+,lib/one_wire/ibutton/ibutton_protocols.h,,
Header,+,lib/one_wire/ibutton/ibutton_worker.h,,
Header,+,lib/one_wire/maxim_crc.h,,
Header,+,lib/one_wire/one_wire_host.h,,
Header,+,lib/one_wire/one_wire_host_timing.h,,
1 entry status name type params
121 Header + lib/flipper_application/plugins/plugin_manager.h
122 Header + lib/flipper_format/flipper_format.h
123 Header + lib/flipper_format/flipper_format_i.h
124 Header + lib/ibutton/ibutton_key.h
125 Header + lib/ibutton/ibutton_protocols.h
126 Header + lib/ibutton/ibutton_worker.h
127 Header + lib/infrared/encoder_decoder/infrared.h
128 Header + lib/infrared/worker/infrared_transmit.h
129 Header + lib/infrared/worker/infrared_worker.h
173 Header + lib/mlib/m-tuple.h
174 Header + lib/mlib/m-variant.h
175 Header + lib/nfc/nfc_device.h
Header + lib/one_wire/ibutton/ibutton_key.h
Header + lib/one_wire/ibutton/ibutton_protocols.h
Header + lib/one_wire/ibutton/ibutton_worker.h
176 Header + lib/one_wire/maxim_crc.h
177 Header + lib/one_wire/one_wire_host.h
178 Header + lib/one_wire/one_wire_host_timing.h

View File

@@ -1,21 +1,3 @@
/**
******************************************************************************
* @file fatfs.c
* @brief Code for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "fatfs.h"
/** logical drive path */
@@ -35,5 +17,3 @@ void fatfs_init(void) {
DWORD get_fattime(void) {
return 0;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -1,21 +1,3 @@
/**
******************************************************************************
* @file fatfs.h
* @brief Header for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#pragma once
#include "fatfs/ff.h"
@@ -34,6 +16,4 @@ void fatfs_init(void);
#ifdef __cplusplus
}
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#endif

View File

@@ -1,21 +1,3 @@
/**
******************************************************************************
* @file user_diskio.c
* @brief This file includes a diskio driver skeleton to be completed by the user.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "user_diskio.h"
#include <furi_hal.h>
#include "sector_cache.h"
@@ -287,5 +269,3 @@ static DRESULT driver_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
return res;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -1,22 +1,3 @@
/**
******************************************************************************
* @file user_diskio.h
* @brief This file contains the common defines and functions prototypes for
* the user_diskio driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#pragma once
#ifdef __cplusplus

View File

@@ -4,8 +4,6 @@
#include <stm32wbxx_ll_cortex.h>
#include <fatfs.h>
#define TAG "FuriHal"
void furi_hal_init_early() {
@@ -80,10 +78,6 @@ void furi_hal_init() {
furi_hal_nfc_init();
furi_hal_rfid_init();
#endif
// FatFS driver initialization
fatfs_init();
FURI_LOG_I(TAG, "FATFS OK");
}
void furi_hal_switch(void* address) {

View File

@@ -35,6 +35,7 @@
"appframe",
"assets",
"one_wire",
"ibutton",
"misc",
"mbedtls",
"lfrfid",
@@ -42,4 +43,4 @@
"flipperformat",
"toolbox"
]
}
}

View File

@@ -88,6 +88,7 @@ libs = env.BuildModules(
"fatfs",
"flipper_format",
"one_wire",
"ibutton",
"infrared",
"littlefs",
"mbedtls",

View File

@@ -830,8 +830,9 @@ void elf_file_init_debug_info(ELFFile* elf, ELFDebugInfo* debug_info) {
const void* data_ptr = itref->value.data;
if(data_ptr) {
debug_info->mmap_entries[mmap_entry_idx].address = (uint32_t)data_ptr;
debug_info->mmap_entries[mmap_entry_idx].name = itref->key;
ELFMemoryMapEntry* entry = &debug_info->mmap_entries[mmap_entry_idx];
entry->address = (uint32_t)data_ptr;
entry->name = itref->key;
mmap_entry_idx++;
}
}

View File

@@ -3,7 +3,9 @@
#include <notification/notification_messages.h>
#include "application_assets.h"
#define TAG "fapp"
#include <m-list.h>
#define TAG "Fap"
struct FlipperApplication {
ELFDebugInfo state;
@@ -13,8 +15,39 @@ struct FlipperApplication {
void* ep_thread_args;
};
/* For debugger access to app state */
FlipperApplication* last_loaded_app = NULL;
/********************** Debugger access to loader state **********************/
LIST_DEF(FlipperApplicationList, const FlipperApplication*, M_POD_OPLIST);
FlipperApplicationList_t flipper_application_loaded_app_list = {0};
static bool flipper_application_loaded_app_list_initialized = false;
static void flipper_application_list_add_app(const FlipperApplication* app) {
furi_assert(app);
if(!flipper_application_loaded_app_list_initialized) {
FlipperApplicationList_init(flipper_application_loaded_app_list);
flipper_application_loaded_app_list_initialized = true;
}
FlipperApplicationList_push_back(flipper_application_loaded_app_list, app);
}
static void flipper_application_list_remove_app(const FlipperApplication* app) {
furi_assert(flipper_application_loaded_app_list_initialized);
furi_assert(app);
FlipperApplicationList_it_t it;
for(FlipperApplicationList_it(it, flipper_application_loaded_app_list);
!FlipperApplicationList_end_p(it);
FlipperApplicationList_next(it)) {
if(*FlipperApplicationList_ref(it) == app) {
FlipperApplicationList_remove(flipper_application_loaded_app_list, it);
break;
}
}
}
/*****************************************************************************/
FlipperApplication*
flipper_application_alloc(Storage* storage, const ElfApiInterface* api_interface) {
@@ -37,8 +70,8 @@ void flipper_application_free(FlipperApplication* app) {
furi_thread_free(app->thread);
}
if(!flipper_application_is_plugin(app)) {
last_loaded_app = NULL;
if(app->state.entry) {
flipper_application_list_remove_app(app);
}
elf_file_clear_debug_info(&app->state);
@@ -153,14 +186,12 @@ const FlipperApplicationManifest* flipper_application_get_manifest(FlipperApplic
}
FlipperApplicationLoadStatus flipper_application_map_to_memory(FlipperApplication* app) {
if(!flipper_application_is_plugin(app)) {
last_loaded_app = app;
}
ELFFileLoadStatus status = elf_file_load_sections(app->elf);
switch(status) {
case ELFFileLoadStatusSuccess:
elf_file_init_debug_info(app->elf, &app->state);
flipper_application_list_add_app(app);
return FlipperApplicationLoadStatusSuccess;
case ELFFileLoadStatusNoFreeMemory:
return FlipperApplicationLoadStatusNoFreeMemory;

24
lib/ibutton/SConscript Normal file
View File

@@ -0,0 +1,24 @@
Import("env")
env.Append(
LINT_SOURCES=[
Dir("."),
],
CPPPATH=[
"#/lib/ibutton",
],
SDK_HEADERS=[
File("ibutton_key.h"),
File("ibutton_worker.h"),
File("ibutton_protocols.h"),
],
)
libenv = env.Clone(FW_LIB_NAME="ibutton")
libenv.ApplyLibFlags()
sources = libenv.GlobRecursive("*.c*")
lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources)
libenv.Install("${LIB_DIST_DIR}", lib)
Return("lib")

View File

@@ -11,9 +11,6 @@ env.Append(
File("one_wire_host_timing.h"),
File("one_wire_host.h"),
File("one_wire_slave.h"),
File("ibutton/ibutton_key.h"),
File("ibutton/ibutton_worker.h"),
File("ibutton/ibutton_protocols.h"),
File("maxim_crc.h"),
],
)

View File

@@ -455,7 +455,7 @@ uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) {
uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) {
furi_assert(instance);
if(idx < FrequencyList_size(instance->frequencies)) {
if(idx < FrequencyList_size(instance->hopper_frequencies)) {
return *FrequencyList_get(instance->hopper_frequencies, idx);
} else {
return 0;

View File

@@ -1,6 +1,7 @@
import logging
import os
import typing
from enum import Enum
from flipper.utils.programmer import Programmer
from flipper.utils.openocd import OpenOCD
@@ -8,6 +9,14 @@ from flipper.utils.stm32wb55 import STM32WB55
from flipper.assets.obdata import OptionBytesData
class OpenOCDProgrammerResult(Enum):
Success = 0
ErrorGeneric = 1
ErrorAlignment = 2
ErrorAlreadyWritten = 3
ErrorValidation = 4
class OpenOCDProgrammer(Programmer):
def __init__(
self,
@@ -199,18 +208,18 @@ class OpenOCDProgrammer(Programmer):
return True
def otp_write(self, address: int, file_path: str) -> bool:
def otp_write(self, address: int, file_path: str) -> OpenOCDProgrammerResult:
# Open file, check that it aligned to 8 bytes
with open(file_path, "rb") as f:
data = f.read()
if len(data) % 8 != 0:
self.logger.error(f"File {file_path} is not aligned to 8 bytes")
return False
return OpenOCDProgrammerResult.ErrorAlignment
# Check that address is aligned to 8 bytes
if address % 8 != 0:
self.logger.error(f"Address {address} is not aligned to 8 bytes")
return False
return OpenOCDProgrammerResult.ErrorAlignment
# Get size of data
data_size = len(data)
@@ -218,7 +227,7 @@ class OpenOCDProgrammer(Programmer):
# Check that data size is aligned to 8 bytes
if data_size % 8 != 0:
self.logger.error(f"Data size {data_size} is not aligned to 8 bytes")
return False
return OpenOCDProgrammerResult.ErrorAlignment
self.logger.debug(f"Writing {data_size} bytes to OTP at {address:08X}")
self.logger.debug(f"Data: {data.hex().upper()}")
@@ -241,14 +250,14 @@ class OpenOCDProgrammer(Programmer):
self.logger.error(
f"OTP memory at {address + i:08X} is not empty: {device_word:08X}"
)
raise Exception("OTP memory is not empty")
return OpenOCDProgrammerResult.ErrorAlreadyWritten
if device_word != file_word:
already_written = False
if already_written:
self.logger.info(f"OTP memory is already written with the given data")
return True
return OpenOCDProgrammerResult.Success
self.reset(self.RunMode.Stop)
stm32.clear_flash_errors(oocd)
@@ -278,4 +287,8 @@ class OpenOCDProgrammer(Programmer):
stm32.reset(oocd, stm32.RunMode.Run)
oocd.stop()
return validation_result
return (
OpenOCDProgrammerResult.Success
if validation_result
else OpenOCDProgrammerResult.ErrorValidation
)

View File

@@ -34,8 +34,16 @@ OTP_DISPLAYS = {
}
from flipper.app import App
from flipper.cube import CubeProgrammer
from flipper.utils.programmer_openocd import OpenOCDProgrammer
from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
class OTPException(Exception):
def __init__(self, message: str, result: OpenOCDProgrammerResult):
self.message = message
self.result = result
def get_exit_code(self) -> int:
return int(self.result.value)
class Main(App):
@@ -183,13 +191,14 @@ class Main(App):
self.args.serial,
)
if not openocd.otp_write(0x1FFF7000, filename):
raise Exception("Failed to flash OTP")
programmer_result = openocd.otp_write(0x1FFF7000, filename)
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
except Exception as e:
except OTPException as e:
self.logger.exception(e)
return 1
return e.get_exit_code()
finally:
os.remove(filename)
@@ -215,13 +224,14 @@ class Main(App):
self.args.serial,
)
if not openocd.otp_write(0x1FFF7010, filename):
raise Exception("Failed to flash OTP")
programmer_result = openocd.otp_write(0x1FFF7010, filename)
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
except Exception as e:
except OTPException as e:
self.logger.exception(e)
return 1
return e.get_exit_code()
finally:
os.remove(filename)
@@ -249,13 +259,14 @@ class Main(App):
self.args.serial,
)
if not openocd.otp_write(0x1FFF7000, filename):
raise Exception("Failed to flash OTP")
programmer_result = openocd.otp_write(0x1FFF7000, filename)
if programmer_result != OpenOCDProgrammerResult.Success:
raise OTPException("Failed to flash OTP", programmer_result)
self.logger.info(f"Flashed Successfully")
except Exception as e:
except OTPException as e:
self.logger.exception(e)
return 1
return e.get_exit_code()
finally:
os.remove(filename)