Просмотр исходного кода

Add script for compiler-based checkpoint insertions & benchmarks

Youngbin Kim 1 год назад
Родитель
Сommit
7d746269f9

+ 65 - 16
CMakeLists.txt

@@ -4,10 +4,18 @@ set(CMAKE_BUILD_TYPE Debug)
 set(CMAKE_VERBOSE_MAKEFILE 0)
 set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
 
-set(CMAKE_C_COMPILER arm-none-eabi-gcc) #tested with: clang, arm-none-eabi-gcc
+# user configurations: use -D option to change these on command line
+set(IMC_INSERT_COMPILER_CHECKPOINTS 1 CACHE BOOL "" FORCE)
+set(IMC_ENABLE_EXTENSION 1 CACHE BOOL "" FORCE)
+
+# set(CMAKE_C_COMPILER arm-none-eabi-gcc) #tested with: clang, arm-none-eabi-gcc
+set(CMAKE_C_COMPILER /home/ybkim/workspace/imc/llvm/llvm-17/build/bin/clang)
 set(CMAKE_SYSROOT "/opt/gcc-arm-none-eabi/arm-none-eabi")
-set(ARM_CORTEXM_MULTI_DIR "/opt/gcc-arm-none-eabi/arm-none-eabi/lib/thumb/v7e-m+fp/hard")
-set(ARM_CORTEXM_BUILTINS_DIR "/opt/gcc-arm-none-eabi/lib/gcc/arm-none-eabi/11.2.1/thumb/v7e-m+fp/hard")
+set(ARM_CORTEXM_MULTI_DIR "/opt/gcc-arm-none-eabi/arm-none-eabi/lib/thumb/v8-m.main+fp/hard")
+set(ARM_CORTEXM_BUILTINS_DIR "/opt/gcc-arm-none-eabi/lib/gcc/arm-none-eabi/11.2.1/thumb/v8-m.main+fp/hard")
+set(OPT_BIN /home/ybkim/workspace/imc/llvm/llvm-17/build/bin/opt)
+set(LLC_BIN /home/ybkim/workspace/imc/llvm/llvm-17/build/bin/llc)
+set(LLVM_OPT_PLUGIN /home/ybkim/workspace/imc/loop_duplication/build/lib/libImcInsertCheckpoints.so)
 
 set(SRC_FILES
     USB_Device/Target/usbd_conf.c
@@ -65,7 +73,6 @@ set(SRC_FILES
     Core/Src/ImC/decoder.c
     Core/Src/ImC/imc_api.c
     Core/Src/ImC/imc_kernel.c
-    # Core/Src/ImC/uartBufferIT.c
     Core/Src/app_freertos.c
     Core/Src/main.c
     Core/Src/stm32l5xx_hal_msp.c
@@ -74,6 +81,7 @@ set(SRC_FILES
     Core/Src/syscalls.c
     Core/Src/sysmem.c
     Core/Src/system_stm32l5xx.c
+    Core/Src/benchmarks/benchmark_driver.c
 )
 
 include_directories(
@@ -91,6 +99,21 @@ include_directories(
     Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM33_NTZ/non_secure 
 )
 
+link_directories(
+    ${ARM_CORTEXM_BUILTINS_DIR}
+    ${ARM_CORTEXM_MULTI_DIR}
+)
+
+if(IMC_ENABLE_EXTENSION)
+    include(imc_extension.cmake)
+    add_compile_definitions(imcUSE_IMC_EXTENSION=1)
+else()
+    add_compile_definitions(imcUSE_IMC_EXTENSION=0)
+    set(IMC_APP_FILES
+        Core/Src/benchmarks/conv2d/conv2d.c
+    )
+endif()
+
 # compile flags
 
 add_compile_definitions(USE_HAL_DRIVER STM32L552xx)
@@ -101,13 +124,12 @@ set(FPU "-mfpu=fpv5-sp-d16")
 set(FLOAT-ABI "-mfloat-abi=hard")
 set(MCU "${CPU} -mthumb ${FPU} ${FLOAT-ABI}")
 set(OPT "-O1")
-#set(C_FLAGS_NO_ASM "-g -gdwarf-2")
 set(C_FLAGS_NO_ASM )
-set(C_FLAGS_EXTRA "-Wall -Wno-char-subscripts -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -nostdlib -fdata-sections -ffunction-sections")
+set(C_FLAGS_EXTRA "-Wall -Wno-char-subscripts -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-format -nostdlib -fdata-sections -ffunction-sections")
 
 set(COMPILER_SPECIFIC_CFLAGS )
 if (CMAKE_C_COMPILER MATCHES "clang")
-    set(TARGET-TRIPPLE "--target=arm-none-eabi --sysroot=${CMAKE_SYSROOT}")
+    set(TARGET-TRIPPLE "--target=armv8m-none-eabi --sysroot=${CMAKE_SYSROOT}")
     set(COMPILER_SPECIFIC_CFLAGS "${TARGET-TRIPPLE}")
 endif()
 
@@ -124,18 +146,45 @@ set(ARM_CORTEXM_BUILTINS "-L${ARM_CORTEXM_BUILTINS_DIR}")
 set(LD_ADDITIONAL_FILES "${ARM_CORTEXM_BUILTINS_DIR}/crti.o ${ARM_CORTEXM_BUILTINS_DIR}/crtn.o")
 
 set(LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/STM32L552ZETX_FLASH.ld")
+set(CMAKE_EXE_LINKER_FLAGS "${LD_ADDITIONAL_FILES} -T ${LINKER_SCRIPT}")
 
-set(LIBDIR "-L${ARM_CORTEXM_MULTI_DIR} ${ARM_CORTEXM_BUILTINS}")
-set(VERBOSE_LINKER_OUTPUT "") #-v for verbose output
-#set(LDFLAGS "${VERBOSE_LINKER_OUTPUT} -lc -lm -lnosys -lgcc -u _printf_float")
-set(LDFLAGS "${VERBOSE_LINKER_OUTPUT} -lc -lm -lnosys -lgcc")
-
-set(COMPILER_SPECIFIC_LDFLAGS )
+project(imc_freeRTOS C ASM)
+add_executable(imc_freeRTOS ${SRC_FILES})
 
-set(CMAKE_EXE_LINKER_FLAGS "${LD_ADDITIONAL_FILES} ${LIBDIR} ${LDFLAGS} ${COMPILER_SPECIFIC_LDFLAGS} -T ${LINKER_SCRIPT}")
+if(IMC_INSERT_COMPILER_CHECKPOINTS)
+    if(NOT CMAKE_C_COMPILER MATCHES "clang")
+        message(FATAL_ERROR "compiler must be clang 17 to enable compiler checkpoint insertion")
+    endif()
+    add_compile_definitions(imcUSE_IMC_KERNEL=1)
+    get_target_property(SRC_INCLUDES imc_freeRTOS INCLUDE_DIRECTORIES)
+    foreach(dir ${SRC_INCLUDES})
+        list(APPEND INCLUDE_DIRS "-I${dir}")
+    endforeach()
+    string(REPLACE " " ";" C_FLAGS ${CMAKE_C_FLAGS})
+
+    set(BASIC_OPT_PASSES "loop-simplify,loop-rotate,mem2reg,instcombine,instsimplify,dce,simplifycfg")
+    set(IMC_OPT_PASSES "imc-insert-checkpoints")
+    set(IMC_FLAGS ${IMC_BASE})
+    set(TARGET_TRIPPLE "--target=armv7em-none-eabi --sysroot=${CMAKE_SYSROOT}")
+
+    foreach(APP_SRC ${IMC_APP_FILES})
+        add_custom_command(
+            OUTPUT ${PROJECT_BINARY_DIR}/${APP_SRC}.s
+            DEPENDS ${APP_SRC}
+            # COMMAND ${CLANG_BIN} --target=armv8m-none-eabi --sysroot=${CMAKE_SYSROOT} -g ${C_FLAGS} -O0 -Xclang -disable-O0-optnone ${INCLUDE_DIRS} -D USE_HAL_DRIVER -D STM32L552xx -c -emit-llvm ${PROJECT_SOURCE_DIR}/${APP_SRC} -o ${PROJECT_BINARY_DIR}/${APP_SRC}.bc
+            COMMAND ${CMAKE_C_COMPILER} -g ${C_FLAGS} -O0 -Xclang -disable-O0-optnone ${INCLUDE_DIRS} -D USE_HAL_DRIVER -D STM32L552xx -c -emit-llvm ${PROJECT_SOURCE_DIR}/${APP_SRC} -o ${PROJECT_BINARY_DIR}/${APP_SRC}.bc
+            COMMAND ${OPT_BIN} -o ${PROJECT_BINARY_DIR}/${APP_SRC}_imc.bc -load-pass-plugin=${LLVM_OPT_PLUGIN} -passes=${BASIC_OPT_PASSES},${IMC_OPT_PASSES} ${PROJECT_BINARY_DIR}/${APP_SRC}.bc
+            COMMAND ${OPT_BIN} ${OPT} -o ${PROJECT_BINARY_DIR}/${APP_SRC}.opt.bc ${PROJECT_BINARY_DIR}/${APP_SRC}_imc.bc
+            COMMAND ${LLC_BIN} ${IMC_FLAGS} ${CPU} ${OPT} -o ${PROJECT_BINARY_DIR}/${APP_SRC}.s ${PROJECT_BINARY_DIR}/${APP_SRC}.opt.bc
+        )
+        list(APPEND APP_OPTS ${PROJECT_BINARY_DIR}/${APP_SRC}.s)
+    endforeach()
+    add_library(imc_apps "${APP_OPTS}")
+else()
+    add_library(imc_apps "${IMC_APP_FILES}")
+endif()
 
-project(imc_freeRTOS C ASM)
+target_link_libraries(imc_freeRTOS PRIVATE imc_apps c m nosys gcc)
 
-add_executable(imc_freeRTOS ${SRC_FILES})
 target_compile_options(imc_freeRTOS PRIVATE "-g")
 set_target_properties(imc_freeRTOS PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})

+ 12 - 0
Core/Inc/ImC/imc_extension.h

@@ -0,0 +1,12 @@
+#ifndef INC_IMC_IMC_EXTENSION_H_
+#define INC_IMC_IMC_EXTENSION_H_
+
+#ifndef imcBENCH_NAME
+    #define imcBENCH_NAME vConv2d
+#endif
+
+#ifndef imcBENCH_INFINITE_LOOP
+    #define imcBENCH_INFINITE_LOOP 0
+#endif
+
+#endif

+ 18 - 4
Core/Inc/ImC/imc_kernel.h

@@ -1,12 +1,18 @@
 #ifndef INC_IMC_IMC_KERNEL_H_
 #define INC_IMC_IMC_KERNEL_H_
 
-#define imcUSE_IMC_KERNEL 1
+#ifndef imcUSE_IMC_KERNEL
+    #define imcUSE_IMC_KERNEL 1
+#endif
+
+#ifndef imcCHECKPOINT_PASS_COUNT
+    #define imcCHECKPOINT_PASS_COUNT 100
+#endif
 
 #define imcSTM32_CUBE_IDE 0
 
-#define imcMAX_NUM_TASKS 5
-#define imcSTACK_SIZE (1024)
+#define imcMAX_NUM_TASKS 2
+#define imcSTACK_SIZE (4096)
 
 #define IMC_GLOBAL __attribute__((section(".imc_global")))
 
@@ -17,10 +23,18 @@
         __asm("  svc #6");      \
     }
 
+
 #include "cmsis_os.h"
 
 void imcInit();
-
 osThreadId_t imcOsThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
+int needCheckpointExecution();
+
+extern int checkpointCounter;
+extern const int checkpoint_pass_count;
+
+#ifndef imcUSE_IMC_EXTENSION
+    #define imcUSE_IMC_EXTENSION 0
+#endif
 
 #endif

+ 18 - 0
Core/Inc/benchmarks/benchmark_driver.h

@@ -0,0 +1,18 @@
+#ifndef __BENCHMARK_DRIVER_H
+#define __BENCHMARK_DRIVER_H
+
+// void vStringSearch();
+// void vBasicMath();
+// void vCrc();
+// void vFFT();
+// void vSha();
+// void vEnergyLevelTest();
+// void vTest_nvm();
+// void vCustom();
+// void vMemAccessPatternTest();
+// void vMatMul();
+void vConv2d();
+
+void vBenchmarkDriver(void *_benchmark);
+
+#endif //__BENCHMARK_DRIVER_H

+ 13 - 0
Core/Src/ImC/imc_kernel.c

@@ -1,7 +1,20 @@
 #include "ImC/imc_kernel.h"
 #include "stm32l5xx.h"
 
+int checkpointCounter = 0;
+const int checkpoint_pass_count = imcCHECKPOINT_PASS_COUNT;
+
 void imcInit()
 {
     FPU->FPCCR &= ~(FPU_FPCCR_LSPEN_Msk); // turn off lazy stacking
+}
+
+int needCheckpointExecution() {
+    if (checkpointCounter == checkpoint_pass_count) {
+        checkpointCounter = 0;
+        return 1;
+    } else {
+        checkpointCounter++;
+        return 0;
+    }
 }

+ 29 - 0
Core/Src/benchmarks/benchmark_driver.c

@@ -0,0 +1,29 @@
+#include "cmsis_os.h"
+#include "ImC/imc_kernel.h"
+#include "ImC/imc_extension.h"
+
+#include <stdio.h>
+
+void vBenchmarkDriver(void *_benchmark)
+{
+    void (*benchmark)(void) = _benchmark;
+    #if (imcBENCH_INFINITE_LOOP)
+    while(1) {
+    #endif
+    portDISABLE_INTERRUPTS();
+    printf("Start benchmark\r\n");
+    portENABLE_INTERRUPTS();
+
+    benchmark();
+
+    portDISABLE_INTERRUPTS();
+    printf("End benchmark\r\n");
+    portENABLE_INTERRUPTS();
+    #if (imcBENCH_INFINITE_LOOP)
+    }
+    #endif
+
+// #if (imcUSE_IMC_KERNEL == 1)
+//     vImcInvalidateRecovery();
+// #endif
+}

+ 62 - 0
Core/Src/benchmarks/conv2d/conv2d.c

@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include "ImC/imc_kernel.h"
+
+#define INPUT_SIZE 20
+#define KERNEL_SIZE 6
+#define OUTPUT_SIZE (INPUT_SIZE - KERNEL_SIZE + 1)
+
+static int input[INPUT_SIZE][INPUT_SIZE] = {
+    [0 ... INPUT_SIZE - 1] = {[0 ... INPUT_SIZE - 1] = 2}};
+
+static int kernel[KERNEL_SIZE][KERNEL_SIZE] = {
+    [0 ... KERNEL_SIZE - 1] = {[0 ... KERNEL_SIZE - 1] = 2}};
+
+void vConv2d()
+{
+    int IMC_REPEAT = 10;
+
+    int output[OUTPUT_SIZE * OUTPUT_SIZE];
+
+#pragma clang loop unroll(disable)
+    for (int imc_repeat = 0; imc_repeat < IMC_REPEAT; imc_repeat++)
+    {
+
+// #pragma clang loop unroll(disable)
+// for(int i=0; i<OUTPUT_SIZE; i++) {
+//     #pragma clang loop unroll(disable)
+//     for(int j=0; j<OUTPUT_SIZE; j++) {
+#pragma clang loop unroll(disable)
+        for (int _i = 0; _i < OUTPUT_SIZE * OUTPUT_SIZE; _i++)
+        {
+            int i = _i / OUTPUT_SIZE;
+            int j = _i % OUTPUT_SIZE;
+            int sum = 0;
+            // #pragma clang loop unroll(disable)
+            for (int ii = 0; ii < KERNEL_SIZE; ii++)
+            {
+                // #pragma clang loop unroll(disable)
+                for (int jj = 0; jj < KERNEL_SIZE; jj++)
+                {
+                    int input_i = i + ii;
+                    int input_j = j + jj;
+                    sum += input[input_i][input_j] * kernel[ii][jj];
+                }
+            }
+            // output[i * OUTPUT_SIZE + j] = sum;
+            output[_i] = sum;
+        }
+        // }
+    }
+
+#pragma clang loop unroll(disable)
+    for (int _i = 0; _i < OUTPUT_SIZE * OUTPUT_SIZE; _i++)
+    {
+        printf("%d ", output[_i]);
+        if (_i % OUTPUT_SIZE == OUTPUT_SIZE - 1)
+        {
+            printf("\r\n");
+        }
+    }
+
+    printf("\r\n");
+}

+ 10 - 86
Core/Src/main.c

@@ -25,6 +25,10 @@
 /* USER CODE BEGIN Includes */
 #include "ImC/imc_api.h"
 #include "ImC/imc_kernel.h"
+#include "benchmarks/benchmark_driver.h"
+#if (imcUSE_IMC_EXTENSION)
+#include "ImC/imc_extension.h"
+#endif
 /* USER CODE END Includes */
 
 /* Private typedef -----------------------------------------------------------*/
@@ -105,19 +109,6 @@ SRAM_HandleTypeDef hsram2;
 SRAM_HandleTypeDef hsram3;
 SRAM_HandleTypeDef hsram4;
 
-/* Definitions for taskEPS */
-// osThreadId_t taskEPSHandle;
-// uint32_t taskEPSBuffer[ imcSTACK_SIZE ];
-// osStaticThreadDef_t taskEPSControlBlock;
-// const osThreadAttr_t taskEPS_attributes = {
-//   .name = "taskEPS",
-//   .stack_mem = &taskEPSBuffer[0],
-//   .stack_size = sizeof(taskEPSBuffer),
-//   .cb_mem = &taskEPSControlBlock,
-//   .cb_size = sizeof(taskEPSControlBlock),
-//   .priority = (osPriority_t) osPriorityRealtime,
-// };
-
 /* Definitions for taskSnap */
 osThreadId_t taskSnapHandle;
 uint32_t taskSnapBuffer[ imcSTACK_SIZE ];
@@ -131,44 +122,6 @@ const osThreadAttr_t taskSnap_attributes = {
   .priority = (osPriority_t) osPriorityRealtime,
 };
 
-/* Definitions for taskTest1 */
-osThreadId_t taskTest1Handle;
-uint32_t taskTest1Buffer[ imcSTACK_SIZE ];
-osStaticThreadDef_t taskTest1ControlBlock;
-const osThreadAttr_t taskTest1_attributes = {
-  .name = "taskTest1",
-  .stack_mem = &taskTest1Buffer[0],
-  .stack_size = sizeof(taskTest1Buffer),
-  .cb_mem = &taskTest1ControlBlock,
-  .cb_size = sizeof(taskTest1ControlBlock),
-  .priority = (osPriority_t) osPriorityRealtime,
-};
-
-/* Definitions for taskTest2 */
-osThreadId_t taskTest2Handle;
-uint32_t taskTest2Buffer[ imcSTACK_SIZE ];
-osStaticThreadDef_t taskTest2ControlBlock;
-const osThreadAttr_t taskTest2_attributes = {
-  .name = "taskTest2",
-  .stack_mem = &taskTest2Buffer[0],
-  .stack_size = sizeof(taskTest2Buffer),
-  .cb_mem = &taskTest2ControlBlock,
-  .cb_size = sizeof(taskTest2ControlBlock),
-  .priority = (osPriority_t) osPriorityRealtime,
-};
-
-/* Definitions for taskAI */
-// osThreadId_t taskAIHandle;
-// uint32_t taskAIBuffer[ 37968 ];
-// osStaticThreadDef_t taskAIControlBlock;
-// const osThreadAttr_t taskAI_attributes = {
-//   .name = "taskAI",
-//   .stack_mem = &taskAIBuffer[0],
-//   .stack_size = sizeof(taskAIBuffer),
-//   .cb_mem = &taskAIControlBlock,
-//   .cb_size = sizeof(taskAIControlBlock),
-//   .priority = (osPriority_t) osPriorityNormal,
-// };
 /* USER CODE BEGIN PV */
 
 /* USER CODE END PV */
@@ -305,46 +258,17 @@ int main(void)
   /* Init scheduler */
   osKernelInitialize();
 
-  /* USER CODE BEGIN RTOS_MUTEX */
-  /* add mutexes, ... */
-  /* USER CODE END RTOS_MUTEX */
-
-  /* USER CODE BEGIN RTOS_SEMAPHORES */
-  /* add semaphores, ... */
-  /* USER CODE END RTOS_SEMAPHORES */
-
-  /* USER CODE BEGIN RTOS_TIMERS */
-  /* start timers, add new ones, ... */
-  /* USER CODE END RTOS_TIMERS */
-
-  /* USER CODE BEGIN RTOS_QUEUES */
-  /* add queues, ... */
-  /* USER CODE END RTOS_QUEUES */
-
-  /* Create the thread(s) */
-  /* creation of taskEPS */
-  // taskEPSHandle = osThreadNew(taskEPSRunner, NULL, &taskEPS_attributes);
-
   /* creation of taskSnap */
   #if (imcUSE_IMC_KERNEL == 1)
-  taskSnapHandle = imcOsThreadNew(taskSnapRunner, NULL, &taskSnap_attributes);
-  taskTest1Handle = imcOsThreadNew(taskImcTest, NULL, &taskTest1_attributes);
-  taskTest2Handle = imcOsThreadNew(taskImcTest_2, NULL, &taskTest2_attributes);
+    #if (imcUSE_IMC_EXTENSION)
+    taskSnapHandle = imcOsThreadNew(vBenchmarkDriver, imcBENCH_NAME, &taskSnap_attributes);
+    #else
+    taskSnapHandle = imcOsThreadNew(vConv2d, NULL, &taskSnap_attributes);
+    #endif
   #else
-  // taskSnapHandle = osThreadNew(taskSnapRunner, NULL, &taskSnap_attributes);
+  taskSnapHandle = osThreadNew(vBenchmarkDriver, imcBENCH_NAME, &taskSnap_attributes);
   #endif
 
-  /* creation of taskAI */
-//  taskAIHandle = osThreadNew(taskAIRunner, NULL, &taskAI_attributes);
-
-  /* USER CODE BEGIN RTOS_THREADS */
-  /* add threads, ... */
-  /* USER CODE END RTOS_THREADS */
-
-  /* USER CODE BEGIN RTOS_EVENTS */
-  /* add events, ... */
-  /* USER CODE END RTOS_EVENTS */
-
   /* Start scheduler */
   osKernelStart();
 

+ 7 - 7
Middlewares/Third_Party/FreeRTOS/Source/include/task.h

@@ -2533,18 +2533,18 @@ TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
  */
 void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
 
-#if (imcUSE_IMC_KERNEL == 1)
+// #if (imcUSE_IMC_KERNEL == 1)
 
-#include "ImC/imc_kernel.h"
-// #include "cmsis_os.h"
+// // #include "ImC/imc_kernel.h"
+// // #include "cmsis_os.h"
 
-void xTaskCheckpointCurrentTask(uint32_t lr_register) PRIVILEGED_FUNCTION;
+// void xTaskCheckpointCurrentTask(uint32_t lr_register) PRIVILEGED_FUNCTION;
 
-void vRecoverTask(TaskHandle_t tcb);
+// void vRecoverTask(TaskHandle_t tcb);
 
-// osThreadId_t imcOsThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
+// // osThreadId_t imcOsThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
 
-#endif // imcUSE_IMC_KERNEL
+// #endif // imcUSE_IMC_KERNEL
 
 #ifdef __cplusplus
 }

+ 2 - 1
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM33_NTZ/non_secure/port.c

@@ -782,6 +782,7 @@ uint8_t ucSVCNumber;
 	 * R12, LR, PC, xPSR. */
 	ulPC = pulCallerStackAddress[ 6 ];
 	ucSVCNumber = ( ( uint8_t *) ulPC )[ -2 ];
+	__asm(" mov r0, %0": : "r"(pulCallerStackAddress));
 
 	switch( ucSVCNumber )
 	{
@@ -924,7 +925,7 @@ uint8_t ucSVCNumber;
 					"	mov r0, #0							\n"
 					"	msr basepri, r0						\n"
 					"	ldmia sp!, {lr}				\n"
-					"	add sp, #4	\n"
+					// "	add sp, #4	\n"
 					"	bx lr 					\n"
 					"pxCurrentTCBConst3: .word pxCurrentTCB				\n" );
 			}

