Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable optional GPROF profiling of apps #2669

Merged
merged 20 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: codespell-project/actions-codespell@v2
with:
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git,./libraries/FatFS/lib/fatfs,./libraries/FatFS/src/diskio.h,./libraries/FatFS/src/ff.cpp,./libraries/FatFS/src/ffconf.h,./libraries/FatFS/src/ffsystem.cpp,./libraries/FatFS/src/ff.h,./libraries/lwIP_WINC1500/src/driver,./libraries/lwIP_WINC1500/src/common,./libraries/lwIP_WINC1500/src/bus_wrapper,./libraries/lwIP_WINC1500/src/spi_flash
ignore_words_list: ser,dout,shiftIn,acount
ignore_words_list: ser,dout,shiftIn,acount,froms
- name: Get submodules for following tests
run: git submodule update --init
- name: Check package references
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
* printf (i.e. debug) output over USB serial
* Transparent use of PSRAM globals and heap (RP2350 only)
* ARM or RISC-V (Hazard3) support for the RP2350
* Semihosted serial and file system access
* GPROF profiling support

The RP2040 PIO state machines (SMs) are used to generate jitter-free:
* Servos
Expand Down
457 changes: 457 additions & 0 deletions boards.txt

Large diffs are not rendered by default.

18 changes: 17 additions & 1 deletion cores/rp2040/RP2040Support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <Arduino.h>
#include <pico/runtime.h>

#ifdef PICO_RP2040

#include <Arduino.h>
#include <hardware/structs/psm.h>

extern "C" void boot_double_tap_check();
Expand All @@ -35,3 +37,17 @@ void RP2040::enableDoubleResetBootloader() {
}

#endif

#ifdef __PROFILE
Stream *__profileFile;
int __writeProfileCB(const void *data, int len) {
return __profileFile->write((const char *)data, len);
}

#ifdef __PROFILE
extern "C" void runtime_init_setup_profiling();
#define PICO_RUNTIME_INIT_PROFILING "11011" // Towards the end, after PSRAM
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_profiling, PICO_RUNTIME_INIT_PROFILING);
#endif

#endif
36 changes: 30 additions & 6 deletions cores/rp2040/RP2040Support.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#pragma once

#include <hardware/clocks.h>
#include <hardware/irq.h>
#include <hardware/pio.h>
Expand Down Expand Up @@ -45,6 +47,13 @@

extern "C" volatile bool __otherCoreIdled;

extern "C" {
#ifdef __PROFILE
typedef int (*profileWriteCB)(const void *data, int len);
extern void _writeProfile(profileWriteCB writeCB);
#endif
}

class _MFIFO {
public:
_MFIFO() { /* noop */ };
Expand Down Expand Up @@ -180,7 +189,7 @@ class RP2040 {

void begin() {
_epoch = 0;
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
if (!__isFreeRTOS) {
// Enable SYSTICK exception
exception_set_exclusive_handler(SYSTICK_EXCEPTION, _SystickHandler);
Expand All @@ -193,7 +202,7 @@ class RP2040 {
_ccountPgm->prepare(&_pio, &_sm, &off);
ccount_program_init(_pio, _sm, off);
pio_sm_set_enabled(_pio, _sm, true);
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}
Expand All @@ -217,7 +226,7 @@ class RP2040 {
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
volatile uint64_t _epoch = 0;
inline uint32_t getCycleCount() {
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
if (!__isFreeRTOS) {
uint32_t epoch;
uint32_t ctr;
Expand All @@ -229,13 +238,13 @@ class RP2040 {
} else {
#endif
return ccount_read(_pio, _sm);
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}

inline uint64_t getCycleCount64() {
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
if (!__isFreeRTOS) {
uint64_t epoch;
uint64_t ctr;
Expand All @@ -247,7 +256,7 @@ class RP2040 {
} else {
#endif
return ccount_read(_pio, _sm);
#if !defined(__riscv)
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}
Expand Down Expand Up @@ -473,6 +482,21 @@ class RP2040 {
#endif
}

#ifdef __PROFILE
void writeProfiling(Stream *f) {
extern Stream *__profileFile;
extern int __writeProfileCB(const void *data, int len);
__profileFile = f;
_writeProfile(__writeProfileCB);
}

size_t getProfileMemoryUsage() {
extern int __profileMemSize;
return (size_t) __profileMemSize;
}
#endif



private:
static void _SystickHandler() {
Expand Down
42 changes: 23 additions & 19 deletions cores/rp2040/_freertos.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,36 @@ extern bool __isFreeRTOS;
// FreeRTOS has been set up
extern volatile bool __freeRTOSinitted;

#ifdef __cplusplus
extern "C" {
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
typedef struct QueueDefinition * QueueHandle_t;
typedef QueueHandle_t SemaphoreHandle_t;
typedef int32_t BaseType_t;
#endif // __cplusplus
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
typedef struct QueueDefinition * QueueHandle_t;
typedef QueueHandle_t SemaphoreHandle_t;
typedef int32_t BaseType_t;

extern bool __freertos_check_if_in_isr() __attribute__((weak));
extern bool __freertos_check_if_in_isr() __attribute__((weak));

extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak));

extern void __freertos_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));

extern int __freertos_mutex_take_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));
extern int __freertos_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));
extern int __freertos_mutex_take_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));
extern int __freertos_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));

extern void __freertos_recursive_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern int __freertos_recursive_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_recursive_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_recursive_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern int __freertos_recursive_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_recursive_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));

extern void __freertos_idle_other_core() __attribute__((weak));
extern void __freertos_resume_other_core() __attribute__((weak));
extern void __freertos_idle_other_core() __attribute__((weak));
extern void __freertos_resume_other_core() __attribute__((weak));

extern void __freertos_task_exit_critical() __attribute__((weak));
extern void __freertos_task_enter_critical() __attribute__((weak));
extern void __freertos_task_exit_critical() __attribute__((weak));
extern void __freertos_task_enter_critical() __attribute__((weak));
#ifdef __cplusplus
}
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive = false);
#endif // __cplusplus
Loading
Loading