임베디드/STM32

STM32F103RCT6 BOOTLOADER

큰꼬꼬 2023. 9. 4. 23:10

STM32F103RCT6 부트로더 펌웨어를 작성하고 
부트로더 -> 어플리케이션으로 점프하는 과정을 정리해봄
별거 아닌것 같지만 잘 모르면 몇시간을 잡아먹는 부분이기에
내가 알아본걸 조금이나마 도움이 되게 끄적여봄

 

0x08000000 부트로더

0x08006000 어플리케이션

1.부트로더의 링커를 수정해준다.

 

2. 부트로더의 링커파일을 수정해준다. (stm32f103xe_flash.icf)

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__   = 0x08005FFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20003FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__   = 0x800;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

define exported symbol app_vector = 0x08006000;
define exported symbol app_vector1 = 0x08016000;

initialize by copy { readwrite };
do not initialize  { section .noinit };

"INTVEC":
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

"ROM":
place in ROM_region   { readonly };

"RAM":
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

"APPLICATION":
place at address mem: app_vector { readonly section .APP };

"APPLICATION1":
place at address mem: app_vector1 { readonly section .APP1 };

define symbol __region_EEPROM_start__ = 0x08080000;
define symbol __region_EEPROM_end__   = 0x08080FFF;
define region EEPROM_region = mem:[from __region_EEPROM_start__   to __region_EEPROM_end__];

place in EEPROM_region  { section .eeprom };

3. 부트로더 main.c 파일 수정

/* USER CODE BEGIN Includes */

#include <intrinsics.h>			// 추가해줌

/* USER CODE END Includes */


//////////////////////////////////////////////////////////////////////////////////

/* USER CODE BEGIN PV */

typedef void (application_t) (void);

typedef struct vector
{
    uint32_t        stack_addr;     // intvec[0] is initial Stack Pointer
    application_t   *func_p;        // intvec[1] is initial Program Counter
} vector_t;

extern const uint32_t app_vector; 	// 어플리케이션 영역1                               
extern const uint32_t app_vector1;  // 어플리케이션 영역2
                                  
USBD_HandleTypeDef USBD_Device;		// 나중에 DFU할때 사용할것임


/* USER CODE END PV */


///////////////////////////////////////////////////////////////////////////////////

int main(void)
{
  /* USER CODE BEGIN 1 */
	typedef  void (*pFunction)(void);
	pFunction JumpToApplication;
  	uint32_t JumpAddress;

  /* USER CODE END 1 */
  
  
  .
  ....
  .....

  /* USER CODE BEGIN 2 */
  if (HAL_GPIO_ReadPin(Firmup_Pin_GPIO_Port, Firmup_Pin_Pin) != GPIO_PIN_RESET)
  {
        const vector_t *vector_p            = (vector_t*) &app_vector;
        volatile uint32_t stack_arr[100]    = {0}; // Allocate some stack
                                           // just to show that
                                           // the SP should be reset
                                           // before the jump - or the
                                           // stack won't be configured
                                           // correctly.
        __enable_interrupt();

        //		printf("Hello from bootloader!\n");

        __disable_interrupt();              // 1. Disable interrupts
        __set_SP(vector_p->stack_addr);     // 2. Configure stack pointer
        SCB->VTOR = (uint32_t) &app_vector; // 3. Configure VTOR
        vector_p->func_p();                 // 4. Jump to application
    }

링커파일에서 define 한 app_vector를 불러옴

펌웨어 핀이 reset이면
USBD_DFU_APP_DEFAULT_ADD 주소로 점프 뜀

usbd_conf.h

USBD_DFU_APP_DEFAULT_ADD 가 아닌 0x08006000으로 해도됨.

나는 나중에 usb dfu를 할것이기에 저렇게 해놓음.

4. 어플리케이션 main.c 수정
부트로더와 마찮가지로 

#include <intrinsics.h>

를 include 해준다. 이는 

_enable_interrupt();
while (1)
{
}

부트로더에서 disable 한 interrupt를 enable 하는 과정임

 

5.어플리케이션의 링커파일 수정

/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08006000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08006000;
define symbol __ICFEDIT_region_ROM_end__   = 0x0803FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20003FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__   = 0x800;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

"INTVEC":
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

"ROM":
place in ROM_region   { readonly };

"RAM":
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

define symbol __region_EEPROM_start__ = 0x08080000;
define symbol __region_EEPROM_end__   = 0x08080FFF;
define region EEPROM_region = mem:[from __region_EEPROM_start__   to __region_EEPROM_end__];

place in EEPROM_region  { section .eeprom };

 

 

이렇게 하면  bootloader -> application으로 점프를 뛰며 app에서 원하는 코딩을 하면 된다.

 

그럼 이만

'임베디드 > STM32' 카테고리의 다른 글

DFU 이용할때 추가 해야 하는것  (0) 2023.09.04
bootloader 추가..  (0) 2023.09.04