+ 5 - 2
Middlewares/Third_Party/FreeRTOS/Source/tasks.c

@@ -5323,6 +5323,7 @@ uint8_t ucLatestBufferIndex[imcMAX_NUM_TASKS] __attribute__((section(".kernel_nv
 
 void xTaskCheckpointCurrentTask(uint32_t lr_register)
 {
+	// portDISABLE_INTERRUPTS();
 	TCB_t *tcb = pxCurrentTCB;
 	UBaseType_t taskNumber = pxCurrentTCB->uxTCBNumber;
 	uint8_t currentBufferIndex = ucLatestBufferIndex[taskNumber];
@@ -5351,6 +5352,8 @@ void xTaskCheckpointCurrentTask(uint32_t lr_register)
 	ucTaskSnapshotValid[taskNumber] = pdTRUE;
 
 	__DMB();
+	// portENABLE_INTERRUPTS();
+	
 }
 
 void vRecoverTask(TCB_t *tcb)
@@ -5358,8 +5361,8 @@ void vRecoverTask(TCB_t *tcb)
 	UBaseType_t taskNumber = pxCurrentTCB->uxTCBNumber;
 	uint8_t bufferIndex = ucLatestBufferIndex[taskNumber];
 
-	// Should not recover TCB list items; save it and overwrite afterwards
-	// All members of ListItem_t is a pointer, so use a shallow copy
+	// Should not recover TCB list items; save them and overwrite afterwards
+	// All members of ListItem_t are value types; use a shallow copy
 	ListItem_t state = tcb->xStateListItem;
 	ListItem_t event = tcb->xEventListItem;
 

+ 7 - 6
STM32L552ZETX_FLASH.ld

@@ -35,12 +35,6 @@
 /* Entry Point */
 ENTRY(Reset_Handler)
 
-/* Highest address of the user mode stack */
-_estack = ORIGIN(RAM) + LENGTH(RAM);	/* end of "RAM" Ram type memory */
-
-_Min_Heap_Size = 0x200;	/* required amount of heap  */
-_Min_Stack_Size = 0x400;	/* required amount of stack */
-
 /* Memories definition */
 MEMORY
 {
@@ -49,6 +43,13 @@ MEMORY
   NVM (xrw)        : ORIGIN = 0x68000000, LENGTH = 1024K
 }
 
+
+/* Highest address of the user mode stack */
+_estack = ORIGIN(RAM) + LENGTH(RAM);	/* end of "RAM" Ram type memory */
+
+_Min_Heap_Size = 0x200;	/* required amount of heap  */
+_Min_Stack_Size = 0x400;	/* required amount of stack */
+
 /* Sections */
 SECTIONS
 {

+ 6 - 0
imc/utils/nvm_reset.sh

@@ -0,0 +1,6 @@
+PROJECT_ROOT_DIR="/home/ybkim/workspace/imc/imc_freertos_app_m33"
+NVM_RESET_DIR="${PROJECT_ROOT_DIR}/imc/utils/nvm_reset.elf"
+OPENOCD_SCRIPT_DIR="${PROJECT_ROOT_DIR}/imc_freertos_app_m33.cfg"
+/home/ybkim/opt/xpack-openocd-0.11.0-4/bin/openocd -f ${OPENOCD_SCRIPT_DIR} -c "program ${NVM_RESET_DIR}" -c reset -c resume -c exit
+sleep 3
+return 0

+ 3 - 0
imc/utils/program_binary.sh

@@ -2,6 +2,9 @@ PROJECT_ROOT_DIR="/home/ybkim/workspace/imc/imc_freertos_app_m33"
 BIN_DIR="${PROJECT_ROOT_DIR}/build/imc_freeRTOS"
 NVM_RESET_DIR="${PROJECT_ROOT_DIR}/imc/utils/nvm_reset.elf"
 OPENOCD_SCRIPT_DIR="${PROJECT_ROOT_DIR}/imc_freertos_app_m33.cfg"
+cd $PROJECT_ROOT_DIR/build
+ninja
+cd $PROJECT_ROOT_DIR
 /home/ybkim/opt/xpack-openocd-0.11.0-4/bin/openocd -f ${OPENOCD_SCRIPT_DIR} -c "program ${NVM_RESET_DIR}" -c reset -c resume -c exit
 sleep 5
 /home/ybkim/opt/xpack-openocd-0.11.0-4/bin/openocd -f ${OPENOCD_SCRIPT_DIR} -c "program ${BIN_DIR}" -c reset -c resume -c exit

+ 19 - 0
imc_extension.cmake

@@ -0,0 +1,19 @@
+set(IMC_BENCH_NAME "vConv2d" CACHE STRING "")
+set(AVAILABLE_BENCHES "vBasicMath" "vStringSearch" "vFFT" "vSha" "vCrc" "vTest_nvm" "vCustom" "vMemAccessPatternTest" "vMatMul" "vConv2d")
+if(NOT IMC_BENCH_NAME IN_LIST AVAILABLE_BENCHES)
+    message( FATAL_ERROR "incorrect benchmark name: ${IMC_BENCH_NAME}")
+endif()
+
+if(IMC_BENCH_NAME MATCHES "vConv2d")
+    set(BENCHMARK_SRC_FILES
+    )
+    set(IMC_APP_FILES
+        Core/Src/benchmarks/conv2d/conv2d.c
+    )
+    set(IMC_LINK_OBJS
+    )
+endif()
+
+foreach(BENCH_SRC ${BENCHMARK_SRC_FILES})
+    list(APPEND SRC_FILES ${BENCH_SRC})
+endforeach()