mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 17:49:10 -04:00
Merge branch 'feature/ulp_riscv_test_multiple_firmware' into 'master'
ulp-riscv: Added API ulp_riscv_reset to reset the ULP core See merge request espressif/esp-idf!22165
This commit is contained in:
commit
27be8a1ebb
@ -1,5 +1,7 @@
|
|||||||
set(app_sources "test_app_main.c" "test_ulp_riscv.c")
|
set(app_sources "test_app_main.c" "test_ulp_riscv.c")
|
||||||
set(ulp_sources "ulp/test_main.c")
|
set(ulp_sources "ulp/test_main.c")
|
||||||
|
set(ulp_sources2 "ulp/test_main_second_cocpu_firmware.c")
|
||||||
|
set(ulp_sources3 "ulp/test_main_cocpu_crash.c")
|
||||||
|
|
||||||
idf_component_register(SRCS ${app_sources}
|
idf_component_register(SRCS ${app_sources}
|
||||||
INCLUDE_DIRS "ulp"
|
INCLUDE_DIRS "ulp"
|
||||||
@ -7,5 +9,9 @@ idf_component_register(SRCS ${app_sources}
|
|||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
||||||
set(ulp_app_name ulp_test_app)
|
set(ulp_app_name ulp_test_app)
|
||||||
|
set(ulp_app_name2 ulp_test_app2)
|
||||||
|
set(ulp_app_name3 ulp_test_app3)
|
||||||
set(ulp_exp_dep_srcs ${app_sources})
|
set(ulp_exp_dep_srcs ${app_sources})
|
||||||
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
|
ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}")
|
||||||
|
ulp_embed_binary(${ulp_app_name2} "${ulp_sources2}" "${ulp_exp_dep_srcs}")
|
||||||
|
ulp_embed_binary(${ulp_app_name3} "${ulp_sources3}" "${ulp_exp_dep_srcs}")
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "ulp_riscv.h"
|
#include "ulp_riscv.h"
|
||||||
#include "ulp_riscv_lock.h"
|
#include "ulp_riscv_lock.h"
|
||||||
#include "ulp_test_app.h"
|
#include "ulp_test_app.h"
|
||||||
|
#include "ulp_test_app2.h"
|
||||||
#include "ulp_test_shared.h"
|
#include "ulp_test_shared.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -22,20 +23,28 @@
|
|||||||
|
|
||||||
#define ULP_WAKEUP_PERIOD 1000000 // 1 second
|
#define ULP_WAKEUP_PERIOD 1000000 // 1 second
|
||||||
|
|
||||||
|
// First ULP firmware
|
||||||
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_test_app_bin_start");
|
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_test_app_bin_start");
|
||||||
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_test_app_bin_end");
|
extern const size_t ulp_main_bin_length asm("ulp_test_app_bin_length");
|
||||||
static bool firmware_loaded = false;
|
static bool firmware_loaded = false;
|
||||||
|
|
||||||
static void load_and_start_ulp_firmware(void)
|
// Second ULP firmware
|
||||||
|
extern const uint8_t ulp_test_app2_bin_start[] asm("_binary_ulp_test_app2_bin_start");
|
||||||
|
extern const size_t ulp_test_app2_bin_length asm("ulp_test_app2_bin_length");
|
||||||
|
|
||||||
|
// Faulty ULP firmware
|
||||||
|
extern const uint8_t ulp_test_app3_bin_start[] asm("_binary_ulp_test_app3_bin_start");
|
||||||
|
extern const size_t ulp_test_app3_bin_length asm("ulp_test_app3_bin_length");
|
||||||
|
|
||||||
|
static void load_and_start_ulp_firmware(const uint8_t* ulp_bin, size_t ulp_bin_len)
|
||||||
{
|
{
|
||||||
if (!firmware_loaded) {
|
if (!firmware_loaded) {
|
||||||
TEST_ASSERT(ulp_riscv_load_binary(ulp_main_bin_start,
|
TEST_ASSERT(ulp_riscv_load_binary(ulp_bin, ulp_bin_len) == ESP_OK);
|
||||||
(ulp_main_bin_end - ulp_main_bin_start)) == ESP_OK);
|
|
||||||
|
|
||||||
TEST_ASSERT(ulp_set_wakeup_period(0, ULP_WAKEUP_PERIOD) == ESP_OK);
|
TEST_ASSERT(ulp_set_wakeup_period(0, ULP_WAKEUP_PERIOD) == ESP_OK);
|
||||||
TEST_ASSERT(ulp_riscv_run() == ESP_OK);
|
TEST_ASSERT(ulp_riscv_run() == ESP_OK);
|
||||||
|
|
||||||
firmware_loaded = true;
|
firmware_loaded = true;
|
||||||
|
printf("New ULP firmware loaded\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +54,7 @@ TEST_CASE("ULP-RISC-V and main CPU are able to exchange data", "[ulp]")
|
|||||||
struct timeval start, end;
|
struct timeval start, end;
|
||||||
|
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
/* Setup wakeup triggers */
|
/* Setup wakeup triggers */
|
||||||
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
||||||
@ -79,7 +88,7 @@ TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp]")
|
|||||||
struct timeval start, end;
|
struct timeval start, end;
|
||||||
|
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
/* Setup wakeup triggers */
|
/* Setup wakeup triggers */
|
||||||
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
||||||
@ -119,14 +128,14 @@ TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp]")
|
|||||||
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ulp_riscv_is_running(void)
|
static bool ulp_riscv_is_running(uint32_t *counter_variable)
|
||||||
{
|
{
|
||||||
uint32_t start_cnt = ulp_riscv_counter;
|
uint32_t start_cnt = *counter_variable;
|
||||||
|
|
||||||
/* Wait a few ULP wakeup cycles to ensure ULP has run */
|
/* Wait a few ULP wakeup cycles to ensure ULP has run */
|
||||||
vTaskDelay((5 * ULP_WAKEUP_PERIOD / 1000) / portTICK_PERIOD_MS);
|
vTaskDelay((5 * ULP_WAKEUP_PERIOD / 1000) / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
uint32_t end_cnt = ulp_riscv_counter;
|
uint32_t end_cnt = *counter_variable;
|
||||||
printf("start run count: %" PRIu32 ", end run count %" PRIu32 "\n", start_cnt, end_cnt);
|
printf("start run count: %" PRIu32 ", end run count %" PRIu32 "\n", start_cnt, end_cnt);
|
||||||
|
|
||||||
/* If the ulp is running the counter should have been incremented */
|
/* If the ulp is running the counter should have been incremented */
|
||||||
@ -136,20 +145,89 @@ static bool ulp_riscv_is_running(void)
|
|||||||
TEST_CASE("ULP-RISC-V can be stopped and resumed from main CPU", "[ulp]")
|
TEST_CASE("ULP-RISC-V can be stopped and resumed from main CPU", "[ulp]")
|
||||||
{
|
{
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
TEST_ASSERT(ulp_riscv_is_running());
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
printf("Stopping the ULP\n");
|
printf("Stopping the ULP\n");
|
||||||
ulp_riscv_timer_stop();
|
ulp_riscv_timer_stop();
|
||||||
ulp_riscv_halt();
|
ulp_riscv_halt();
|
||||||
|
|
||||||
TEST_ASSERT(!ulp_riscv_is_running());
|
TEST_ASSERT(!ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
printf("Resuming the ULP\n");
|
printf("Resuming the ULP\n");
|
||||||
ulp_riscv_timer_resume();
|
ulp_riscv_timer_resume();
|
||||||
|
|
||||||
TEST_ASSERT(ulp_riscv_is_running());
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ULP-RISC-V can be loaded with and run multiple firmwares", "[ulp]")
|
||||||
|
{
|
||||||
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
|
printf("Stopping the ULP\n");
|
||||||
|
ulp_riscv_timer_stop();
|
||||||
|
ulp_riscv_halt();
|
||||||
|
|
||||||
|
TEST_ASSERT(!ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
|
printf("Loading second firmware on the ULP\n");
|
||||||
|
firmware_loaded = false;
|
||||||
|
load_and_start_ulp_firmware(ulp_test_app2_bin_start, ulp_test_app2_bin_length);
|
||||||
|
|
||||||
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter2));
|
||||||
|
|
||||||
|
printf("Stopping the ULP\n");
|
||||||
|
ulp_riscv_timer_stop();
|
||||||
|
ulp_riscv_halt();
|
||||||
|
|
||||||
|
TEST_ASSERT(!ulp_riscv_is_running(&ulp_riscv_counter2));
|
||||||
|
|
||||||
|
printf("Loading the first firmware again on the ULP\n");
|
||||||
|
firmware_loaded = false;
|
||||||
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("ULP-RISC-V can be reloaded with a good fimware after a crash", "[ulp]")
|
||||||
|
{
|
||||||
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
|
printf("Stopping the ULP\n");
|
||||||
|
ulp_riscv_timer_stop();
|
||||||
|
ulp_riscv_halt();
|
||||||
|
|
||||||
|
TEST_ASSERT(!ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
|
/* Enable ULP wakeup */
|
||||||
|
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
||||||
|
|
||||||
|
printf("Loading faulty firmware on the ULP and go into light sleep\n");
|
||||||
|
firmware_loaded = false;
|
||||||
|
load_and_start_ulp_firmware(ulp_test_app3_bin_start, ulp_test_app3_bin_length);
|
||||||
|
esp_light_sleep_start();
|
||||||
|
|
||||||
|
/* Verify that main CPU wakes up by a COCPU trap signal trigger */
|
||||||
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
|
TEST_ASSERT(cause != ESP_SLEEP_WAKEUP_COCPU);
|
||||||
|
|
||||||
|
printf("Resetting the ULP\n");
|
||||||
|
ulp_riscv_reset();
|
||||||
|
|
||||||
|
esp_rom_delay_us(20);
|
||||||
|
|
||||||
|
printf("Loading the good firmware on ULP\n");
|
||||||
|
firmware_loaded = false;
|
||||||
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]")
|
TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]")
|
||||||
@ -157,9 +235,9 @@ TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]"
|
|||||||
volatile riscv_test_commands_t *command_resp = (riscv_test_commands_t*)&ulp_command_resp;
|
volatile riscv_test_commands_t *command_resp = (riscv_test_commands_t*)&ulp_command_resp;
|
||||||
|
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
TEST_ASSERT(ulp_riscv_is_running());
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
printf("Stopping the ULP\n");
|
printf("Stopping the ULP\n");
|
||||||
/* Setup test data */
|
/* Setup test data */
|
||||||
@ -171,13 +249,13 @@ TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]"
|
|||||||
/* Wait a bit to ensure ULP finished shutting down */
|
/* Wait a bit to ensure ULP finished shutting down */
|
||||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
TEST_ASSERT(!ulp_riscv_is_running());
|
TEST_ASSERT(!ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
|
|
||||||
printf("Resuming the ULP\n");
|
printf("Resuming the ULP\n");
|
||||||
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
ulp_main_cpu_command = RISCV_NO_COMMAND;
|
||||||
ulp_riscv_timer_resume();
|
ulp_riscv_timer_resume();
|
||||||
|
|
||||||
TEST_ASSERT(ulp_riscv_is_running());
|
TEST_ASSERT(ulp_riscv_is_running(&ulp_riscv_counter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,7 +263,7 @@ TEST_CASE("ULP-RISC-V can stop itself and be resumed from the main CPU", "[ulp]"
|
|||||||
TEST_CASE("ULP-RISC-V mutex", "[ulp]")
|
TEST_CASE("ULP-RISC-V mutex", "[ulp]")
|
||||||
{
|
{
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
/* Setup test data */
|
/* Setup test data */
|
||||||
ulp_riscv_incrementer = 0;
|
ulp_riscv_incrementer = 0;
|
||||||
@ -219,7 +297,7 @@ static void do_ulp_wakeup_deepsleep(riscv_test_commands_t ulp_cmd, bool rtc_peri
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
/* Load ULP RISC-V firmware and start the ULP RISC-V Coprocessor */
|
||||||
load_and_start_ulp_firmware();
|
load_and_start_ulp_firmware(ulp_main_bin_start, ulp_main_bin_length);
|
||||||
|
|
||||||
/* Setup wakeup triggers */
|
/* Setup wakeup triggers */
|
||||||
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK);
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
/* Make sure ULP core crashes by doing a NULL pointer access */
|
||||||
|
uint32_t *null_ptr = NULL;
|
||||||
|
*null_ptr = 1;
|
||||||
|
|
||||||
|
/* ulp_riscv_halt() is called automatically when main exits */
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
volatile uint32_t riscv_counter2 = 0;
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
riscv_counter2++;
|
||||||
|
|
||||||
|
/* ulp_riscv_halt() is called automatically when main exits */
|
||||||
|
return 0;
|
||||||
|
}
|
@ -92,6 +92,15 @@ void ulp_riscv_timer_resume(void);
|
|||||||
*/
|
*/
|
||||||
void ulp_riscv_halt(void);
|
void ulp_riscv_halt(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the ULP-RISC-V core from the main CPU
|
||||||
|
*
|
||||||
|
* @note This will reset the ULP core from the main CPU. It is intended to be used when the
|
||||||
|
* ULP is in a bad state and cannot run as intended due to a corrupt firmware or any other reason.
|
||||||
|
* The main core can reset the ULP core with this API and then re-initilialize the ULP.
|
||||||
|
*/
|
||||||
|
void ulp_riscv_reset(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,6 +142,15 @@ void ulp_riscv_halt(void)
|
|||||||
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
|
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ulp_riscv_reset()
|
||||||
|
{
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT | RTC_CNTL_COCPU_DONE);
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
|
||||||
|
esp_rom_delay_us(20);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT | RTC_CNTL_COCPU_DONE);
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes)
|
esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes)
|
||||||
{
|
{
|
||||||
if (program_binary == NULL) {
|
if (program_binary == NULL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user