Jefenlie YCONGPaul Rodolf P. Castor
Published © MIT

STM32 Assembly Code Execution and Debugging on the RT-Spark

Exploring ARM Cortex-M4 assembly execution and debugging using the STM32F407 RT-Spark board.

BeginnerFull instructions provided1 hour38
STM32 Assembly Code Execution and Debugging on the RT-Spark

Things used in this project

Hardware components

RT-Spark (Spark-1) RT-Thread Development Board
×1

Software apps and online services

Github: RT-Thread-Studio / SDK-BSP-STM32f407-Spark
RT-Thread STM32CubeIDE (V1.19.0)

Story

Read more

Schematics

SEQUENCE DIAGRAM

Code

STM32 Assembly Code Execution and Debugging on the RT-Spark

C#
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;

/* USER CODE BEGIN PV */
/* Flags and instrumentation variables for foreground/background communication */
volatile uint8_t task_adc_ready = 0;
volatile uint8_t task_display_ready = 0;
volatile uint32_t tick_count = 0;

/* Latency measurement variables using DWT Cyccnt */
volatile uint32_t start = 0;
volatile uint32_t tick = 0;
volatile uint32_t maxlatency = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM3_Init(void);

/* USER CODE BEGIN PFP */
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
  * @brief  Period elapsed callback in non-blocking mode (Hardware Timer ISR)
  * @param  htim TIM handle
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
    // Background Task 1: TIM2 - High priority, 1 Hz (ADC Trigger)
    if(htim->Instance == TIM2) {
        // Record precise cycle count at interrupt trigger
        start = DWT->CYCCNT; 
        
        // Signal background task runtime via Debug Pin
        HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_SET);
        
        HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
        task_adc_ready = 1;
        tick_count++;
        
        HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_RESET);
    }

    // Background Task 2: TIM3 - Lower priority, 2 Hz (Display Trigger)
    if(htim->Instance == TIM3) {
        HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
        task_display_ready = 1;
    }
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();

  /* USER CODE BEGIN 2 */
  /* Start Hardware Timers in Interrupt Mode */
  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_Base_Start_IT(&htim3);

  /* Enable Data Watchpoint and Trace (DWT) Cycle Counter for timing profiling */
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  DWT->CYCCNT = 0;
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    /* Foreground Cyclic Executive Loop */

    // Task A: Process ADC data (Triggered by TIM2 background flag)
    if(task_adc_ready) {
        // Calculate latency time difference immediately upon entry
        tick = DWT->CYCCNT - start;
        if(tick > maxlatency) {
            maxlatency = tick;
        }

        // Assert Debug pin to mark Task processing window
        HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_SET);
        task_adc_ready = 0;
        
        // Simulate real workload processing execution time
        HAL_Delay(50); 
        HAL_GPIO_WritePin(DEBUG_PIN_GPIO_Port, DEBUG_PIN_Pin, GPIO_PIN_RESET);
    }

    // Task B: Update display (Triggered by TIM3 background flag)
    if(task_display_ready) {
        task_display_ready = 0;
        
        // Simulate real display update execution workload
        HAL_Delay(20); 
    }

    // Task C: Background periodic housekeeping monitor
    if(tick_count >= 10) {
        tick_count = 0;
        // Perform 10-second check operations here
    }
  }
  /* USER CODE END 3 */
}

/* USER CODE BEGIN 4 */
/**
  * @brief  EXTI line detection callback (Event-Triggered Button Press)
  * @param  GPIO_Pin Specifies the pins connected to the EXTI line.
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    // Responding to PA0 User Button press
    if(GPIO_Pin == GPIO_PIN_0) {
        HAL_GPIO_TogglePin(LED_RED_GPIO_Port, LED_RED_Pin);
        HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
    }
}
/* USER CODE END 4 */

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  // System clock configuration is automatically generated here by CubeMX
}

static void MX_TIM2_Init(void)
{
  // TIM2 configuration setup automatically generated here by CubeMX
}

static void MX_TIM3_Init(void)
{
  // TIM3 configuration setup automatically generated here by CubeMX
}

static void MX_GPIO_Init(void)
{
  // GPIO Pin configuration (PF11, PF12, PE0, PA0) automatically generated here by CubeMX
}

STM32-Assembly-Code-Execution-and-Debugging-on-the-RT-Spark

Credits

Jefenlie YCONG
4 projects • 0 followers
Paul Rodolf P. Castor
74 projects • 11 followers

Comments