mirror of
https://github.com/flipperdevices/flipperzero-firmware.git
synced 2025-12-12 04:41:26 +04:00
VA Fixes: USB IRQ Handling and EP configuration, Thread handler shenanigans. (#3705)
* FuriHal: properly handle high priority USB IRQ, change CDC decriptor to use separate TX/RX endpoints * Furi: drop task handle, cleanup casts and memory corrupt in threads * FuriHal: update max power in USB descriptors * Furi: properly handle thread free if thread was not started * Furi crash: meaningful interrupt name instead of id --------- Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <furi_hal_rtc.h>
|
||||
#include <furi_hal_debug.h>
|
||||
#include <furi_hal_bt.h>
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
@@ -110,8 +111,14 @@ static void __furi_print_heap_info(void) {
|
||||
|
||||
static void __furi_print_name(bool isr) {
|
||||
if(isr) {
|
||||
uint8_t exception_number = __get_IPSR();
|
||||
const char* name = furi_hal_interrupt_get_name(exception_number);
|
||||
furi_log_puts("[ISR ");
|
||||
__furi_put_uint32_as_text(__get_IPSR());
|
||||
if(name) {
|
||||
furi_log_puts(name);
|
||||
} else {
|
||||
__furi_put_uint32_as_text(__get_IPSR());
|
||||
}
|
||||
furi_log_puts("] ");
|
||||
} else {
|
||||
const char* name = pcTaskGetName(NULL);
|
||||
|
||||
@@ -28,7 +28,6 @@ struct FuriThreadStdout {
|
||||
|
||||
struct FuriThread {
|
||||
StaticTask_t container;
|
||||
TaskHandle_t task_handle;
|
||||
StackType_t* stack_buffer;
|
||||
|
||||
FuriThreadState state;
|
||||
@@ -54,6 +53,7 @@ struct FuriThread {
|
||||
// this ensures that the size of this structure is minimal
|
||||
bool is_service;
|
||||
bool heap_trace_enabled;
|
||||
volatile bool is_active;
|
||||
};
|
||||
|
||||
// IMPORTANT: container MUST be the FIRST struct member
|
||||
@@ -90,9 +90,8 @@ static void furi_thread_body(void* context) {
|
||||
furi_check(thread->state == FuriThreadStateStarting);
|
||||
furi_thread_set_state(thread, FuriThreadStateRunning);
|
||||
|
||||
TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
|
||||
if(thread->heap_trace_enabled == true) {
|
||||
memmgr_heap_enable_thread_trace((FuriThreadId)task_handle);
|
||||
memmgr_heap_enable_thread_trace(thread);
|
||||
}
|
||||
|
||||
thread->ret = thread->callback(thread->context);
|
||||
@@ -101,14 +100,14 @@ static void furi_thread_body(void* context) {
|
||||
|
||||
if(thread->heap_trace_enabled == true) {
|
||||
furi_delay_ms(33);
|
||||
thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)task_handle);
|
||||
thread->heap_size = memmgr_heap_get_thread_memory(thread);
|
||||
furi_log_print_format(
|
||||
thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo,
|
||||
TAG,
|
||||
"%s allocation balance: %zu",
|
||||
thread->name ? thread->name : "Thread",
|
||||
thread->heap_size);
|
||||
memmgr_heap_disable_thread_trace((FuriThreadId)task_handle);
|
||||
memmgr_heap_disable_thread_trace(thread);
|
||||
}
|
||||
|
||||
furi_check(thread->state == FuriThreadStateRunning);
|
||||
@@ -197,7 +196,7 @@ void furi_thread_free(FuriThread* thread) {
|
||||
furi_check(thread->is_service == false);
|
||||
// Cannot free a non-joined thread
|
||||
furi_check(thread->state == FuriThreadStateStopped);
|
||||
furi_check(thread->task_handle == NULL);
|
||||
furi_check(!thread->is_active);
|
||||
|
||||
furi_thread_set_name(thread, NULL);
|
||||
furi_thread_set_appid(thread, NULL);
|
||||
@@ -313,16 +312,17 @@ void furi_thread_start(FuriThread* thread) {
|
||||
uint32_t stack_depth = thread->stack_size / sizeof(StackType_t);
|
||||
UBaseType_t priority = thread->priority ? thread->priority : FuriThreadPriorityNormal;
|
||||
|
||||
thread->task_handle = xTaskCreateStatic(
|
||||
furi_thread_body,
|
||||
thread->name,
|
||||
stack_depth,
|
||||
thread,
|
||||
priority,
|
||||
thread->stack_buffer,
|
||||
&thread->container);
|
||||
thread->is_active = true;
|
||||
|
||||
furi_check(thread->task_handle == (TaskHandle_t)&thread->container);
|
||||
furi_check(
|
||||
xTaskCreateStatic(
|
||||
furi_thread_body,
|
||||
thread->name,
|
||||
stack_depth,
|
||||
thread,
|
||||
priority,
|
||||
thread->stack_buffer,
|
||||
&thread->container) == (TaskHandle_t)thread);
|
||||
}
|
||||
|
||||
void furi_thread_cleanup_tcb_event(TaskHandle_t task) {
|
||||
@@ -330,8 +330,8 @@ void furi_thread_cleanup_tcb_event(TaskHandle_t task) {
|
||||
if(thread) {
|
||||
// clear thread local storage
|
||||
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
|
||||
furi_check(thread->task_handle == task);
|
||||
thread->task_handle = NULL;
|
||||
furi_check(thread == (FuriThread*)task);
|
||||
thread->is_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ bool furi_thread_join(FuriThread* thread) {
|
||||
//
|
||||
// If your thread exited, but your app stuck here: some other thread uses
|
||||
// all cpu time, which delays kernel from releasing task handle
|
||||
while(thread->task_handle) {
|
||||
while(thread->is_active) {
|
||||
furi_delay_ms(10);
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ bool furi_thread_join(FuriThread* thread) {
|
||||
|
||||
FuriThreadId furi_thread_get_id(FuriThread* thread) {
|
||||
furi_check(thread);
|
||||
return thread->task_handle;
|
||||
return thread;
|
||||
}
|
||||
|
||||
void furi_thread_enable_heap_trace(FuriThread* thread) {
|
||||
|
||||
Reference in New Issue
Block a user