본문 바로가기

Project/RIS

[RIS] 1/5 (__attribute, stdint.h, ros::Timer)

728x90
  • 모터 드라이버 MD200T의 Source Code를 분석하며 공부한 내용

 

1) __attribute__

모터 드라이버 (MD200T)의 com.hpp source code중 일부

  • 위 사진에 있는 __attribute__는 Unix/Linux의 GCC Compiler에 존재하는 메커니즘으로, compiler가  program에서 사용될 함수들을 더 주의해서 최적화하고 검사하도록 한다
  • Function 선언시 compiler에게 특성을 주겠다는 것을 의마한다
  • 뒤의 소괄호 안에 속성 인자를 작성하며 속성은 함수속성, 변수속성 그리고 타입속성의 종류로 구분된다

 - 사용 이유

struct struct1{
    char flags;		// 1byte
    short count;	// 2byte
    int msg;		// 4byte
} 
sizeif(struct1);	// 8byte
  • Structure 는 포함 요소들중 크기가 가장 큰 data type을 기준으로 그 크기의 배수만큼의 크기를 가진다
  • 따라서 ST의 각 data type의 크기합은 7byte지만 크기가 가장 큰 int의 2배수인 8byte의 크기를 갖는다

  • 이 때, 위 그림처럼 1byte의 padding(빈 공간)이 생기는 문제가 발생한다

 

struct struct2{
    char flags;		// 1byte
    int	msg;		// 4byte
    short count;	// 2byte
} 
sizeof(struct2);	// 12byte
  • 위처럼 member들의 배치 순서가 바뀌면 struct의 크기는 12byte가 된다
  • CPU가 data type 저장시 효율을 위해 data type 크기의 배수에 해당하는 주소에 위치시키기 때문에 이같은 현상이 발생한다
    • 1byte의 flags를 4byte를 할당하고 거기에 집어넣는다
    • CPU가 memory address 지정시 4byte 단위가 내부적으로 가장 최적화되어있어 빠른 data access가 가능하므로 위와 같은 방식을 사용한다

 

  • 위 같이 padding이 발생하는 것을 방지하고자 __attribute__ (packed) 메커니즘을 사용한다
struct struct{
    char flags;		// 1byte
    int	msg;		// 4byte
    short count;	// 2byte
} __attribute__ ((packed)) struct_att
sizeof(struct_att);	// 6byte
  • 위와 같이 '__attribute__' 를 사용하여 compiler가 struct_att의 실제 크기만큼의 memory address를 할당하게 한다. (Struct의 member들이 memory address를 빈자리 없이 꽉 채우라는(packed) 의미)
  • Padding은 사라지나 속도가 약간 늦어진다

 

  • aligned(alignment) : Function에 대한 최소 정렬을 byte 단위로 나타낸다. 즉, struct의 memory에 몇 byte 단위로 끊어 위치시킬 것인지 나타낸다
  • 따라서 위 코드에서는 구조체에 대한 memory 주소값이 1byte씩 나눠진다

 - 정리

typedef struct {
    int16_t rpm_id1;			// 2bytes	
    int16_t current_id1;		// 2bytes
    MOTOR_STATE_t mtr_state_id1;	// 1bytes 
    int32_t mtr_pos_id1;		// 4bytes

    int16_t rpm_id2;			// 2bytes
    int16_t current_id2;		// 2bytes
    MOTOR_STATE_t mtr_state_id2;	// 1bytes
    int32_t mtr_pos_id2;		// 4bytes
} __attribute__((aligned(1),packed)) PID_PNT_MAIN_DATA_t;

sizeof(PID_PNT_MAIN_DATA_t);		// 18bytes
  • 구조체 PID_PNT_MAIN_DATA_t는 1bytes씩 나눠 총 32bytes 크기의 memory address를 할당받는다
  • MOTOR_STATE_t는 다른 곳에서 정의된 1byte 크기의 union

 

2) <stdint.h>

  • uint8_t는 <stdint.h> header에 정의된 data type으로, 모든 platform에서 동일한 bit 수를 사용하도록 설정하기 위해 사용한다 (C언어에서는 compiler의 종류나 OS의 차이에 따라 data type의 크기가 변경될 수 있다)
  • Memory 관리가 중요한 Embedded 환경에서 자주 사용한다

