Загрузка данных


#include <zephyr/kernel.h>
#include <string.h>

/* Размеры массивов (кратно 4 байтам для выравнивания) */
#define RESAMPLE_BUF_SIZE     160
#define FLOOD_ARRAY_SIZE      (256 * 1024) /* 256 КБ (заведомо больше D-Cache) */
#define STACK_SIZE            2048
#define TEST_THREAD_PRIO      5

/* Флуд-буфер, который принудительно размещается в SDRAM */
static uint32_t flood_buffer[FLOOD_ARRAY_SIZE] __attribute__((section(".sdram_data")));
volatile uint32_t flood_dummy_sink;

/* Буферы для ресемплера */
/* В зависимости от Теста 1 или 2, линкер положит их в SDRAM или DTCM */
static int16_t resample_in_buf[RESAMPLE_BUF_SIZE];
static int16_t resample_out_buf[RESAMPLE_BUF_SIZE * 2];

/* Прототип функции из PJMEDIA resamplesubs.c */
extern int res_Resample(const int16_t X[], int16_t Y[], double pFactor,
                        uint16_t nx, int LargeF, int Interp);

/* --- Поток 1: Вычислительное ядро (Resample) --- */
K_THREAD_STACK_DEFINE(resample_stack, STACK_SIZE);
struct k_thread resample_thread_data;

void resample_test_thread(void *p1, void *p2, void *p3)
{
    /* Заполняем входной буфер тестовым сигналом */
    for (int i = 0; i < RESAMPLE_BUF_SIZE; i++) {
        resample_in_buf[i] = (int16_t)(i * 100);
    }

    while (1) {
        /* Вызываем ресемплер с использованием Large Filter (LargeF = 1) */
        /* pFactor = 2.0 (Up-sampling), nx = 160, Interp = 1 */
        res_Resample(resample_in_buf, resample_out_buf, 2.0, 
                     RESAMPLE_BUF_SIZE, 1, 1);

        /* Уступаем квант времени планировщику, чтобы дать поработать вредителю */
        k_yield();
    }
}

/* --- Поток 2: Интенсивное чтение (Вредитель шины SEMC) --- */
K_THREAD_STACK_DEFINE(flooder_stack, STACK_SIZE);
struct k_thread flooder_thread_data;

void memory_flooder_thread(void *p1, void *p2, void *p3)
{
    while (1) {
        /* Непрерывное линейное чтение всего огромного массива */
        for (int i = 0; i < FLOOD_ARRAY_SIZE; i++) {
            flood_dummy_sink = flood_buffer[i];
        }
        k_yield();
    }
}

/* --- Главный поток инициализации --- */
int main(void)
{
    printk("Starting SEMC Bus Torture Test...\n");

    /* Инициализируем флуд-массив мусором во избежание оптимизаций компилятора */
    for (int i = 0; i < FLOOD_ARRAY_SIZE; i++) {
        flood_buffer[i] = i * 3;
    }

    /* Запускаем поток ресемплера */
    k_thread_create(&resample_thread_data, resample_stack,
                    K_THREAD_STACK_SIZEOF(resample_stack),
                    resample_test_thread, NULL, NULL, NULL,
                    TEST_THREAD_PRIO, 0, K_NO_WAIT);
    k_thread_name_set(&resample_thread_data, "torture_res");

    /* Запускаем поток-вредитель */
    k_thread_create(&flooder_thread_data, flooder_stack,
                    K_THREAD_STACK_SIZEOF(flooder_stack),
                    memory_flooder_thread, NULL, NULL, NULL,
                    TEST_THREAD_PRIO, 0, K_NO_WAIT);
    k_thread_name_set(&flooder_thread_data, "torture_flood");

    return 0;
}