Engineering Agit

[Embedded engineering study 02] - Weak function 본문

Personal Study/Embedded engineering

[Embedded engineering study 02] - Weak function

Sean_Kim95 2020. 10. 28. 20:34

◈ 여는 글

 Interrupt에 관한 프로그래밍을 하다 startup code에 다음과 같이 적혀있는 함수들을 본 적이 있을 것이다.

.
.
.
//Weak Function Deffinitions, can be written / declared in other files
extern void SVC_Handler(void) __attribute__((weak));           // SVCall Handler
extern void DebugMon_Handler(void) __attribute__((weak)); // Debug Monitor Handler
extern void PendSV_Handler(void) __attribute__((weak));        // PendSV Handler
extern void SysTick_Handler(void) __attribute__((weak));      // SysTick Handler
extern void GPIOPortA_Handler(void) __attribute__((weak));        // GPIO Port A
extern void GPIOPortB_Handler(void) __attribute__((weak));        // GPIO Port B
.
.
.

언뜻 보았을 때 일반적인 function definition으로 보일 수도 있지만, 뒷 부분에 '__attribute__((weak))'라는 표기가 추가되어 있는 것을 볼 수 있다. 이러한 function을 weak처리되었다라고 말하는데 이런 방식은 왜 사용되는 것일까에 대하여 알아보고자 한다.


1. Weak symbol

 ① Definition

 Weak symbol은 ELF object file들을 linking하는 과정에서 특별히 표기되는 symbol이다. 아무런 표기가 없는 object file내의 symbol은 'Strong'이다(default setting). 'Strong'과 'Weak'가 내포한 기본적인 의미와 같이 linking 과정에서 동일한 이름을 갖는 두 개의 symbol들이 있고 하나는 strong, 다른 하나는 weak로 표기되었다면 strong으로 표기되어 있는 symbol이 weak로 표기되어있는 symbol을 'override'한다. 만약에 두 개의 symbol이 strong으로 표기되어 있다면 어떻게 될까? 이는 linking 과정에서 error를 발생하게 된다. 

 'Binary executable'을 linking할 때는 weak하게 선언된 symbol은 'definition'이 필요하지 않다. 이에 반해, strong하게 선언된 symbol은 'definition'이 없으면 'undefined symbol link error'를 발생시킨다.

※ Weak symbol은 C/C++의 표준에는 언급이 되지 않는다. 이는 code가 portable하지 않음을 의미한다. 심지어 두 platform의 weak 마킹법이 동일하거나 비슷하더라도 'Semantics'가 상이할 수 있다.

https://en.wikipedia.org/wiki/Semantics_(computer_science) 

 

Semantics (computer science) - Wikipedia

The field concerned with the rigorous mathematical study of the meaning of programming languages In programming language theory, semantics is the field concerned with the rigorous mathematical study of the meaning of programming languages. It does so by ev

en.wikipedia.org

 이러한 표기는 어떤 상황에서 사용되는 것일까?

 ② Usage

 CCS를 이용해서 TM4C123GH6PM MCU를 이용하여 interrupt를 발생시키는 과정을 보도록 하자.

//*****************************************************************************
//
// Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************
.
.
.
//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
//Weak Function Deffinitions, can be written / declared in other files
.
.
.
extern void GPIOPortF_Handler(void) __attribute__((weak));        // GPIO Port F
.
.
.
//*****************************************************************************
//
// The vector table.  Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000 or at the start of
// the program if located at a start address other than 0.
//
//*****************************************************************************
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (*const g_pfnVectors[])(void) =
{
    (void (*)(void))((uint32_t)&__STACK_TOP),
    // The initial stack pointer
    .
    .
    .
            GPIOPortF_Handler,// GPIO Port F
    .
    .
    .
};

<Code 1.> tm4c123gh6pm_startup_ccs.c


/*
 * main.c
 * Topic: Interrupt01
 *  Created on: Oct 21, 2020
 *      Author: taehoonkim
 */
 .
 .
 .
 int main(void)
{
.
.
.
   while(1){
   .
   .
   .
   }
   return 0;
}
.
.
.
void GPIOPortF_Handler(void)
{
    GPIO_PORTF_ICR_R = 0x10;      // acknowledge flag4
    Int_Flag = !(Int_Flag);
}

<Code 2.> main.c

 Port F에 관련된 interrupt를 사용하는 경우인데, interrupt가 발생할 때 ISR routine으로 넘어가는데 이때 call되는 함수가 'GPIOPortF_Handler()'이다. 이를 사용하기 위해 startup code에 weak 처리 되어있는 동일한 이름의 함수를 main.c에 strong으로 처리하였다. startup code에는 이 뿐만이 아니라 다른 handler 함수들도 weak 처리되어 있다. 해당 handler가 필요하면 main에서 strong처리하여 사용하면 된다. 이를 통해 weak 처리하는 이유를 알 수 있다. Weak symbol은 결국 상황에 따라 꺼내 쓸 수 있는 function들의 'Default implementation'을 제공할 때 사용된다. 

 또다른 용도로는 'Binary Backward compatibility'의 유지보수이다. 이는 다음 링크를 참고하도록 한다.

https://en.wikipedia.org/wiki/Backward_compatibility

 

Backward compatibility - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Technological ability to interact with older technologies The GameCube's two disc-based successors, the Wii and Wii U, employ backwards compatibility with the ability to play games des

en.wikipedia.org


https://en.wikipedia.org/wiki/Weak_symbol#Use_cases
Comments