uint8_t 외에 <stdint.h>에 정의된 자료형들

 

  • <stdint.h>의 source code

sites.uclouvain.be/SystInfo/usr/include/stdint.h.html

 

stdint.h

 

sites.uclouvain.be

 

 

3) ros::Timer

 - main.cpp source code의 일부

  • Timer 함수는 ros::NodeHandle::createTimer()를 통해 생성할 수 있다 (위 코드에선 app_tick_timer)가 Nodehandle 역할)
  • Duration은 timer 호출 간격. 위 코드에선 0.5초의 간격을 둠
  • AppTickTimerCallback은 timer의 callback Function
    • Callback Function : 다른 function의 실행이 끝난 후 실행되는(callback 되는) function으로, 다른 function의 parameter로 사용되는 실행 가능한 function이다

 

ros::Timer app_tick_timer = nh.createTimer(ros::Duration(0.500), AppTickTimerCallback1, true);
ros::Timer app_tick_timer = nh.createTimer(ros::Duration(0.500), AppTickTimerCallback2, false);
  • 위처럼 callback function 뒤에 true, false를 지정할 수 있다
  • true의 경우 one shot timer가 되어 한 번만 호출된다. 따라서 AppTickTimerCallback1 function은 0.5s동안 한 번만 호출된다
  • false일 경우 stop될 때까지 호출된다 (생략가능)

 

 

 


참고 자료 :

https://dobby-the-house-elf.tistory.com/358

 

[C++] 구조체의 크기 (size of struct)

구조체의 크기는 구조체를 구성하는 요소들에 의해 정해 집니다. 하지만 크기를 출력해보면 예상한 값과 다르게 나올때가 있는데, 그 이유와 구조체의 구조에 대해 알아보겠습니다. struct Packet00

dobby-the-house-elf.tistory.com

https://pastime0.tistory.com/entry/attribute-packed-%EA%B5%AC%EC%A1%B0%EC%B2%B4-%EC%A0%95%EB%A0%AC

 

__attribute__ (packed) : 구조체 정렬

__attribute__는 GCC 컴파일러에 있는 메커니즘으로 컴파일러에게 추가적인 에러 체킹 같은 것을 하도록 지시하는 것이다. 형식 : __attribute__(x)괄호 안의 x에는 가능한 몇 가지들이 있는데 특히, packed

pastime0.tistory.com

https://indra17.tistory.com/entry/GNU-C-attribute

 

GNU C, __attribute__

출처: http://blog.daum.net/english_100/5 GNU C의 커다란 특성(초보자가 알기 쉽지 않지만) 중 하나는 속성(__attribute__)체계이다. __attribute__는 함수속성(Function attribute) 변수속성(Variable attribute) 그리고 타입

indra17.tistory.com

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=msyang59&logNo=220885276415 

 

gcc: __attribute__((aligned(n)))

간혹 구조체를 항시 메모리의 짝수 번지부터 시작하게 하거나 16 바이트 단위로 끊어 위치 시킬 필요가 있...

blog.naver.com

https://educoder.tistory.com/entry/cc-int8t-uint8t-int16t-uint16t

 

[c/c++] int8_t, uint8_t, int16_t, uint16_t ?

c언어를 배우면 보통 primitive type 이라고 하여 short, int, long, char, float, double 등의 자료형을 배웁니다. 그런데, 소스코드를 살펴보다 보면 int8_t, uint8_t, int16_t, uint16_t ... 등을 사용하는 것을 심심치

educoder.tistory.com

https://nevertrustbrutus.tistory.com/58

 

[C언어] C언어 <stdint.h> 헤더파일

정수형 char 1byte ~128~127 short 2byte ~32786~32767 int 4byte -2.147.483.648 ~ 2.147.483.647 long 4byte -2.147.483.648 ~ 2.147.483.647 long long 8byte ~9.223.372.036.854.775.808~ 9.223.372.036.854.775.807 실수형 float 4byte +- 3.4 x 10^-37 ~ +-3.4x10

nevertrustbrutus.tistory.com

https://ko.wikipedia.org/wiki/%EC%BD%9C%EB%B0%B1

 

콜백 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 프로그래밍에서 콜백(callback) 또는 콜백 함수(callback function)는 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말한다. 콜백을 넘겨받는 코드는 이 콜백을

ko.wikipedia.org

https://m.blog.naver.com/nimtedd41/221671309534