mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
Merge branch 'dev' into nestednonces
This commit is contained in:
@@ -430,13 +430,11 @@ static void bt_change_profile(Bt* bt, BtMessage* message) {
|
||||
*message->profile_instance = NULL;
|
||||
}
|
||||
}
|
||||
if(message->lock) api_lock_unlock(message->lock);
|
||||
}
|
||||
|
||||
static void bt_close_connection(Bt* bt, BtMessage* message) {
|
||||
static void bt_close_connection(Bt* bt) {
|
||||
bt_close_rpc_connection(bt);
|
||||
furi_hal_bt_stop_advertising();
|
||||
if(message->lock) api_lock_unlock(message->lock);
|
||||
}
|
||||
|
||||
static void bt_apply_settings(Bt* bt) {
|
||||
@@ -484,19 +482,13 @@ static void bt_load_settings(Bt* bt) {
|
||||
}
|
||||
|
||||
static void bt_handle_get_settings(Bt* bt, BtMessage* message) {
|
||||
furi_assert(message->lock);
|
||||
*message->data.settings = bt->bt_settings;
|
||||
api_lock_unlock(message->lock);
|
||||
}
|
||||
|
||||
static void bt_handle_set_settings(Bt* bt, BtMessage* message) {
|
||||
furi_assert(message->lock);
|
||||
bt->bt_settings = *message->data.csettings;
|
||||
|
||||
bt_apply_settings(bt);
|
||||
bt_settings_save(&bt->bt_settings);
|
||||
|
||||
api_lock_unlock(message->lock);
|
||||
}
|
||||
|
||||
static void bt_handle_reload_keys_settings(Bt* bt) {
|
||||
@@ -548,6 +540,12 @@ int32_t bt_srv(void* p) {
|
||||
while(1) {
|
||||
furi_check(
|
||||
furi_message_queue_get(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk);
|
||||
FURI_LOG_D(
|
||||
TAG,
|
||||
"call %d, lock 0x%p, result 0x%p",
|
||||
message.type,
|
||||
(void*)message.lock,
|
||||
(void*)message.result);
|
||||
if(message.type == BtMessageTypeUpdateStatus) {
|
||||
// Update view ports
|
||||
bt_statusbar_update(bt);
|
||||
@@ -571,7 +569,7 @@ int32_t bt_srv(void* p) {
|
||||
} else if(message.type == BtMessageTypeSetProfile) {
|
||||
bt_change_profile(bt, &message);
|
||||
} else if(message.type == BtMessageTypeDisconnect) {
|
||||
bt_close_connection(bt, &message);
|
||||
bt_close_connection(bt);
|
||||
} else if(message.type == BtMessageTypeForgetBondedDevices) {
|
||||
bt_keys_storage_delete(bt->keys_storage);
|
||||
} else if(message.type == BtMessageTypeGetSettings) {
|
||||
@@ -581,6 +579,8 @@ int32_t bt_srv(void* p) {
|
||||
} else if(message.type == BtMessageTypeReloadKeysSettings) {
|
||||
bt_handle_reload_keys_settings(bt);
|
||||
}
|
||||
|
||||
if(message.lock) api_lock_unlock(message.lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -54,11 +54,14 @@ bool dialogs_app_process_module_file_browser(const DialogsAppMessageDataFileBrow
|
||||
ret = file_browser_context->result;
|
||||
|
||||
view_holder_set_view(view_holder, NULL);
|
||||
view_holder_free(view_holder);
|
||||
file_browser_stop(file_browser);
|
||||
|
||||
file_browser_free(file_browser);
|
||||
view_holder_free(view_holder);
|
||||
|
||||
api_lock_free(file_browser_context->lock);
|
||||
free(file_browser_context);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -67,7 +67,7 @@ static RpcSystemCallbacks rpc_systems[] = {
|
||||
struct RpcSession {
|
||||
Rpc* rpc;
|
||||
|
||||
FuriThreadId thread_id;
|
||||
FuriThread* thread;
|
||||
|
||||
RpcHandlerDict_t handlers;
|
||||
FuriStreamBuffer* stream;
|
||||
@@ -172,7 +172,7 @@ size_t rpc_session_feed(
|
||||
|
||||
size_t bytes_sent = furi_stream_buffer_send(session->stream, encoded_bytes, size, timeout);
|
||||
|
||||
furi_thread_flags_set(session->thread_id, RpcEvtNewData);
|
||||
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData);
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
|
||||
break;
|
||||
} else {
|
||||
/* Save disconnect flag and continue reading buffer */
|
||||
furi_thread_flags_set(session->thread_id, RpcEvtDisconnect);
|
||||
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtDisconnect);
|
||||
}
|
||||
} else if(flags & RpcEvtNewData) {
|
||||
// Just wake thread up
|
||||
@@ -347,32 +347,37 @@ static int32_t rpc_session_worker(void* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rpc_session_thread_release_callback(
|
||||
FuriThread* thread,
|
||||
FuriThreadState thread_state,
|
||||
void* context) {
|
||||
if(thread_state == FuriThreadStateStopped) {
|
||||
RpcSession* session = (RpcSession*)context;
|
||||
static void rpc_session_thread_pending_callback(void* context, uint32_t arg) {
|
||||
UNUSED(arg);
|
||||
RpcSession* session = (RpcSession*)context;
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) {
|
||||
if(rpc_systems[i].free) {
|
||||
(rpc_systems[i].free)(session->system_contexts[i]);
|
||||
}
|
||||
for(size_t i = 0; i < COUNT_OF(rpc_systems); ++i) {
|
||||
if(rpc_systems[i].free) {
|
||||
(rpc_systems[i].free)(session->system_contexts[i]);
|
||||
}
|
||||
free(session->system_contexts);
|
||||
free(session->decoded_message);
|
||||
RpcHandlerDict_clear(session->handlers);
|
||||
furi_stream_buffer_free(session->stream);
|
||||
}
|
||||
free(session->system_contexts);
|
||||
free(session->decoded_message);
|
||||
RpcHandlerDict_clear(session->handlers);
|
||||
furi_stream_buffer_free(session->stream);
|
||||
|
||||
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
|
||||
if(session->terminated_callback) {
|
||||
session->terminated_callback(session->context);
|
||||
}
|
||||
furi_mutex_release(session->callbacks_mutex);
|
||||
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
|
||||
if(session->terminated_callback) {
|
||||
session->terminated_callback(session->context);
|
||||
}
|
||||
furi_mutex_release(session->callbacks_mutex);
|
||||
|
||||
furi_mutex_free(session->callbacks_mutex);
|
||||
furi_thread_free(thread);
|
||||
free(session);
|
||||
furi_mutex_free(session->callbacks_mutex);
|
||||
furi_thread_join(session->thread);
|
||||
furi_thread_free(session->thread);
|
||||
free(session);
|
||||
}
|
||||
|
||||
static void
|
||||
rpc_session_thread_state_callback(FuriThread* thread, FuriThreadState state, void* context) {
|
||||
UNUSED(thread);
|
||||
if(state == FuriThreadStateStopped) {
|
||||
furi_timer_pending_callback(rpc_session_thread_pending_callback, context, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,14 +409,12 @@ RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) {
|
||||
};
|
||||
rpc_add_handler(session, PB_Main_stop_session_tag, &rpc_handler);
|
||||
|
||||
FuriThread* thread =
|
||||
furi_thread_alloc_ex("RpcSessionWorker", 3072, rpc_session_worker, session);
|
||||
session->thread_id = furi_thread_get_id(thread);
|
||||
session->thread = furi_thread_alloc_ex("RpcSessionWorker", 3072, rpc_session_worker, session);
|
||||
|
||||
furi_thread_set_state_context(thread, session);
|
||||
furi_thread_set_state_callback(thread, rpc_session_thread_release_callback);
|
||||
furi_thread_set_state_context(session->thread, session);
|
||||
furi_thread_set_state_callback(session->thread, rpc_session_thread_state_callback);
|
||||
|
||||
furi_thread_start(thread);
|
||||
furi_thread_start(session->thread);
|
||||
|
||||
return session;
|
||||
}
|
||||
@@ -423,7 +426,7 @@ void rpc_session_close(RpcSession* session) {
|
||||
rpc_session_set_send_bytes_callback(session, NULL);
|
||||
rpc_session_set_close_callback(session, NULL);
|
||||
rpc_session_set_buffer_is_empty_callback(session, NULL);
|
||||
furi_thread_flags_set(session->thread_id, RpcEvtDisconnect);
|
||||
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtDisconnect);
|
||||
}
|
||||
|
||||
void rpc_on_system_start(void* p) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#define TAG "HidMouseClicker"
|
||||
|
||||
#define DEFAULT_CLICK_RATE 1
|
||||
#define MAXIMUM_CLICK_RATE 60
|
||||
#define MAXIMUM_CLICK_RATE 100
|
||||
|
||||
struct HidMouseClicker {
|
||||
View* view;
|
||||
@@ -34,7 +34,9 @@ static void hid_mouse_clicker_start_or_restart_timer(void* context) {
|
||||
HidMouseClickerModel * model,
|
||||
{
|
||||
furi_timer_start(
|
||||
hid_mouse_clicker->timer, furi_kernel_get_tick_frequency() / model->rate);
|
||||
hid_mouse_clicker->timer,
|
||||
furi_kernel_get_tick_frequency() /
|
||||
((model->rate) ? model->rate : MAXIMUM_CLICK_RATE));
|
||||
},
|
||||
true);
|
||||
}
|
||||
@@ -75,7 +77,11 @@ static void hid_mouse_clicker_draw_callback(Canvas* canvas, void* context) {
|
||||
|
||||
// Clicks/s
|
||||
char label[20];
|
||||
snprintf(label, sizeof(label), "%d clicks/s", model->rate);
|
||||
if(model->rate) {
|
||||
snprintf(label, sizeof(label), "%d clicks/s", model->rate);
|
||||
} else {
|
||||
snprintf(label, sizeof(label), "max clicks/s");
|
||||
}
|
||||
elements_multiline_text_aligned(canvas, 28, 37, AlignCenter, AlignBottom, label);
|
||||
|
||||
canvas_draw_icon(canvas, 25, 20, &I_ButtonUp_7x4);
|
||||
@@ -139,7 +145,7 @@ static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) {
|
||||
consumed = true;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
if(model->rate > 1) {
|
||||
if(model->rate > 0) {
|
||||
model->rate--;
|
||||
}
|
||||
rate_changed = true;
|
||||
|
||||
88
documentation/devboard/Debugging via the Devboard.md
Normal file
88
documentation/devboard/Debugging via the Devboard.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Debugging via the Devboard {#dev_board_debugging_guide}
|
||||
|
||||
On this page, you'll learn about how debugging via the Wi-Fi Developer Board works. To illustrate this process, we'll start a debug session for Flipper Zero's firmware in VS Code using the native Flipper Build Tool.
|
||||
|
||||
***
|
||||
|
||||
## Overview
|
||||
|
||||
The Developer Board acts as the debug probe, which provides a bridge between the IDE (integrated development environment) with a debugger running on a host computer and the target microcontroller (in your Flipper Zero). The user controls the debugging process on the computer connected to the Developer Board via [Wi-Fi](#dev_board_wifi_connection) or [USB cable](#dev_board_usb_connection).
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_hardware_CDN.jpg width=700
|
||||
|
||||
Data exchange between the Wi-Fi Developer Board and your Flipper Zero is conducted via the Serial Wire Debug interface. The following GPIO pins serve this purpose:
|
||||
|
||||
- **Pin 10:** Serial Wire Clock (SWCLK)
|
||||
|
||||
- **Pin 12:** Serial Wire Debug Data I/O (SWDIO)
|
||||
|
||||
To learn more about Flipper Zero pinout, visit [GPIO & modules in Flipper Docs](https://docs.flipper.net/gpio-and-modules).
|
||||
|
||||
***
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Step 1. Installing Git
|
||||
|
||||
You'll need Git installed on your computer to clone the firmware repository. If you don't have Git, install it following the [official installation guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
|
||||
|
||||
### Step 2. Building the firmware
|
||||
|
||||
Before starting debugging, you need to clone and build Flipper Zero firmware:
|
||||
|
||||
1. Open the **Terminal** (on Linux & macOS) or **PowerShell** (on Windows) in the directory where you want to store the firmware source code.
|
||||
|
||||
2. Clone the firmware repository:
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
|
||||
cd flipperzero-firmware
|
||||
```
|
||||
|
||||
3. Run the **Flipper Build Tool (FBT)** to build the firmware:
|
||||
|
||||
```
|
||||
./fbt
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
## Debugging the firmware
|
||||
|
||||
From the **flipperzero-firmware** directory that you cloned earlier, run the following command:
|
||||
|
||||
```
|
||||
./fbt flash
|
||||
```
|
||||
|
||||
This will upload the firmware you've just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware. We recommend using **VS Code** with the recommended extensions (as described below), and we have pre-made configurations for it.
|
||||
|
||||
To debug in **VS Code**, do the following:
|
||||
|
||||
1. In VS Code, open the **flipperzero-firmware** directory.
|
||||
|
||||
2. You should see a notification about recommended extensions. Install them.
|
||||
|
||||
If there were no notifications, open the **Extensions** tab, enter `@recommended` in the search bar, and install the workspace recommendations.
|
||||
|
||||
3. Run the `./fbt vscode_dist` command. This will generate the VS Code configuration files needed for debugging.
|
||||
|
||||
4. In VS Code, open the **Run and Debug** tab and select a debugger from the dropdown menu:
|
||||
|
||||
- **Attach FW (blackmagic):** Can be used via **Wi-Fi** or **USB**
|
||||
- **Attach FW (DAP):** Can be used via **USB** only
|
||||
|
||||
Note that when debugging via USB, you need to make sure the selected debugger matches the debug mode on your Devboard. To check the debug mode on your Devboard, access the Devboard's web interface as described [here](#dev_board_wifi_connection) and check the **USB mode** field. If you want to use a different debug mode, enable this mode by following the steps in [Devboard debug modes](#dev_board_debug_modes).
|
||||
|
||||
5. If needed, flash your Flipper Zero with the `./fbt flash` command, then click the ▷ **Start Debugging** button in the debug sidebar to start the debugging session.
|
||||
|
||||
6. Note that starting a debug session halts the execution of the firmware, so you'll need to click the I▷ **Continue** button on the toolbar at the top of your VS Code window to continue execution.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_VS_Code.jpg width=900
|
||||
|
||||
> [!note]
|
||||
> If you want to use a different debug mode on your Developer Board, visit [Devboard debug modes](#dev_board_debug_modes).
|
||||
>
|
||||
> If you want to read logs via the Developer Board, see [Reading logs via the Devboard](#dev_board_reading_logs).
|
||||
>
|
||||
> To learn about debugging in VS Code, see [VS Code official guide](https://code.visualstudio.com/docs/editor/debugging).
|
||||
33
documentation/devboard/Devboard debug modes.md
Normal file
33
documentation/devboard/Devboard debug modes.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Devboard debug modes {#dev_board_debug_modes}
|
||||
|
||||
The Wi-Fi Devboard for Flipper Zero supports **Black Magic** and **DAPLink** debug modes, and you can switch between them depending on your needs. Note that available modes depend on connection:
|
||||
|
||||
- **Wi-Fi:** Only **Black Magic** mode is available.
|
||||
- **USB:** Switch between **Black Magic** (default) and **DAPLink**. Learn more about switching debug modes for USB connection below.
|
||||
|
||||
> [!note]
|
||||
> Black Magic mode doesn't support RTOS threads, but you can still perform other debugging operations.
|
||||
|
||||
***
|
||||
|
||||
## Switching debug modes for USB connection
|
||||
|
||||
Switching debug modes for working via USB has to be done wirelessly (yes, you read that correctly). Additionally, depending on how the Devboard wireless connection is configured, you may need to follow different steps for **Wi-Fi access point mode** or **Wi-Fi client mode**:
|
||||
|
||||
1. If the Devboard isn't connected to your Flipper Zero, turn off your Flipper Zero and connect the Developer Board, then turn the device back on.
|
||||
|
||||
2. Access the Devboard's web interface:
|
||||
|
||||
- [Wi-Fi access point mode](#wifi-access-point)
|
||||
|
||||
- [Wi-Fi client mode](#wifi-client-mode)
|
||||
|
||||
3. In the **WiFi** tab, click the **USB mode** option and select **BlackMagicProbe** or **DapLink**.
|
||||
|
||||
4. Click **SAVE**, then click **REBOOT** to apply the changes.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_switching_modes_CDN.jpg width=700
|
||||
|
||||
> [!note]
|
||||
> After switching debug modes on your Devboard, remember to select the same debugger in **VS Code** in the **Run and Debug** tab, and click the ▷ **Start Debugging** button.
|
||||
|
||||
@@ -1,122 +1,112 @@
|
||||
# Firmware update on Developer Board {#dev_board_fw_update}
|
||||
|
||||
It's important to regularly update your Developer Board to ensure that you have access to the latest features and bug fixes. This tutorial will guide you through the necessary steps to update the firmware of your Developer Board.
|
||||
It's important to regularly update your Developer Board to ensure that you have access to the latest features and bug fixes. This page will guide you through the necessary steps to update the firmware of your Developer Board.
|
||||
|
||||
This tutorial assumes that you're familiar with the basics of the command line. If you’re not, please refer to the [Windows](https://www.digitalcitizen.life/command-prompt-how-use-basic-commands/) or [MacOS/Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
|
||||
> [!note]
|
||||
> This guide assumes that you're familiar with the basics of the command line. If you're new to it, we recommend checking out these [Windows](https://learn.microsoft.com/en-us/powershell/scripting/learn/ps101/01-getting-started?view=powershell-7.4) or [macOS/Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
|
||||
|
||||
***
|
||||
|
||||
## Installing the micro Flipper Build Tool
|
||||
## Step 1. Install the micro Flipper Build Tool
|
||||
|
||||
Micro Flipper Build Tool (uFBT) is a cross-platform tool that enables basic development tasks for Flipper Zero, such as building and debugging applications, flashing firmware, and creating VS Code development configurations.
|
||||
is a cross-platform tool developed and supported by our team that enables basic development tasks for Flipper Zero, such as building and debugging applications, flashing firmware, creating VS Code development configurations, and flashing firmware to the Wi-Fi Developer Board.
|
||||
|
||||
Install uFBT on your computer by running the following command in the Terminal:
|
||||
**On Linux & macOS:**
|
||||
|
||||
**For Linux & macOS:**
|
||||
Run the following command in the Terminal:
|
||||
|
||||
```text
|
||||
```
|
||||
python3 -m pip install --upgrade ufbt
|
||||
```
|
||||
|
||||
**For Windows:**
|
||||
**On Windows:**
|
||||
|
||||
```text
|
||||
py -m pip install --upgrade ufbt
|
||||
```
|
||||
1. Download the latest version of Python on
|
||||
2. Run the following command in the PowerShell
|
||||
|
||||
If you want to learn more about uFBT, visit [the project's page](https://pypi.org/project/ufbt/).
|
||||
```
|
||||
py -m pip install --upgrade ufbt
|
||||
```
|
||||
|
||||
***
|
||||
|
||||
## Connecting the Developer Board to your computer
|
||||
## Step 2. Connect the Devboard to PC
|
||||
|
||||
To update the firmware, you need to switch your Developer Board to Bootloader mode, connect to a PC via a USB cable, and make sure that the PC detects the Developer Board:
|
||||
|
||||
1. List all of the serial devices on your computer.
|
||||
|
||||
**Windows**
|
||||
- **macOS:** Run the `ls /dev/cu.*` command in the Terminal.
|
||||
|
||||
On Windows, go to Device Manager and expand the Ports (COM & LPT) section.
|
||||
- **Linux:** Run the `ls /dev/tty*` command in the Terminal.
|
||||
|
||||
**macOS**
|
||||
|
||||
On macOS, you can run the following command in the Terminal:
|
||||
|
||||
```text
|
||||
ls /dev/cu.*
|
||||
```
|
||||
|
||||
**Linux**
|
||||
|
||||
On Linux, you can run the following command in the Terminal:
|
||||
|
||||
```text
|
||||
ls /dev/tty*
|
||||
```
|
||||
|
||||
View the devices in the list.
|
||||
- **Windows:** Go to **Device Manager** and expand the **Ports (COM & LPT)** section.
|
||||
|
||||
2. Connect the Developer Board to your computer using a USB-C cable.
|
||||

|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_update_wired_connection.jpg width=700
|
||||
|
||||
3. Switch your Developer Board to Bootloader mode:
|
||||
|
||||
3.1. Press and hold the **BOOT** button.
|
||||
1. Press and hold the **BOOT** button.
|
||||
2. Press the **RESET** button while holding the **BOOT** button.
|
||||
3. Release the **BOOT** button.
|
||||
|
||||
3.2. Press the **RESET** button while holding the **BOOT** button.
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot_to_bootloader.png width=700
|
||||
|
||||
3.3. Release the **BOOT** button.\
|
||||

|
||||
|
||||
4. Repeat Step 1 and view the name of your Developer Board that appeared in the list.
|
||||
|
||||
For example, on macOS:
|
||||
|
||||
```text
|
||||
/dev/cu.usbmodem01
|
||||
```
|
||||
4. Repeat **Step 1** and view the name of your Developer Board that appeared in the list.
|
||||
|
||||
***
|
||||
|
||||
## Flashing the firmware
|
||||
## Step 3. Flash the firmware
|
||||
|
||||
To flash the firmware onto your Developer Board, run the following command in the terminal:
|
||||
**On Linux & macOS:**
|
||||
|
||||
```text
|
||||
```
|
||||
python3 -m ufbt devboard_flash
|
||||
```
|
||||
|
||||
**On Windows:** Run the following command in the PowerShell:
|
||||
|
||||
```
|
||||
py -m ufbt devboard_flash
|
||||
```
|
||||
|
||||
You should see the following message: `WiFi board flashed successfully`.
|
||||
|
||||
## If flashing failed
|
||||
### If flashing failed
|
||||
|
||||
If you get an error message during the flashing process, such as this:
|
||||
Occasionally, you might get an error message during the flashing process, such as:
|
||||
|
||||
```text
|
||||
```
|
||||
A fatal error occurred: Serial data stream stopped: Possible serial noise or corruption.
|
||||
```
|
||||
|
||||
Or this:
|
||||
*or*
|
||||
|
||||
```text
|
||||
```
|
||||
FileNotFoundError: [Errno 2] No such file or directory: '/dev/cu.usbmodem01'
|
||||
```
|
||||
|
||||
Try doing the following:
|
||||
To fix it, try doing the following:
|
||||
|
||||
* Disconnect the Developer Board from your computer, then reconnect it.
|
||||
- Disconnect the Developer Board from your computer, then reconnect it. After that, switch your Developer Board to Bootloader mode once again, as described in
|
||||
|
||||
* Use a different USB port on your computer.
|
||||
- Use a different USB port on your computer.
|
||||
|
||||
* Use a different USB-C cable.
|
||||
- Use a different USB-C cable.
|
||||
|
||||
***
|
||||
|
||||
## Finishing the installation
|
||||
|
||||
After flashing the firmware:
|
||||
## Step 4. Finish the installation
|
||||
|
||||
1. Reboot the Developer Board by pressing the **RESET** button.
|
||||

|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot_after_flashing.jpg width=700
|
||||
|
||||
2. Disconnect and reconnect the USB-C cable.
|
||||
|
||||
The Developer Board should appear as a serial device on your computer. Now, you can use it with the Black Magic Debug client of your choice.
|
||||
You've successfully updated the firmware of your Developer Board!
|
||||
|
||||
If you followed the **Get started with the Devboard** guide, you're ready for the next step: [Step 3. Plug the Devboard into Flipper Zero](#dev_board_get_started_step-3).
|
||||
|
||||
|
||||
@@ -1,178 +1,80 @@
|
||||
# Get started with the Dev Board {#dev_board_get_started}
|
||||
|
||||
The Wi-Fi Developer Board serves as a tool to debug the Flipper Zero firmware. To debug the firmware, the initial step involves compiling the firmware from its source code. This process enables the debugging functionality within the firmware and generates all the necessary files required for debugging purposes.
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_developer_board_box_CDN.jpg width=700
|
||||
|
||||
> **NOTE:** Building and debugging the Flipper Zero firmware is fully supported on MacOS and Linux. Support for Windows is in beta test.
|
||||
Before you start using your Devboard, you need to prepare your Flipper Zero and Devboard for debugging. In this guide, we'll walk you through all the necessary steps and provide links to explore the Devboard's capabilities further.
|
||||
|
||||
***
|
||||
|
||||
## Updating the firmware of your Developer Board
|
||||
## Step 1. Enable Debug Mode on your Flipper Zero
|
||||
|
||||
Update the firmware of your Developer Board before using it. For more information, visit [Firmware update on Developer Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/update).
|
||||
Since the main purpose of the Developer board is to debug applications on Flipper Zero, you first need to enable Debug Mode. To do so, go to **Settings → System** and set **Debug** to **ON**.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_enamble_debug_CDN.jpg width=700
|
||||
|
||||
> [!note]
|
||||
> Debug Mode needs to be re-enabled after each update of Flipper Zero's firmware.
|
||||
|
||||
Debug Mode allows you to debug your apps for Flipper Zero, as well as access debugging options in apps via the user interface and CLI. To learn more about Flipper Zero CLI, visit [Command-line interface in Flipper Docs](https://docs.flipper.net/development/cli).
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Command_Line_Interface_CDN.jpg width=700
|
||||
|
||||
***
|
||||
|
||||
## Installing Git
|
||||
## Step 2. Update firmware on the Developer Board
|
||||
|
||||
You'll need Git installed on your computer to clone the firmware repository. If you don't have Git, install it by doing the following:
|
||||
|
||||
* **MacOS**
|
||||
|
||||
On MacOS, install the **Xcode Command Line Tools** package, which includes Git as one of the pre-installed command-line utilities, by running in the Terminal the following command:
|
||||
|
||||
```text
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
* **Linux**
|
||||
|
||||
On Linux, you can install Git using your package manager. For example, on Ubuntu, run in the Terminal the following command:
|
||||
|
||||
```text
|
||||
sudo apt install git
|
||||
```
|
||||
|
||||
For other distributions, refer to your package manager documentation.
|
||||
The Developer Board comes with stock firmware that may not include all the latest features and bug fixes. To ensure optimal performance, please update your board's firmware using the instructions in [Firmware update on Devboard](#dev_board_fw_update).
|
||||
|
||||
***
|
||||
|
||||
## Building the firmware
|
||||
## Step 3. Plug the Devboard into Flipper Zero {#dev_board_get_started_step-3}
|
||||
|
||||
First, clone the firmware repository:
|
||||
Once your Developer Board firmware is up to date, you can proceed to plug it into your Flipper Zero. Two important things to keep in mind:
|
||||
|
||||
```text
|
||||
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
|
||||
cd flipperzero-firmware
|
||||
```
|
||||
1. **Power off your Flipper Zero before plugging in the Developer Board.**
|
||||
|
||||
Then, run the **Flipper Build Tool** (FBT) to build the firmware:
|
||||
If you skip this step, you may corrupt the data stored on the microSD card. Connecting external modules with a large capacitive load may affect the microSD card's power supply since both the microSD card and external module are powered from the same 3.3 V power source inside Flipper Zero.
|
||||
|
||||
```text
|
||||
./fbt
|
||||
```
|
||||
2. **Make sure the Developer Board is inserted all the way in.**
|
||||
|
||||
If your Flipper Zero isn't in a silicone case, insert the module all the way in so there is no gap between your Flipper Zero and the Devboard. You may need to apply more force to insert it completely. After that, press and hold the **BACK** button to power on your Flipper Zero.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_external_module_without_case_CDN.jpg width=700
|
||||
|
||||
If your Flipper Zero is in a silicone case, insert the module all the way in so there is no gap in the middle between the silicone case and the module. After that, press and hold the **BACK** button to power on your Flipper Zero.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_external_module_with_case_CDN.jpg width=700
|
||||
|
||||
***
|
||||
|
||||
## Connecting the Developer Board
|
||||
## Step 4. Connect to a computer
|
||||
|
||||
The Developer Board can work in the **Wired** mode and two **Wireless** modes: **Wi-Fi access point (AP)** mode and **Wi-Fi client (STA)** mode. The Wired mode is the simplest to set up, but requires a USB Type-C cable. The Wireless modes are more complex to set up, but they allow you to debug your Flipper Zero wirelessly.
|
||||
Now, you can connect the Developer Board to your computer via USB or Wi-Fi, depending on your needs. We described both methods in separate documents:
|
||||
|
||||
> **NOTE:** Use the following credentials when connecting to the Developer Board in **Wi-Fi access point** mode:\n
|
||||
Name: **blackmagic**\n
|
||||
Password: **iamwitcher**
|
||||
|
||||
## Wired
|
||||
|
||||

|
||||
|
||||
To connect the Developer Board in **Wired** mode, do the following:
|
||||
|
||||
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
|
||||
|
||||
2. On your computer, open the **Terminal** and run the following:
|
||||
|
||||
* **MacOS**
|
||||
|
||||
```text
|
||||
ls /dev/cu.*
|
||||
```
|
||||
|
||||
* **Linux**
|
||||
|
||||
```text
|
||||
ls /dev/tty*
|
||||
```
|
||||
|
||||
Note the list of devices.
|
||||
|
||||
3. Connect the Developer Board to your computer via a USB-C cable.
|
||||
|
||||
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
|
||||
|
||||
> **NOTE:** If the Developer Board doesn't appear in the list of devices, try using a different cable, USB port, or computer.
|
||||
>
|
||||
> **NOTE:** Flipper Zero logs can only be viewed when the Developer Board is connected via USB. The option to view logs over Wi-Fi will be added in future updates. For more information, visit [Reading logs via the Dev Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/reading-logs).
|
||||
|
||||
## Wireless
|
||||
|
||||
### Wi-Fi access point (AP) mode
|
||||
|
||||

|
||||
|
||||
Out of the box, the Developer Board is configured to work as a **Wi-Fi access point**. This means it'll create its own Wi-Fi network to which you can connect. If your Developer Board doesn't create a Wi-Fi network, it is probably configured to work in **Wi-Fi client** mode. To reset your Developer Board back to **Wi-Fi access point** mode, press and hold the **BOOT** button for 10 seconds, then wait for the module to reboot.
|
||||
|
||||

|
||||
|
||||
To connect the Developer Board in **Wi-Fi access point** mode, do the following:
|
||||
|
||||
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
|
||||
|
||||
2. Open Wi-Fi settings on your client device (phone, laptop, or other).
|
||||
|
||||
3. Connect to the network:
|
||||
|
||||
* Name: **blackmagic**
|
||||
|
||||
* Password: **iamwitcher**
|
||||
|
||||
4. To configure the Developer Board, open a browser and go to `http://192.168.4.1`.
|
||||
|
||||
### Wi-Fi client (STA) mode
|
||||
|
||||

|
||||
|
||||
To connect the Developer Board in **Wi-Fi client** mode, you need to configure it to connect to your Wi-Fi network by doing the following:
|
||||
|
||||
1. Cold-plug the Developer Board by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
|
||||
|
||||
2. Connect to the Developer Board in **Wi-Fi access point** mode.
|
||||
|
||||
3. In a browser, go to the configuration page on `http://192.168.4.1`.
|
||||
|
||||
4. Select the **STA** mode and enter your network's **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby networks.
|
||||
|
||||
5. Save the configuration and reboot the Developer Board.
|
||||
|
||||

|
||||
|
||||
After rebooting, the Developer Board connects to your Wi-Fi network. You can connect to the device using the mDNS name **blackmagic.local** or the IP address it got from your router (you'll have to figure this out yourself, every router is different).
|
||||
|
||||
After connecting to your debugger via <http://blackmagic.local>, you can find its IP address in the **SYS** tab. You can also change the debugger's mode to **AP** or **STA** there.
|
||||
|
||||

|
||||
- **[Via USB cable](#dev_board_usb_connection)** for debugging in DAP Link or Black Magic mode, and reading logs.
|
||||
- [Via Wi-Fi](#dev_board_wifi_connection) for debugging in Black Magic mode.
|
||||
|
||||
***
|
||||
|
||||
## Debugging the firmware
|
||||
## Next steps
|
||||
|
||||
Open the **Terminal** in the **flipperzero-firmware** directory that you cloned earlier and run the following command:
|
||||
You are ready to debug now! To further explore what you can do with the Devboard, check out these pages:
|
||||
|
||||
```text
|
||||
./fbt flash
|
||||
```
|
||||
- [Debugging via the Devboard](#dev_board_debugging_guide)
|
||||
- [Devboard debug modes](#dev_board_debug_modes)
|
||||
- [Reading logs via the Devboard](#dev_board_reading_logs)
|
||||
|
||||
These guides should help you get started with your Devboard. If you have any questions or you want to share your experience, don't hesitate to join our community on [Reddit](https://www.reddit.com/r/flipperzero/) and [Discord](https://discord.com/invite/flipper), where we have a dedicated #wifi-devboard channel.
|
||||
|
||||
This will upload the firmware you've just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware using the [GDB](https://www.gnu.org/software/gdb/) debugger. We recommend using **VSCode** with the recommended extensions, and we have pre-made configurations for it.
|
||||
|
||||
To debug in **VSCode**, do the following:
|
||||
|
||||
1. In VSCode, open the **flipperzero-firmware** directory.
|
||||
|
||||
2. You should see a notification about recommended extensions. Install them.
|
||||
|
||||
If there were no notifications, open the **Extensions** tab, enter `@recommended` in the search bar, and install the workspace recommendations.
|
||||
|
||||
3. In the **Terminal**, run the `./fbt vscode_dist` command. This will generate the VSCode configuration files needed for debugging.
|
||||
|
||||
4. In VSCode, open the **Run and Debug** tab and select **Attach FW (blackmagic)** from the dropdown menu.
|
||||
|
||||
5. If needed, flash your Flipper Zero with the `./fbt flash` command, then click the **Play** button in the debug sidebar to start the debugging session.
|
||||
|
||||
6. Note that starting a debug session halts the execution of the firmware, so you'll need to click the **Continue** button on the toolbar at the top of your VSCode window to continue execution.
|
||||
|
||||

|
||||
|
||||
To learn about debugging, visit the following pages:
|
||||
|
||||
* [Debugging with GDB](https://sourceware.org/gdb/current/onlinedocs/gdb.pdf)
|
||||
|
||||
* [Debugging in VS Code](https://code.visualstudio.com/docs/editor/debugging)
|
||||
|
||||
@@ -8,9 +8,9 @@ The Developer Board allows you to read Flipper Zero logs via UART. Unlike readin
|
||||
|
||||
## Setting the log level
|
||||
|
||||
Depending on your needs, you can set the log level by going to **Main Menu → Settings → Log Level**. To learn more about logging levels, visit [Settings](https://docs.flipperzero.one/basics/settings#d5TAt).
|
||||
Depending on your needs, you can set the log level by going to **Main Menu → Settings → Log Level**. To learn more about logging levels, visit [Settings](https://docs.flipper.net/basics/settings#d5TAt).
|
||||
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_log_level.jpg "You can manually set the preferred log level" width=700
|
||||
|
||||
***
|
||||
|
||||
@@ -18,9 +18,9 @@ Depending on your needs, you can set the log level by going to **Main Menu → S
|
||||
|
||||
Depending on your operating system, you need to install an additional application on your computer to read logs via the Developer Board:
|
||||
|
||||
### MacOS
|
||||
### macOS
|
||||
|
||||
On MacOS, you need to install the **minicom** communication program by doing the following:
|
||||
On macOS, you need to install the **minicom** communication program by doing the following:
|
||||
|
||||
1. [Install Homebrew](https://brew.sh/) by running the following command in the Terminal:
|
||||
|
||||
@@ -47,7 +47,7 @@ After installation of minicom on your macOS computer, you can connect to the Dev
|
||||
Note the list of devices.
|
||||
|
||||
3. Connect the developer board to your computer using a USB Type-C cable.
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
|
||||
|
||||
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
|
||||
|
||||
@@ -100,7 +100,7 @@ After installation of minicom on your Linux computer, you can connect to the Dev
|
||||
Note the list of devices.
|
||||
|
||||
3. Connect the developer board to your computer using a USB Type-C cable.
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
|
||||
|
||||
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
|
||||
|
||||
@@ -143,17 +143,17 @@ On Windows, do the following:
|
||||
2. Cold-plug the Developer Board into your Flipper Zero by turning off the Flipper Zero, connecting the developer board, and then turning it back on.
|
||||
|
||||
3. Connect the developer board to your computer using a USB Type-C cable.
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_developer_board_wired.png width=700
|
||||
|
||||
4. Find the serial port that the developer board is connected to by going to **Device Manager → Ports (COM & LPT)** and looking for a new port that appears when you connect the Wi-Fi developer board.
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_Device_Manager.png width=700
|
||||
|
||||
5. Run the PuTTY application and select **Serial** as the connection type.
|
||||
|
||||
6. Enter the port number you found in the previous step into the **Serial line** field.
|
||||
|
||||
7. Set the **Speed** parameter to **230400** and click **Open**.
|
||||

|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_PuTTy.jpg width=700
|
||||
|
||||
8. View logs of your Flipper Zero in the PuTTY terminal window.
|
||||
|
||||
|
||||
22
documentation/devboard/USB connection to the Devboard.md
Normal file
22
documentation/devboard/USB connection to the Devboard.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# USB connection to the Devboard {#dev_board_usb_connection}
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_USB_connection_CDN.jpg width=700
|
||||
|
||||
To connect to the Developer Board via USB, do the following:
|
||||
|
||||
1. If the Devboard isn't connected to your Flipper Zero, turn off your Flipper Zero and connect the Developer Board to it. Then, turn your Flipper Zero back on.
|
||||
|
||||
2. On your computer, check the list of serial devices.
|
||||
|
||||
- **macOS:** On your computer, run `ls /dev/cu.*` in the Terminal.
|
||||
|
||||
- **Linux:** On your computer, run `ls /dev/tty*` in the Terminal.
|
||||
|
||||
- **Windows:** Go to **Device Manager** and expand the **Ports (COM & LPT)** section.
|
||||
|
||||
3. Connect the Devboard to your computer via a USB-C cable.
|
||||
|
||||
4. Repeat **Step 2**. Two new devices will appear — this is the Developer Board.
|
||||
|
||||
> [!warning]
|
||||
> If the Developer Board doesn't appear in the list of devices, try using a different cable, USB port, or computer.
|
||||
60
documentation/devboard/Wi-Fi connection to the Devboard.md
Normal file
60
documentation/devboard/Wi-Fi connection to the Devboard.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Wi-Fi connection to the Devboard {#dev_board_wifi_connection}
|
||||
|
||||
You can connect to the Developer Board wirelessly in two ways:
|
||||
|
||||
- **Wi-Fi access point mode (default):** The Devboard creates its own Wi-Fi network, which you can connect to in order to access its web interface and debug via Wi-Fi. The downside is that you will need to disconnect from your current Wi-Fi network, resulting in a loss of internet connection.
|
||||
|
||||
- **Wi-Fi client mode:** You can connect to the Devboard through an existing Wi-Fi network, allowing you to access the Devboard web interface and debug via Wi-Fi without losing your internet connection.
|
||||
|
||||
Let's go over both of these modes below.
|
||||
|
||||
***
|
||||
|
||||
## Wi-Fi access point (AP) mode {#wifi-access-point}
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_Access_Point_CDN.jpg width=700
|
||||
|
||||
Out of the box, the Developer Board is configured to work as a Wi-Fi access point. To connect the Developer Board in this mode, do the following:
|
||||
|
||||
1. Plug the Wi-Fi Devboard into your Flipper Zero by turning off your Flipper Zero and connecting the Developer Board, and then turning it back on.
|
||||
|
||||
2. Open Wi-Fi settings on your client device (phone, laptop, or other).
|
||||
|
||||
3. Connect to the network:
|
||||
|
||||
Name: `blackmagic`
|
||||
Password: `iamwitcher`
|
||||
|
||||
If your computer fails to find the **blackmagic** network, read the [troubleshooting section](#wifi-access-point_troubleshooting) below.
|
||||
|
||||
4. To access the Devboard's web interface, open a browser and go to <http://192.168.4.1> or <http://blackmagic.local>.
|
||||
|
||||
### If your computer fails to find the black magic network {#wifi-access-point_troubleshooting}
|
||||
|
||||
- Reset Wi-Fi connection on your computer.
|
||||
|
||||
- The Developer Board is probably configured to work in Wi-Fi client mode. → Reset your Developer Board settings to default by pressing and holding the **BOOT** button for **10 seconds**, then wait for the Devboard to reboot. After the reset, the Devboard will work in Wi-Fi access point mode.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_Wi-Fi_devboard_reboot.jpg width=700
|
||||
|
||||
***
|
||||
|
||||
## Wi-Fi client (STA) mode {#wifi-client-mode}
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_STA_CDN.jpg width=700
|
||||
|
||||
To connect the Developer Board in **Wi-Fi client** mode, you need to configure it to connect to your Wi-Fi network by doing the following:
|
||||
|
||||
1. Plug the Wi-Fi Devboard into your Flipper Zero by turning off your Flipper Zero and connecting the Developer Board, and then turning the device back on.
|
||||
|
||||
2. Connect to the Developer Board in [Wi-Fi access point](#wifi-access-point) mode.
|
||||
|
||||
3. In a browser, go to the Devboard's web interface at <http://192.168.4.1> or <http://blackmagic.local>.
|
||||
|
||||
4. Select the **STA** mode and enter your network's **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby 2.4 GHz networks (5 GHz networks aren't supported).
|
||||
|
||||
5. Save the configuration and reboot the Developer Board.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_connect_to_WiFi_CDN.jpg width=700
|
||||
|
||||
6. Now, you can access the Devboard's web interface at [http://blackmagic.local](https://blackmagic.local) via the existing Wi-Fi network without losing connection to the internet.
|
||||
@@ -1,10 +1,37 @@
|
||||
/**
|
||||
@page dev_board Developer Board
|
||||
@page dev_board Wi-Fi Developer Board
|
||||
|
||||
[ESP32-based development board](https://shop.flipperzero.one/collections/flipper-zero-accessories/products/wifi-devboard).
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_devboard_laptop_CDN.jpg width=700
|
||||
|
||||
Wi-Fi-enabled Developer Board brings debugging and firmware update capabilities to your Flipper Zero. The Developer Board is based on the ESP32-S2 MCU with custom firmware incorporating Black Magic Debug and CMSIS-DAP, and is built with ESP-IDF. It can flash and debug various microprocessors and microcontrollers (including the one used in your Flipper Zero) via Wi-Fi or USB cable.
|
||||
|
||||
The Developer Board provides a debug interface, allowing developers to halt program execution, set breakpoints, inspect variables and memory, and step through code execution.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://shop.flipperzero.one/products/wifi-devboard"><img src="https://cdn.flipperzero.one/Get_developer_board_button_green_600.png" width="350" align="center" alt="Get your Wi-Fi Developer Board"/></a>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
Check out these guides to get started with the Devboard:
|
||||
|
||||
- @subpage dev_board_get_started — Quick start for new users
|
||||
- @subpage dev_board_fw_update — Keep the Developer Board up to date
|
||||
- @subpage dev_board_usb_connection — Instructions for Windows, macOS and Linux
|
||||
- @subpage dev_board_wifi_connection — Instructions for Windows, macOS and Linux
|
||||
- @subpage dev_board_debugging_guide — Learn how it works
|
||||
- @subpage dev_board_debug_modes — Available modes and how to switch between them
|
||||
- @subpage dev_board_reading_logs — Find out what is currently happening on the system
|
||||
- @subpage dev_board_fw_update — Keep the developer board up to date
|
||||
|
||||
## Hardware
|
||||
|
||||
The Developer Board is equipped with an [ESP32-S2-WROVER](https://www.espressif.com/en/products/socs/esp32-s2) module, which includes built-in Wi-Fi capabilities. It also offers GPIO pins for easy connectivity to various targets. Additionally, the Developer Board features a USB Type-C connector for data transfer and power supply. For user interaction, the Developer Board has tactile switches.
|
||||
|
||||
\image html https://cdn.flipperzero.one/Flipper_Zero_WiFi_developer_board_hardware_CDN.jpg width=700
|
||||
|
||||
## Additional resources
|
||||
|
||||
To learn more about the Wi-Fi Developer Board hardware, visit [Schematics in Flipper Docs](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/schematics).
|
||||
|
||||
For additional information about Flipper Zero GPIO pins, visit [GPIO & modules in Flipper Docs](https://docs.flipperzero.one/gpio-and-modules).
|
||||
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ $extrastylesheet
|
||||
<!--END PROJECT_LOGO-->
|
||||
<!--BEGIN PROJECT_NAME-->
|
||||
<td id="projectalign">
|
||||
<div id="projectname"><a href="index.html">$projectname</a><!--BEGIN PROJECT_NUMBER--><span id="projectnumber"> $projectnumber</span><!--END PROJECT_NUMBER-->
|
||||
<div id="projectname"><a href="index.html" style="background: none; color: var(--foreground_color) !important;">$projectname</a><!--BEGIN PROJECT_NUMBER--><span id="projectnumber"> $projectnumber</span><!--END PROJECT_NUMBER-->
|
||||
</div>
|
||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||
</td>
|
||||
|
||||
@@ -44,7 +44,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
|
||||
|
||||
## VSCode integration
|
||||
|
||||
`fbt` includes basic development environment configuration for VS Code. Run `./fbt vscode_dist` to deploy it. That will copy the initial environment configuration to the `.vscode` folder. After that, you can use that configuration by starting VS Code and choosing the firmware root folder in the "File > Open Folder" menu.
|
||||
`fbt` includes basic development environment configuration for VS Code. Run `./fbt vscode_dist` to deploy it. That will copy the initial environment configuration to the `.vscode` folder. After that, you can use that configuration by starting VS Code and choosing the firmware root folder in the "File > Open Folder" menu.
|
||||
|
||||
To use language servers other than the default VS Code C/C++ language server, use `./fbt vscode_dist LANG_SERVER=<language-server>` instead. Currently `fbt` supports the default language server (`cpptools`) and `clangd`.
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ bool furi_kernel_is_irq_or_masked(void) {
|
||||
}
|
||||
|
||||
bool furi_kernel_is_running(void) {
|
||||
return xTaskGetSchedulerState() != taskSCHEDULER_RUNNING;
|
||||
return xTaskGetSchedulerState() == taskSCHEDULER_RUNNING;
|
||||
}
|
||||
|
||||
int32_t furi_kernel_lock(void) {
|
||||
@@ -129,6 +129,8 @@ uint32_t furi_kernel_get_tick_frequency(void) {
|
||||
|
||||
void furi_delay_tick(uint32_t ticks) {
|
||||
furi_check(!furi_kernel_is_irq_or_masked());
|
||||
furi_check(furi_thread_get_current_id() != xTaskGetIdleTaskHandle());
|
||||
|
||||
if(ticks == 0U) {
|
||||
taskYIELD();
|
||||
} else {
|
||||
@@ -138,6 +140,7 @@ void furi_delay_tick(uint32_t ticks) {
|
||||
|
||||
FuriStatus furi_delay_until_tick(uint32_t tick) {
|
||||
furi_check(!furi_kernel_is_irq_or_masked());
|
||||
furi_check(furi_thread_get_current_id() != xTaskGetIdleTaskHandle());
|
||||
|
||||
TickType_t tcnt, delay;
|
||||
FuriStatus stat;
|
||||
|
||||
@@ -108,10 +108,17 @@ void furi_log_puts(const char* data) {
|
||||
}
|
||||
|
||||
void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...) {
|
||||
if(level <= furi_log.log_level &&
|
||||
furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) {
|
||||
FuriString* string;
|
||||
string = furi_string_alloc();
|
||||
do {
|
||||
if(level > furi_log.log_level) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(furi_mutex_acquire(furi_log.mutex, furi_kernel_is_running() ? FuriWaitForever : 0) !=
|
||||
FuriStatusOk) {
|
||||
break;
|
||||
}
|
||||
|
||||
FuriString* string = furi_string_alloc();
|
||||
|
||||
const char* color = _FURI_LOG_CLR_RESET;
|
||||
const char* log_letter = " ";
|
||||
@@ -157,7 +164,7 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form
|
||||
furi_log_puts("\r\n");
|
||||
|
||||
furi_mutex_release(furi_log.mutex);
|
||||
}
|
||||
} while(0);
|
||||
}
|
||||
|
||||
void furi_log_print_raw_format(FuriLogLevel level, const char* format, ...) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "thread.h"
|
||||
#include "thread_i.h"
|
||||
#include "thread_list_i.h"
|
||||
#include "kernel.h"
|
||||
#include "message_queue.h"
|
||||
#include "memmgr.h"
|
||||
#include "memmgr_heap.h"
|
||||
#include "check.h"
|
||||
@@ -67,6 +68,8 @@ static_assert(offsetof(FuriThread, container) == 0);
|
||||
// Our idle priority should be equal to the one from FreeRTOS
|
||||
static_assert(FuriThreadPriorityIdle == tskIDLE_PRIORITY);
|
||||
|
||||
static FuriMessageQueue* furi_thread_scrub_message_queue = NULL;
|
||||
|
||||
static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size);
|
||||
static int32_t __furi_thread_stdout_flush(FuriThread* thread);
|
||||
|
||||
@@ -125,7 +128,9 @@ static void furi_thread_body(void* context) {
|
||||
|
||||
furi_thread_set_state(thread, FuriThreadStateStopping);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
furi_message_queue_put(furi_thread_scrub_message_queue, &thread, FuriWaitForever);
|
||||
|
||||
vTaskSuspend(NULL);
|
||||
furi_thread_catch();
|
||||
}
|
||||
|
||||
@@ -159,6 +164,31 @@ static void furi_thread_init_common(FuriThread* thread) {
|
||||
}
|
||||
}
|
||||
|
||||
void furi_thread_init(void) {
|
||||
furi_thread_scrub_message_queue = furi_message_queue_alloc(8, sizeof(FuriThread*));
|
||||
}
|
||||
|
||||
void furi_thread_scrub(void) {
|
||||
FuriThread* thread_to_scrub = NULL;
|
||||
while(true) {
|
||||
furi_check(
|
||||
furi_message_queue_get(
|
||||
furi_thread_scrub_message_queue, &thread_to_scrub, FuriWaitForever) ==
|
||||
FuriStatusOk);
|
||||
|
||||
TaskHandle_t task = (TaskHandle_t)thread_to_scrub;
|
||||
|
||||
// Delete task: FreeRTOS will remove task from all lists where it may be
|
||||
vTaskDelete(task);
|
||||
// Sanity check: ensure that local storage is ours and clear it
|
||||
furi_check(pvTaskGetThreadLocalStoragePointer(task, 0) == thread_to_scrub);
|
||||
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
|
||||
|
||||
// Deliver thread stopped callback
|
||||
furi_thread_set_state(thread_to_scrub, FuriThreadStateStopped);
|
||||
}
|
||||
}
|
||||
|
||||
FuriThread* furi_thread_alloc(void) {
|
||||
FuriThread* thread = malloc(sizeof(FuriThread));
|
||||
|
||||
@@ -358,16 +388,6 @@ void furi_thread_start(FuriThread* thread) {
|
||||
&thread->container) == (TaskHandle_t)thread);
|
||||
}
|
||||
|
||||
void furi_thread_cleanup_tcb_event(TaskHandle_t task) {
|
||||
FuriThread* thread = pvTaskGetThreadLocalStoragePointer(task, 0);
|
||||
if(thread) {
|
||||
// clear thread local storage
|
||||
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
|
||||
furi_check(thread == (FuriThread*)task);
|
||||
furi_thread_set_state(thread, FuriThreadStateStopped);
|
||||
}
|
||||
}
|
||||
|
||||
bool furi_thread_join(FuriThread* thread) {
|
||||
furi_check(thread);
|
||||
// Cannot join a service thread
|
||||
|
||||
@@ -21,10 +21,10 @@ extern "C" {
|
||||
* Many of the FuriThread functions MUST ONLY be called when the thread is STOPPED.
|
||||
*/
|
||||
typedef enum {
|
||||
FuriThreadStateStopped, /**< Thread is stopped and is safe to release */
|
||||
FuriThreadStateStopping, /**< Thread is stopping */
|
||||
FuriThreadStateStarting, /**< Thread is starting */
|
||||
FuriThreadStateRunning, /**< Thread is running */
|
||||
FuriThreadStateStopped, /**< Thread is stopped and is safe to release. Event delivered from system init thread(TCB cleanup routine). It is safe to release thread instance. */
|
||||
FuriThreadStateStopping, /**< Thread is stopping. Event delivered from child thread. */
|
||||
FuriThreadStateStarting, /**< Thread is starting. Event delivered from parent(self) thread. */
|
||||
FuriThreadStateRunning, /**< Thread is running. Event delivered from child thread. */
|
||||
} FuriThreadState;
|
||||
|
||||
/**
|
||||
@@ -32,6 +32,7 @@ typedef enum {
|
||||
*/
|
||||
typedef enum {
|
||||
FuriThreadPriorityIdle = 0, /**< Idle priority */
|
||||
FuriThreadPriorityInit = 4, /**< Init System Thread Priority */
|
||||
FuriThreadPriorityLowest = 14, /**< Lowest */
|
||||
FuriThreadPriorityLow = 15, /**< Low */
|
||||
FuriThreadPriorityNormal = 16, /**< Normal, system default */
|
||||
@@ -77,13 +78,15 @@ typedef int32_t (*FuriThreadCallback)(void* context);
|
||||
typedef void (*FuriThreadStdoutWriteCallback)(const char* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief State change callback function pointer type.
|
||||
* @brief State change callback function pointer type.
|
||||
*
|
||||
* The function to be used as a state callback MUST follow this signature.
|
||||
* The function to be used as a state callback MUST follow this
|
||||
* signature.
|
||||
*
|
||||
* @param[in] pointer to the FuriThread instance that changed the state
|
||||
* @param[in] state identifier of the state the thread has transitioned to
|
||||
* @param[in,out] context pointer to a user-specified object
|
||||
* @param[in] thread to the FuriThread instance that changed the state
|
||||
* @param[in] state identifier of the state the thread has transitioned
|
||||
* to
|
||||
* @param[in,out] context pointer to a user-specified object
|
||||
*/
|
||||
typedef void (*FuriThreadStateCallback)(FuriThread* thread, FuriThreadState state, void* context);
|
||||
|
||||
|
||||
7
furi/core/thread_i.h
Normal file
7
furi/core/thread_i.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
void furi_thread_init(void);
|
||||
|
||||
void furi_thread_scrub(void);
|
||||
@@ -17,12 +17,24 @@ static_assert(offsetof(FuriTimer, container) == 0);
|
||||
|
||||
#define TIMER_DELETED_EVENT (1U << 0)
|
||||
|
||||
static void TimerCallback(TimerHandle_t hTimer) {
|
||||
static void furi_timer_callback(TimerHandle_t hTimer) {
|
||||
FuriTimer* instance = pvTimerGetTimerID(hTimer);
|
||||
furi_check(instance);
|
||||
instance->cb_func(instance->cb_context);
|
||||
}
|
||||
|
||||
static void furi_timer_flush_epilogue(void* context, uint32_t arg) {
|
||||
furi_assert(context);
|
||||
UNUSED(arg);
|
||||
|
||||
EventGroupHandle_t hEvent = context;
|
||||
|
||||
// See https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/1142
|
||||
vTaskSuspendAll();
|
||||
xEventGroupSetBits(hEvent, TIMER_DELETED_EVENT);
|
||||
(void)xTaskResumeAll();
|
||||
}
|
||||
|
||||
FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) {
|
||||
furi_check((furi_kernel_is_irq_or_masked() == 0U) && (func != NULL));
|
||||
|
||||
@@ -33,23 +45,13 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co
|
||||
|
||||
const UBaseType_t reload = (type == FuriTimerTypeOnce ? pdFALSE : pdTRUE);
|
||||
const TimerHandle_t hTimer = xTimerCreateStatic(
|
||||
NULL, portMAX_DELAY, reload, instance, TimerCallback, &instance->container);
|
||||
NULL, portMAX_DELAY, reload, instance, furi_timer_callback, &instance->container);
|
||||
|
||||
furi_check(hTimer == (TimerHandle_t)instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void furi_timer_epilogue(void* context, uint32_t arg) {
|
||||
furi_assert(context);
|
||||
UNUSED(arg);
|
||||
|
||||
EventGroupHandle_t hEvent = context;
|
||||
vTaskSuspendAll();
|
||||
xEventGroupSetBits(hEvent, TIMER_DELETED_EVENT);
|
||||
(void)xTaskResumeAll();
|
||||
}
|
||||
|
||||
void furi_timer_free(FuriTimer* instance) {
|
||||
furi_check(!furi_kernel_is_irq_or_masked());
|
||||
furi_check(instance);
|
||||
@@ -57,16 +59,21 @@ void furi_timer_free(FuriTimer* instance) {
|
||||
TimerHandle_t hTimer = (TimerHandle_t)instance;
|
||||
furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS);
|
||||
|
||||
furi_timer_flush();
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void furi_timer_flush(void) {
|
||||
StaticEventGroup_t event_container = {};
|
||||
EventGroupHandle_t hEvent = xEventGroupCreateStatic(&event_container);
|
||||
furi_check(xTimerPendFunctionCall(furi_timer_epilogue, hEvent, 0, portMAX_DELAY) == pdPASS);
|
||||
furi_check(
|
||||
xTimerPendFunctionCall(furi_timer_flush_epilogue, hEvent, 0, portMAX_DELAY) == pdPASS);
|
||||
|
||||
furi_check(
|
||||
xEventGroupWaitBits(hEvent, TIMER_DELETED_EVENT, pdFALSE, pdTRUE, portMAX_DELAY) ==
|
||||
TIMER_DELETED_EVENT);
|
||||
vEventGroupDelete(hEvent);
|
||||
|
||||
free(instance);
|
||||
}
|
||||
|
||||
FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) {
|
||||
@@ -112,6 +119,8 @@ FuriStatus furi_timer_stop(FuriTimer* instance) {
|
||||
|
||||
furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS);
|
||||
|
||||
furi_timer_flush();
|
||||
|
||||
return FuriStatusOk;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,12 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co
|
||||
*/
|
||||
void furi_timer_free(FuriTimer* instance);
|
||||
|
||||
/** Flush timer task control message queue
|
||||
*
|
||||
* Ensures that all commands before this point was processed.
|
||||
*/
|
||||
void furi_timer_flush(void);
|
||||
|
||||
/** Start timer
|
||||
*
|
||||
* @warning This is asynchronous call, real operation will happen as soon as
|
||||
@@ -61,8 +67,7 @@ FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks);
|
||||
|
||||
/** Stop timer
|
||||
*
|
||||
* @warning This is asynchronous call, real operation will happen as soon as
|
||||
* timer service process this request.
|
||||
* @warning This is synchronous call that will be blocked till timer queue processed.
|
||||
*
|
||||
* @param instance The pointer to FuriTimer instance
|
||||
*
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "furi.h"
|
||||
|
||||
#include "core/thread_i.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <queue.h>
|
||||
|
||||
@@ -7,6 +9,7 @@ void furi_init(void) {
|
||||
furi_check(!furi_kernel_is_irq_or_masked());
|
||||
furi_check(xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED);
|
||||
|
||||
furi_thread_init();
|
||||
furi_log_init();
|
||||
furi_record_init();
|
||||
}
|
||||
@@ -18,3 +21,7 @@ void furi_run(void) {
|
||||
/* Start the kernel scheduler */
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
void furi_background(void) {
|
||||
furi_thread_scrub();
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ void furi_init(void);
|
||||
|
||||
void furi_run(void);
|
||||
|
||||
void furi_background(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,76.0,,
|
||||
Version,+,77.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
@@ -1102,6 +1102,7 @@ Function,-,ftello,off_t,FILE*
|
||||
Function,-,ftrylockfile,int,FILE*
|
||||
Function,-,funlockfile,void,FILE*
|
||||
Function,-,funopen,FILE*,"const void*, int (*)(void*, char*, int), int (*)(void*, const char*, int), fpos_t (*)(void*, fpos_t, int), int (*)(void*)"
|
||||
Function,-,furi_background,void,
|
||||
Function,+,furi_delay_ms,void,uint32_t
|
||||
Function,+,furi_delay_tick,void,uint32_t
|
||||
Function,+,furi_delay_until_tick,FuriStatus,uint32_t
|
||||
@@ -1672,6 +1673,7 @@ Function,+,furi_thread_stdout_write,size_t,"const char*, size_t"
|
||||
Function,+,furi_thread_suspend,void,FuriThreadId
|
||||
Function,+,furi_thread_yield,void,
|
||||
Function,+,furi_timer_alloc,FuriTimer*,"FuriTimerCallback, FuriTimerType, void*"
|
||||
Function,+,furi_timer_flush,void,
|
||||
Function,+,furi_timer_free,void,FuriTimer*
|
||||
Function,+,furi_timer_get_expire_time,uint32_t,FuriTimer*
|
||||
Function,+,furi_timer_is_running,uint32_t,FuriTimer*
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,76.0,,
|
||||
Version,+,77.0,,
|
||||
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_keys_storage.h,,
|
||||
@@ -1212,6 +1212,7 @@ Function,-,ftello,off_t,FILE*
|
||||
Function,-,ftrylockfile,int,FILE*
|
||||
Function,-,funlockfile,void,FILE*
|
||||
Function,-,funopen,FILE*,"const void*, int (*)(void*, char*, int), int (*)(void*, const char*, int), fpos_t (*)(void*, fpos_t, int), int (*)(void*)"
|
||||
Function,-,furi_background,void,
|
||||
Function,+,furi_delay_ms,void,uint32_t
|
||||
Function,+,furi_delay_tick,void,uint32_t
|
||||
Function,+,furi_delay_until_tick,FuriStatus,uint32_t
|
||||
@@ -1891,6 +1892,7 @@ Function,+,furi_thread_stdout_write,size_t,"const char*, size_t"
|
||||
Function,+,furi_thread_suspend,void,FuriThreadId
|
||||
Function,+,furi_thread_yield,void,
|
||||
Function,+,furi_timer_alloc,FuriTimer*,"FuriTimerCallback, FuriTimerType, void*"
|
||||
Function,+,furi_timer_flush,void,
|
||||
Function,+,furi_timer_free,void,FuriTimer*
|
||||
Function,+,furi_timer_get_expire_time,uint32_t,FuriTimer*
|
||||
Function,+,furi_timer_is_running,uint32_t,FuriTimer*
|
||||
|
||||
|
@@ -87,6 +87,8 @@ void ble_glue_init(void) {
|
||||
TL_Init();
|
||||
|
||||
ble_glue->shci_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
// Take mutex, SHCI will release it in most unusual way later
|
||||
furi_check(furi_mutex_acquire(ble_glue->shci_mtx, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
// FreeRTOS system task creation
|
||||
ble_event_thread_start();
|
||||
@@ -248,7 +250,9 @@ void ble_glue_stop(void) {
|
||||
ble_event_thread_stop();
|
||||
// Free resources
|
||||
furi_mutex_free(ble_glue->shci_mtx);
|
||||
ble_glue->shci_mtx = NULL;
|
||||
furi_timer_free(ble_glue->hardfault_check_timer);
|
||||
ble_glue->hardfault_check_timer = NULL;
|
||||
|
||||
ble_glue_clear_shared_memory();
|
||||
free(ble_glue);
|
||||
@@ -309,10 +313,13 @@ BleGlueCommandResult ble_glue_force_c2_mode(BleGlueC2Mode desired_mode) {
|
||||
static void ble_sys_status_not_callback(SHCI_TL_CmdStatus_t status) {
|
||||
switch(status) {
|
||||
case SHCI_TL_CmdBusy:
|
||||
furi_mutex_acquire(ble_glue->shci_mtx, FuriWaitForever);
|
||||
furi_check(
|
||||
furi_mutex_acquire(
|
||||
ble_glue->shci_mtx, furi_kernel_is_running() ? FuriWaitForever : 0) ==
|
||||
FuriStatusOk);
|
||||
break;
|
||||
case SHCI_TL_CmdAvailable:
|
||||
furi_mutex_release(ble_glue->shci_mtx);
|
||||
furi_check(furi_mutex_release(ble_glue->shci_mtx) == FuriStatusOk);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -129,7 +129,7 @@ BleEventFlowStatus ble_event_app_notification(void* pckt) {
|
||||
event_pckt = (hci_event_pckt*)((hci_uart_pckt*)pckt)->data;
|
||||
|
||||
furi_check(gap);
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
switch(event_pckt->evt) {
|
||||
case HCI_DISCONNECTION_COMPLETE_EVT_CODE: {
|
||||
@@ -304,7 +304,7 @@ BleEventFlowStatus ble_event_app_notification(void* pckt) {
|
||||
break;
|
||||
}
|
||||
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
|
||||
return BleEventFlowEnable;
|
||||
}
|
||||
@@ -490,7 +490,7 @@ static void gap_advertise_stop(void) {
|
||||
}
|
||||
|
||||
void gap_start_advertising(void) {
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(gap->state == GapStateIdle) {
|
||||
gap->state = GapStateStartingAdv;
|
||||
FURI_LOG_I(TAG, "Start advertising");
|
||||
@@ -498,18 +498,18 @@ void gap_start_advertising(void) {
|
||||
GapCommand command = GapCommandAdvFast;
|
||||
furi_check(furi_message_queue_put(gap->command_queue, &command, 0) == FuriStatusOk);
|
||||
}
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void gap_stop_advertising(void) {
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(gap->state > GapStateIdle) {
|
||||
FURI_LOG_I(TAG, "Stop advertising");
|
||||
gap->enable_adv = false;
|
||||
GapCommand command = GapCommandAdvStop;
|
||||
furi_check(furi_message_queue_put(gap->command_queue, &command, 0) == FuriStatusOk);
|
||||
}
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
static void gap_advetise_timer_callback(void* context) {
|
||||
@@ -566,9 +566,9 @@ bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context) {
|
||||
GapState gap_get_state(void) {
|
||||
GapState state;
|
||||
if(gap) {
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
state = gap->state;
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
} else {
|
||||
state = GapStateUninitialized;
|
||||
}
|
||||
@@ -577,17 +577,21 @@ GapState gap_get_state(void) {
|
||||
|
||||
void gap_thread_stop(void) {
|
||||
if(gap) {
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
gap->enable_adv = false;
|
||||
GapCommand command = GapCommandKillThread;
|
||||
furi_message_queue_put(gap->command_queue, &command, FuriWaitForever);
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
furi_thread_join(gap->thread);
|
||||
furi_thread_free(gap->thread);
|
||||
gap->thread = NULL;
|
||||
// Free resources
|
||||
furi_mutex_free(gap->state_mutex);
|
||||
gap->state_mutex = NULL;
|
||||
furi_message_queue_free(gap->command_queue);
|
||||
gap->command_queue = NULL;
|
||||
furi_timer_free(gap->advertise_timer);
|
||||
gap->advertise_timer = NULL;
|
||||
|
||||
ble_event_dispatcher_reset();
|
||||
free(gap);
|
||||
@@ -604,7 +608,7 @@ static int32_t gap_app(void* context) {
|
||||
FURI_LOG_E(TAG, "Message queue get error: %d", status);
|
||||
continue;
|
||||
}
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
furi_check(furi_mutex_acquire(gap->state_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
if(command == GapCommandKillThread) {
|
||||
break;
|
||||
}
|
||||
@@ -615,7 +619,7 @@ static int32_t gap_app(void* context) {
|
||||
} else if(command == GapCommandAdvStop) {
|
||||
gap_advertise_stop();
|
||||
}
|
||||
furi_mutex_release(gap->state_mutex);
|
||||
furi_check(furi_mutex_release(gap->state_mutex) == FuriStatusOk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -202,7 +202,7 @@ bool furi_hal_spi_bus_trx_dma(
|
||||
furi_check(size > 0);
|
||||
|
||||
// If scheduler is not running, use blocking mode
|
||||
if(furi_kernel_is_running()) {
|
||||
if(!furi_kernel_is_running()) {
|
||||
return furi_hal_spi_bus_trx(handle, tx_buffer, rx_buffer, size, timeout_ms);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ to exclude the API function. */
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
|
||||
/* Workaround for various notification issues:
|
||||
* - First one used by system primitives
|
||||
@@ -129,25 +130,11 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
|
||||
(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
#ifdef DEBUG
|
||||
#include <core/check.h>
|
||||
#define configASSERT(x) \
|
||||
if((x) == 0) { \
|
||||
furi_crash("FreeRTOS Assert"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names. */
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
|
||||
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1
|
||||
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION \
|
||||
1 /* required only for Keil but does not hurt otherwise */
|
||||
|
||||
#define traceTASK_SWITCHED_IN() \
|
||||
extern void furi_hal_mpu_set_stack_protection(uint32_t* stack); \
|
||||
furi_hal_mpu_set_stack_protection((uint32_t*)pxCurrentTCB->pxStack); \
|
||||
@@ -157,6 +144,14 @@ standard names. */
|
||||
// referencing `FreeRTOS_errno' here vvvvv because FreeRTOS calls our hook _before_ copying the value into the TCB, hence a manual write to the TCB would get overwritten
|
||||
#define traceTASK_SWITCHED_OUT() FreeRTOS_errno = errno
|
||||
|
||||
#define portCLEAN_UP_TCB(pxTCB) \
|
||||
extern void furi_thread_cleanup_tcb_event(TaskHandle_t task); \
|
||||
furi_thread_cleanup_tcb_event(pxTCB)
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
#ifdef DEBUG
|
||||
#define configASSERT(x) \
|
||||
if((x) == 0) { \
|
||||
furi_crash("FreeRTOS Assert"); \
|
||||
}
|
||||
#endif
|
||||
|
||||
// Must be last line of config because of recursion
|
||||
#include <core/check.h>
|
||||
|
||||
@@ -15,6 +15,8 @@ int32_t init_task(void* context) {
|
||||
// Init flipper
|
||||
flipper_init();
|
||||
|
||||
furi_background();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,7 +27,8 @@ int main(void) {
|
||||
// Flipper critical FURI HAL
|
||||
furi_hal_init_early();
|
||||
|
||||
FuriThread* main_thread = furi_thread_alloc_ex("Init", 4096, init_task, NULL);
|
||||
FuriThread* main_thread = furi_thread_alloc_ex("InitSrv", 1024, init_task, NULL);
|
||||
furi_thread_set_priority(main_thread, FuriThreadPriorityInit);
|
||||
|
||||
#ifdef FURI_RAM_EXEC
|
||||
// Prevent entering sleep mode when executed from RAM
|
||||
|
||||
Reference in New Issue
Block a user