| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  Test for thread local storage support. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <esp_types.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/task.h"
 | 
					
						
							|  |  |  | #include "unity.h"
 | 
					
						
							| 
									
										
										
										
											2018-10-25 12:52:32 +08:00
										 |  |  | #include "test_utils.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  | #include "sdkconfig.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-02 14:25:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  | static __thread int tl_test_var1; | 
					
						
							|  |  |  | static __thread uint8_t tl_test_var2 = 55; | 
					
						
							|  |  |  | static __thread uint16_t tl_test_var3 = 44; | 
					
						
							|  |  |  | static __thread uint8_t tl_test_arr_var[10]; | 
					
						
							|  |  |  | static __thread struct test_tls_var { | 
					
						
							|  |  |  |     int f32; | 
					
						
							|  |  |  |     uint8_t f8; | 
					
						
							|  |  |  |     uint16_t f16; | 
					
						
							|  |  |  |     uint8_t farr[10]; | 
					
						
							|  |  |  | } tl_test_struct_var; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void task_test_tls(void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     bool *running = (bool *)arg; | 
					
						
							|  |  |  |     uint32_t tp = (uint32_t)-1; | 
					
						
							|  |  |  |     int test_var1_old = 0; | 
					
						
							|  |  |  |     uint8_t test_var2_old = 0; | 
					
						
							|  |  |  |     uint16_t test_var3_old = 0; | 
					
						
							|  |  |  |     int f32_old = 0; | 
					
						
							|  |  |  |     uint8_t f8_old = 0; | 
					
						
							|  |  |  |     uint16_t f16_old = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asm volatile ("rur.threadptr %0":"=r"(tp)); | 
					
						
							|  |  |  |     for (int i = 0; i < 5; i++) { | 
					
						
							|  |  |  |         printf("Task[%x]: var = 0x%x 0x%x\n", tp, tl_test_var1, tl_test_var2); | 
					
						
							|  |  |  |         if (i == 0) { | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(0, tl_test_var1); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(55, tl_test_var2); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(44, tl_test_var3); | 
					
						
							|  |  |  |             for (int k = 0; k < sizeof(tl_test_arr_var); k++) { | 
					
						
							|  |  |  |                 TEST_ASSERT_EQUAL(0, tl_test_arr_var[k]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(0, tl_test_struct_var.f32); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(0, tl_test_struct_var.f8); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(0, tl_test_struct_var.f16); | 
					
						
							|  |  |  |             for (int k = 0; k < sizeof(tl_test_struct_var.farr); k++) { | 
					
						
							|  |  |  |                 TEST_ASSERT_EQUAL(0, tl_test_struct_var.farr[k]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(test_var1_old+1, tl_test_var1); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(test_var2_old+1, tl_test_var2); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(test_var3_old+1, tl_test_var3); | 
					
						
							|  |  |  |             for (int k = 0; k < sizeof(tl_test_arr_var); k++) { | 
					
						
							|  |  |  |                 TEST_ASSERT_EQUAL(i-1, tl_test_arr_var[k]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(f32_old+1, tl_test_struct_var.f32); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(f8_old+1, tl_test_struct_var.f8); | 
					
						
							|  |  |  |             TEST_ASSERT_EQUAL(f16_old+1, tl_test_struct_var.f16); | 
					
						
							|  |  |  |             for (int k = 0; k < sizeof(tl_test_struct_var.farr); k++) { | 
					
						
							|  |  |  |                 TEST_ASSERT_EQUAL(i-1, tl_test_struct_var.farr[k]); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         test_var1_old = tl_test_var1; | 
					
						
							|  |  |  |         test_var2_old = tl_test_var2; | 
					
						
							|  |  |  |         test_var3_old = tl_test_var3; | 
					
						
							|  |  |  |         f32_old = tl_test_struct_var.f32; | 
					
						
							|  |  |  |         f8_old = tl_test_struct_var.f8; | 
					
						
							|  |  |  |         f16_old = tl_test_struct_var.f16; | 
					
						
							|  |  |  |         tl_test_var1++; | 
					
						
							|  |  |  |         tl_test_var2++; | 
					
						
							|  |  |  |         tl_test_var3++; | 
					
						
							|  |  |  |         memset(tl_test_arr_var, i, sizeof(tl_test_arr_var)); | 
					
						
							|  |  |  |         tl_test_struct_var.f32++; | 
					
						
							|  |  |  |         tl_test_struct_var.f8++; | 
					
						
							|  |  |  |         tl_test_struct_var.f16++; | 
					
						
							|  |  |  |         memset(tl_test_struct_var.farr, i, sizeof(tl_test_struct_var.farr)); | 
					
						
							|  |  |  |         vTaskDelay(10); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (running) { | 
					
						
							|  |  |  |         *running = false; | 
					
						
							|  |  |  |         vTaskDelete(NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-02 14:25:33 +08:00
										 |  |  | TEST_CASE("TLS test", "[freertos]") | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-17 15:39:40 +10:00
										 |  |  |     const size_t stack_size = 3072; | 
					
						
							|  |  |  |     StackType_t s_stack[stack_size]; /* with 8KB test task stack (default) this test still has ~3KB headroom */ | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  |     StaticTask_t s_task; | 
					
						
							|  |  |  |     bool running[2] = {true, true}; | 
					
						
							|  |  |  | #if CONFIG_FREERTOS_UNICORE == 0
 | 
					
						
							|  |  |  |     int other_core = 1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     int other_core = 0; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-17 15:39:40 +10:00
										 |  |  |     xTaskCreatePinnedToCore((TaskFunction_t)&task_test_tls, "task_test_tls", stack_size, &running[0], | 
					
						
							|  |  |  |                             UNITY_FREERTOS_PRIORITY, NULL, 0); | 
					
						
							|  |  |  |     xTaskCreateStaticPinnedToCore((TaskFunction_t)&task_test_tls, "task_test_tls", stack_size, &running[1], | 
					
						
							|  |  |  |         UNITY_FREERTOS_PRIORITY, s_stack, &s_task, other_core); | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  |     while (running[0] || running[1]) { | 
					
						
							|  |  |  |         vTaskDelay(10); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-07-17 15:12:44 +10:00
										 |  |  |     vTaskDelay(10); /* Make sure idle task can clean up s_task, before it goes out of scope */ | 
					
						
							| 
									
										
										
										
											2018-02-05 01:06:45 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-07-17 15:12:44 +10:00
										 |  |  | 
 |