mirror of
https://github.com/espressif/esp-idf.git
synced 2026-06-11 11:42:39 +02:00
add unit tests to esp-idf
rename nvs host test folder, modify .gitlab-ci.yml remove unit-test-app build re-format unit test files remove extra newlines in project.mk some refactoring for unit test part in project.mk add build files of unit-test-app in gitignore add README.md for unit test app correct headings in README.md remove files and make minor tweaks in unit test app update .gitlab-ci.yml to use unit test app delete unused lines in component_wrapper.mk delete periph_i2s.h and lcd test add text floating point in components/esp32/test/Kconfig correct idf test build paths in .gitlab-ci.yml
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
#
|
||||
#Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
|
||||
void ets_isr_unmask(uint32_t unmask);
|
||||
|
||||
static xQueueHandle myQueue;
|
||||
static xQueueHandle uartRxQueue;
|
||||
|
||||
int ctr;
|
||||
|
||||
#if 1
|
||||
//Idle-loop for delay. Tests involuntary yielding
|
||||
static void cvTaskDelay(int dummy)
|
||||
{
|
||||
volatile int i;
|
||||
for (i = 0; i < (1 << 17); i++);
|
||||
}
|
||||
#else
|
||||
//Delay task execution using FreeRTOS methods. Tests voluntary yielding.
|
||||
#define cvTaskDelay(x) vTaskDelay(x)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void dosegfault3(int i)
|
||||
{
|
||||
volatile char *p = (volatile char *)0;
|
||||
*p = i;
|
||||
}
|
||||
|
||||
static void dosegfault2(int i)
|
||||
{
|
||||
if (i > 3) {
|
||||
dosegfault3(i);
|
||||
}
|
||||
}
|
||||
|
||||
static void dosegfault(int i)
|
||||
{
|
||||
if (i < 5) {
|
||||
dosegfault(i + 1);
|
||||
}
|
||||
dosegfault2(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void queueSender(void *pvParameters)
|
||||
{
|
||||
int myCtr = xPortGetCoreID() * 100000;
|
||||
while (1) {
|
||||
printf("Core %d: Send to queue: %d\n", xPortGetCoreID(), myCtr);
|
||||
xQueueSend(myQueue, (void *)(&myCtr), portMAX_DELAY);
|
||||
printf("Send to queue done.\n");
|
||||
cvTaskDelay(100);
|
||||
myCtr++;
|
||||
}
|
||||
}
|
||||
|
||||
static void queueReceiver(void *pvParameters)
|
||||
{
|
||||
int theCtr;
|
||||
while (1) {
|
||||
xQueueReceive(myQueue, &theCtr, portMAX_DELAY);
|
||||
printf("Core %d: Receive from queue: %d\n", xPortGetCoreID(), theCtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tskone(void *pvParameters)
|
||||
{
|
||||
// char *p=(char *)0;
|
||||
while (1) {
|
||||
ctr++;
|
||||
// if (ctr>60) dosegfault(3);
|
||||
printf("Task1, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
|
||||
cvTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void tsktwo(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
ctr++;
|
||||
printf("Task2, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
|
||||
cvTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void tskthree(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
ctr++;
|
||||
printf("Task3, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
|
||||
cvTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void tskfour(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
ctr++;
|
||||
printf("Task4, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
|
||||
cvTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void tskfive(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
ctr++;
|
||||
printf("Task5, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
|
||||
cvTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
static void tskyield(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
|
||||
static void tskUartRecv(void *pvParameters)
|
||||
{
|
||||
char c;
|
||||
while (1) {
|
||||
xQueueReceive(uartRxQueue, &c, portMAX_DELAY);
|
||||
printf("Uart received %c!\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uartIsrHdl(void *arg)
|
||||
{
|
||||
char c;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR);
|
||||
while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
|
||||
c = READ_PERI_REG(UART_FIFO_REG(0));
|
||||
xQueueSendFromISR(uartRxQueue, &c, &xHigherPriorityTaskWoken);
|
||||
printf("ISR: %c\n", c);
|
||||
}
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void uartRxInit(xQueueHandle q)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
|
||||
|
||||
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
|
||||
|
||||
// reg_val = READ_PERI_REG(UART_CONF1(0));
|
||||
reg_val = (1 << UART_RXFIFO_FULL_THRHD_S);
|
||||
WRITE_PERI_REG(UART_CONF1_REG(0), reg_val);
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA);
|
||||
|
||||
printf("Enabling int %d\n", ETS_UART0_INUM);
|
||||
REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM);
|
||||
REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM);
|
||||
|
||||
xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL);
|
||||
xt_ints_on(1 << ETS_UART0_INUM);
|
||||
|
||||
}
|
||||
|
||||
// TODO: split this thing into separate orthogonal tests
|
||||
TEST_CASE("Bunch of FreeRTOS tests", "[freertos]")
|
||||
{
|
||||
char *tst;
|
||||
TaskHandle_t th[12];
|
||||
int i;
|
||||
printf("%s\n", __FUNCTION__);
|
||||
tst = pvPortMalloc(16);
|
||||
printf("Test malloc returns addr %p\n", tst);
|
||||
printf("Free heap: %u\n", xPortGetFreeHeapSize());
|
||||
myQueue = xQueueCreate(10, sizeof(int));
|
||||
uartRxQueue = xQueueCreate(256, sizeof(char));
|
||||
printf("Free heap: %u\n", xPortGetFreeHeapSize());
|
||||
|
||||
printf("Creating tasks\n");
|
||||
xTaskCreatePinnedToCore(tskyield , "tskyield1" , 2048, NULL, 3, &th[0], 0);
|
||||
xTaskCreatePinnedToCore(tskyield , "tskyield2" , 2048, NULL, 3, &th[1], 1);
|
||||
|
||||
xTaskCreatePinnedToCore(tskone , "tskone" , 2048, NULL, 3, &th[2], 0);
|
||||
xTaskCreatePinnedToCore(tsktwo , "tsktwo" , 2048, NULL, 3, &th[3], 1);
|
||||
xTaskCreatePinnedToCore(tskthree, "tskthree", 2048, NULL, 3, &th[4], 0);
|
||||
xTaskCreatePinnedToCore(tskfour , "tskfour" , 2048, NULL, 3, &th[5], tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(tskfive , "tskfive" , 2048, NULL, 3, &th[6], tskNO_AFFINITY);
|
||||
xTaskCreatePinnedToCore(queueSender , "qsend1" , 2048, NULL, 3, &th[7], 0);
|
||||
xTaskCreatePinnedToCore(queueSender , "qsend2" , 2048, NULL, 3, &th[8], 1);
|
||||
xTaskCreatePinnedToCore(queueReceiver , "qrecv1" , 2048, NULL, 3, &th[9], 1);
|
||||
xTaskCreatePinnedToCore(queueReceiver , "qrecv2" , 2048, NULL, 3, &th[10], 0);
|
||||
xTaskCreatePinnedToCore(tskUartRecv , "tskuart" , 2048, NULL, 4, &th[11], 1);
|
||||
printf("Free heap: %u\n", xPortGetFreeHeapSize());
|
||||
uartRxInit(uartRxQueue);
|
||||
|
||||
// Let stuff run for 20s
|
||||
vTaskDelay(20000 / portTICK_PERIOD_MS);
|
||||
|
||||
//Shut down all the tasks
|
||||
for (i = 0; i < 12; i++) {
|
||||
vTaskDelete(th[i]);
|
||||
}
|
||||
xt_ints_off(1 << ETS_UART0_INUM);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "unity.h"
|
||||
|
||||
#define BIT_CALL (1 << 0)
|
||||
#define BIT_RESPONSE(TASK) (1 << (TASK+1))
|
||||
#define ALL_RESPONSE_BITS (((1 << NUM_TASKS) - 1) << 1)
|
||||
|
||||
static const int NUM_TASKS = 4;
|
||||
static const int COUNT = 4000;
|
||||
static EventGroupHandle_t eg;
|
||||
|
||||
static void task_event_group_call_response(void *param)
|
||||
{
|
||||
int task_num = (int)param;
|
||||
|
||||
printf("Started %d\n", task_num);
|
||||
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
/* Wait until the common "call" bit is set, starts off all tasks
|
||||
(clear on return) */
|
||||
while (!xEventGroupWaitBits(eg, BIT_CALL, true, false, portMAX_DELAY)) {
|
||||
}
|
||||
|
||||
/* Set our individual "response" bit */
|
||||
xEventGroupSetBits(eg, BIT_RESPONSE(task_num));
|
||||
}
|
||||
|
||||
printf("Task %d done\n", task_num);
|
||||
|
||||
/* Delay is due to not-yet-fixed bug with deleting tasks at same time */
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("FreeRTOS Event Groups", "[freertos]")
|
||||
{
|
||||
eg = xEventGroupCreate();
|
||||
|
||||
/* Note: task_event_group_call_response all have higher priority than us, so will block together.
|
||||
|
||||
This is important because we need to know they'll all have blocked on BIT_CALL each time we
|
||||
signal it, or they get out of sync.
|
||||
*/
|
||||
for (int c = 0; c < NUM_TASKS; c++) {
|
||||
xTaskCreatePinnedToCore(task_event_group_call_response, "tsk_call_resp", 4096, (void *)c, configMAX_PRIORITIES - 1, NULL, c % portNUM_PROCESSORS);
|
||||
}
|
||||
/* Scheduler weirdness, if we don't sleep a few ticks here then the tasks on the other CPU aren't running yet... */
|
||||
vTaskDelay(10);
|
||||
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
if (i % 100 == 0) {
|
||||
//printf("Call %d\n", i);
|
||||
}
|
||||
/* signal all tasks with "CALL" bit... */
|
||||
xEventGroupSetBits(eg, BIT_CALL);
|
||||
|
||||
while (xEventGroupWaitBits(eg, ALL_RESPONSE_BITS, true, true, portMAX_DELAY) != ALL_RESPONSE_BITS) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define BIT_DONE(X) (1<<(NUM_TASKS+1+X))
|
||||
|
||||
static void task_test_sync(void *param)
|
||||
{
|
||||
int task_num = (int)param;
|
||||
|
||||
printf("Started %d\n", task_num);
|
||||
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
/* set our bit, and wait on all tasks to set their bits */
|
||||
xEventGroupSync(eg, BIT_RESPONSE(task_num), ALL_RESPONSE_BITS, portMAX_DELAY);
|
||||
/* clear our bit */
|
||||
xEventGroupClearBits(eg, BIT_RESPONSE(task_num));
|
||||
}
|
||||
int after_done = xEventGroupSetBits(eg, BIT_DONE(task_num));
|
||||
|
||||
printf("Done %d = %x\n", task_num, after_done);
|
||||
|
||||
/* Delay is due to not-yet-fixed bug with deleting tasks at same time */
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("FreeRTOS Event Group Sync", "[freertos]")
|
||||
{
|
||||
eg = xEventGroupCreate();
|
||||
|
||||
for (int c = 0; c < NUM_TASKS; c++) {
|
||||
xTaskCreatePinnedToCore(task_test_sync, "task_test_sync", 4096, (void *)c, configMAX_PRIORITIES - 1, NULL, c % portNUM_PROCESSORS);
|
||||
}
|
||||
|
||||
for (int c = 0; c < NUM_TASKS; c++) {
|
||||
printf("Waiting on %d (%x)\n", c, BIT_DONE(c));
|
||||
xEventGroupWaitBits(eg, BIT_DONE(c), false, false, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "unity.h"
|
||||
|
||||
static void task_delete_self(void *param)
|
||||
{
|
||||
printf("Task %p running on core %d. Deleting shortly...\n", xTaskGetCurrentTaskHandle(), xPortGetCoreID());
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("FreeRTOS Delete Tasks", "[freertos]")
|
||||
{
|
||||
xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
xTaskCreatePinnedToCore(task_delete_self, "tsk_self_a", 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
printf("Done?\n");
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
|
||||
volatile static int done;
|
||||
volatile static int error;
|
||||
|
||||
static void tskTestRand(void *pvParameters)
|
||||
{
|
||||
int l;
|
||||
srand(0x1234);
|
||||
vTaskDelay((int)pvParameters / portTICK_PERIOD_MS);
|
||||
l = rand();
|
||||
printf("Rand1: %d\n", l);
|
||||
if (l != 869320854) {
|
||||
error++;
|
||||
}
|
||||
vTaskDelay((int)pvParameters / portTICK_PERIOD_MS);
|
||||
l = rand();
|
||||
printf("Rand2: %d\n", l);
|
||||
if (l != 1148737841) {
|
||||
error++;
|
||||
}
|
||||
done++;
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: split this thing into separate orthogonal tests
|
||||
TEST_CASE("Test for per-task non-reentrant tasks", "[freertos]")
|
||||
{
|
||||
done = 0;
|
||||
error = 0;
|
||||
xTaskCreatePinnedToCore(tskTestRand, "tsk1", 2048, (void *)100, 3, NULL, 0);
|
||||
xTaskCreatePinnedToCore(tskTestRand, "tsk2", 2048, (void *)200, 3, NULL, 0);
|
||||
xTaskCreatePinnedToCore(tskTestRand, "tsk3", 2048, (void *)300, 3, NULL, 1);
|
||||
xTaskCreatePinnedToCore(tskTestRand, "tsk4", 2048, (void *)400, 3, NULL, 0);
|
||||
while (done != 4) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
TEST_ASSERT(error == 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
|
||||
TEST_CASE("Panic handler", "[freertos]")
|
||||
{
|
||||
volatile int *i;
|
||||
i = (volatile int *)0x0;
|
||||
*i = 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Test for multicore FreeRTOS ringbuffer.
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void ets_isr_unmask(uint32_t unmask);
|
||||
|
||||
static RingbufHandle_t rb;
|
||||
typedef enum {
|
||||
TST_MOSTLYFILLED,
|
||||
TST_MOSTLYEMPTY,
|
||||
TST_INTTOTASK,
|
||||
TST_TASKTOINT,
|
||||
} testtype_t;
|
||||
|
||||
static volatile testtype_t testtype;
|
||||
|
||||
static void task1(void *arg)
|
||||
{
|
||||
testtype_t oldtest;
|
||||
char buf[100];
|
||||
int i = 0;
|
||||
int x, r;
|
||||
while (1) {
|
||||
oldtest = testtype;
|
||||
if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) {
|
||||
for (x = 0; x < 10; x++) {
|
||||
sprintf(buf, "This is test %d item %d.", (int)testtype, i++);
|
||||
ets_printf("TSK w");
|
||||
xRingbufferPrintInfo(rb);
|
||||
r = xRingbufferSend(rb, buf, strlen(buf) + 1, 2000 / portTICK_PERIOD_MS);
|
||||
if (!r) {
|
||||
printf("Test %d: Timeout on send!\n", (int)testtype);
|
||||
}
|
||||
if (testtype == TST_MOSTLYEMPTY) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
//Send NULL event to stop other side.
|
||||
r = xRingbufferSend(rb, NULL, 0, 10000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
while (oldtest == testtype) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void task2(void *arg)
|
||||
{
|
||||
testtype_t oldtest;
|
||||
char *buf;
|
||||
size_t len;
|
||||
while (1) {
|
||||
oldtest = testtype;
|
||||
if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) {
|
||||
while (1) {
|
||||
ets_printf("TSK r");
|
||||
xRingbufferPrintInfo(rb);
|
||||
buf = xRingbufferReceive(rb, &len, 2000 / portTICK_PERIOD_MS);
|
||||
if (buf == NULL) {
|
||||
printf("Test %d: Timeout on recv!\n", (int)testtype);
|
||||
} else if (len == 0) {
|
||||
printf("End packet received.\n");
|
||||
vRingbufferReturnItem(rb, buf);
|
||||
break;
|
||||
} else {
|
||||
printf("Received: %s (%d bytes, %p)\n", buf, len, buf);
|
||||
vRingbufferReturnItem(rb, buf);
|
||||
}
|
||||
if (testtype == TST_MOSTLYFILLED) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (oldtest == testtype) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void uartIsrHdl(void *arg)
|
||||
{
|
||||
char c;
|
||||
char buf[50];
|
||||
char *item;
|
||||
int r;
|
||||
size_t len;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR);
|
||||
while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
|
||||
c = READ_PERI_REG(UART_FIFO_REG(0));
|
||||
if (c == 'r') {
|
||||
ets_printf("ISR r");
|
||||
xRingbufferPrintInfo(rb);
|
||||
item = xRingbufferReceiveFromISR(rb, &len);
|
||||
if (item == NULL) {
|
||||
ets_printf("ISR recv fail!\n");
|
||||
} else if (len == 0) {
|
||||
ets_printf("ISR recv NULL!\n");
|
||||
vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
|
||||
} else {
|
||||
ets_printf("ISR recv '%s' (%d bytes, %p)\n", buf, len, buf);
|
||||
vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
} else {
|
||||
sprintf(buf, "UART: %c", c);
|
||||
ets_printf("ISR w");
|
||||
xRingbufferPrintInfo(rb);
|
||||
r = xRingbufferSendFromISR(rb, buf, strlen(buf) + 1, &xHigherPriorityTaskWoken);
|
||||
if (!r) {
|
||||
ets_printf("ISR send fail\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static void uartRxInit()
|
||||
{
|
||||
uint32_t reg_val;
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
|
||||
|
||||
// reg_val = READ_PERI_REG(UART_CONF1(0));
|
||||
reg_val = (1 << UART_RXFIFO_FULL_THRHD_S);
|
||||
WRITE_PERI_REG(UART_CONF1_REG(0), reg_val);
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
|
||||
SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA);
|
||||
|
||||
printf("Enabling int %d\n", ETS_UART0_INUM);
|
||||
REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM);
|
||||
REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM);
|
||||
|
||||
xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL);
|
||||
xt_ints_on(1 << ETS_UART0_INUM);
|
||||
|
||||
}
|
||||
|
||||
static void testRingbuffer(int type)
|
||||
{
|
||||
TaskHandle_t th[2];
|
||||
int i;
|
||||
rb = xRingbufferCreate(32 * 3, type);
|
||||
|
||||
testtype = TST_MOSTLYFILLED;
|
||||
|
||||
xTaskCreatePinnedToCore(task1 , "tskone" , 2048, NULL, 3, &th[0], 0);
|
||||
xTaskCreatePinnedToCore(task2 , "tsktwo" , 2048, NULL, 3, &th[1], 0);
|
||||
uartRxInit();
|
||||
|
||||
printf("Press 'r' to read an event in isr, any other key to write one.\n");
|
||||
printf("Test: mostlyfilled; putting 10 items in ringbuff ASAP, reading 1 a second\n");
|
||||
vTaskDelay(15000 / portTICK_PERIOD_MS);
|
||||
printf("Test: mostlyempty; putting 10 items in ringbuff @ 1/sec, reading as fast as possible\n");
|
||||
testtype = TST_MOSTLYEMPTY;
|
||||
vTaskDelay(15000 / portTICK_PERIOD_MS);
|
||||
|
||||
//Shut down all the tasks
|
||||
for (i = 0; i < 2; i++) {
|
||||
vTaskDelete(th[i]);
|
||||
}
|
||||
xt_ints_off(1 << ETS_UART0_INUM);
|
||||
}
|
||||
|
||||
// TODO: split this thing into separate orthogonal tests
|
||||
TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos]")
|
||||
{
|
||||
testRingbuffer(0);
|
||||
}
|
||||
|
||||
TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos]")
|
||||
{
|
||||
testRingbuffer(1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
|
||||
|
||||
static void tskdelcb(int no, void *arg)
|
||||
{
|
||||
printf("Delete callback: %d = %p!\n", no, arg);
|
||||
}
|
||||
|
||||
|
||||
static void tska(void *pvParameters)
|
||||
{
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), 0, (void *)0xAAAAAAAA, tskdelcb);
|
||||
while (1) {
|
||||
vTaskDelay(10000000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
static void tskb(void *pvParameters)
|
||||
{
|
||||
vTaskSetThreadLocalStoragePointerAndDelCallback(xTaskGetCurrentTaskHandle(), 0, (void *)0xBBBBBBBB, tskdelcb);
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
TaskHandle_t a = (TaskHandle_t)pvParameters;
|
||||
printf("Killing task A\n");
|
||||
vTaskDelete(a);
|
||||
while (1) {
|
||||
vTaskDelay(10000000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: split this thing into separate orthogonal tests
|
||||
TEST_CASE("Freertos TLS delete cb", "[freertos]")
|
||||
{
|
||||
TaskHandle_t a, b;
|
||||
|
||||
xTaskCreatePinnedToCore(tska , "tska" , 2048, NULL, 3, &a, 0);
|
||||
xTaskCreatePinnedToCore(tskb , "tska" , 2048, a, 3, &b, 0);
|
||||
|
||||
// Let stuff run for 20s
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
printf("Killing task B\n");
|
||||
//Shut down b
|
||||
vTaskDelete(b);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user