2020년 10월 6일 화요일

EDMA

Tool 정보 : ccsv9

Board 정보 : EVM C6678 


사용 라이브러리 및 Products : 

Products : c667x PDK(2.0.16), SYS/BIOS (6.76.3.01), EDMA3 Low Level Driver

라이브러리 : 


시험 설명 

DDR3 메모리에 데이터를 기록해 놓고 MSMCSRAM 메모리로 DMA를 통한 데이터 전송을 시험하낟.

소스코드 위치

https://github.com/pcw1029/tms320C6678/tree/edma

설정(XGCONF)




























결과 화면





2020년 10월 2일 금요일

DSP PDK Example 및 프로젝트 생성

 PDK에는 모든 PDK 하위 구성 요소에 대한 예제를 만들고 CCS 프로젝트를 테스트하는 데 사용되는 Windows 스크립트가 포함되어 있습니다. 다음 단계에서는 스크립트를 사용하여 CCS 프로젝트 콘텐츠를 만드는 방법을 설명합니다.

우선 gmake를 사용할수 있도록 설정해야 합니다. gmake는 xdctools의 있습니다.

제어판 -> 시스템 -> 고급 시스템 설정 -> 환경변수 -> 시스템 변수 중 Path를 편집을 이용하여 gmake Path를 추가합니다.


command창을 열고 PDK의 하위폴더인 packages로 이동하여 아래 명령을 실행합니다.

c:\ti\pdk_c667x_2_0_16\packages> pdkProjectCreate.bat C6678 all little all example dsp

실행이 완료되면 MyExampleProjects폴더가 만들어집니다.



2020년 9월 26일 토요일

Very Large FFT for TMS320C6678

Introduction

이 백서는 TI의 TMS320C6678 8 코어 고정형 DSP 코어의 1, 2, 4 및 8 DSP 코어에서 16K ~ 1024K 샘플 크기의 1 차원 복합 단 정밀도 부동 소수점 FFT를 구현하는 초대형 FFT (VLFFT) 데모에 대해 설명합니다. C66x DSP 코어의 기능과 추가 된 코어 수에 비례하는 성능 향상을 통해 여러 코어에 걸친 병렬화를 수용하는 아키텍처의 기능을 보여주기위한 부동 소수점 DSP. FFT는 의료 영상, 통신, 군사 및 상업용 레이더, 전자전 (재머, 안티 재머)과 같은 애플리케이션에 사용되는 일반적인 신호 처리 빌딩 블록이므로이 데모의 알고리즘으로 FFT가 선택되었습니다. 1024K 샘플 FFT는 알고리즘이 1GHz에서 TMS320C6678 장치의 8 개 DSP 코어 모두에서 실행될 때 6.4ms에 불과한 것으로 나타났습니다.


TMS320C6678 SoC

TMS320C6678 장치는 TI의 C66x 고정 및 부동 소수점 DSP 코어를 기반으로하는 8 코어 DSP이며 완전한 멀티 코어 권한을 지원하는 TI의 혁신적인 KeyStone ™ 아키텍처를 기반으로합니다.

최대 1.25GHz에서 작동 할 수 있으며이 속도에서 160GFLOPS를 생성 할 수 있으며 일반적인 사용 사례에서 10W 미만을 소비합니다. 또한 DSP 코어 당 512KB의 L2 메모리와 총 8MB의 온칩 메모리를위한 4MB의 공유 메모리가 있으며 모두 ECC를 사용합니다. DDR3 인터페이스는 최대 1600MTPS를 실행할 수 있으며 최대 8GB의 외부 메모리에 액세스 할 수 있으며 64 비트 + 8 비트 ECC 인터페이스입니다. 주변 장치에는 PCIe, Serial RapidIO® 및 기가비트 이더넷, 타사 IP 블록을 통해 FPGA뿐만 아니라 다른 TI DSP, ARM® 및 ARM + DSP 프로세서에 최대 50Gbps 연결을 제공하는 TI의 HyperLink 인터페이스가 포함됩니다. .

VLFFT 데모에서 TMS320C6678 장치는 1333MHz에서 DDR3 전송을 사용하여 1GHz에서 작동합니다.


VLFFT 데모

VLFFT 알고리즘을 사용하려면 입력 데이터를 장치의 외부 메모리에 배치해야합니다. 데모 중에 데이터는 DSP 코어에 의해 액세스, 배포 및 처리 된 다음 출력이 외부 메모리에 배치됩니다. 측정 된주기 수와 시간은이 전체 프로세스를 포함합니다. 다음 크기의 FFT에서 계산을 수행하기 위해 다른 수의 코어 (1, 2, 4 또는 8)를 사용하도록 소프트웨어를 구성 할 수 있습니다.

• 16K

• 32K

• 64K

• 128K

• 256K

• 512K

• 1024K

FFT 구현은 계산 부하를 여러 코어에 분산하고 C66x DSP 코어의 고성능 계산 능력을 완전히 활용하여 최대 성능을 달성하도록 설계되었습니다. 기본적인 데시 메이션-인-타임 접근법은 1 차원 매우 큰 FFT 계산을 2 차원 FFT 계산과 유사한 형태로 공식화하는 데 사용됩니다.

매우 큰 N의 경우 N = N1 * N2로 계수 될 수 있습니다. 크기가 매우 큰 경우 1 차원 입력 배열을 N1 행과 N2 열의 2 차원 배열로 나타낼 수 있으며 다음 단계를 수행하여이 표현에서 매우 큰 1 차원 FFT를 계산할 수 있습니다.

1. 열 방향에서 N1 크기의 N2 FFT 계산

2. 회전 계수로 곱하기

3. N1 크기의 N2 FFT를 행 방향으로 저장하여 N2 x N1 2 차원 배열을 형성합니다.

4. N2 크기의 N1 FFT를 열 방향으로 계산

5. 데이터를 열 방향으로 저장하여 N2 x N1 2 차원 배열 형성

이 알고리즘은 Takahashi가 "Hitachi SR8000 용 고성능 병렬 FFT 알고리즘"에서 자세히 설명합니다. [1] 멀티 코어 구현에서 1 단계는 각 코어에서 N1 크기의 N2 / (코어 수) FFT를 계산하여 수행됩니다. 각 코어에서 N1 / (코어 수) 크기 N2의 FFT를 계산하여 4 단계. 코어 0은 마스터 코어로 사용되며 모든 코어를 동기화하고 나머지 코어는 슬레이브 코어로 사용됩니다. 각 코어에서 N1 및 N2의 크기에 따라 각 코어의 총 FFT 수는 코어 당 L2 SRAM의 크기를 수용하기 위해 여러 개의 작은 블록으로 나뉩니다. 각 데이터 블록은 DMA에 의해 외부 메모리에서 L2 SRAM으로 프리 페치되고 FFT 결과는 DDR에 의해 외부 메모리에 다시 기록됩니다. 각 코어는 2 개의 DMA 채널을 사용하여 외부 메모리 (DDR3)와 내부 메모리 (L2 SRAM)간에 입력 및 출력 샘플을 전송합니다.

2020년 9월 25일 금요일

DSP GPIO Interrupt

Tool 정보 : ccsv9

Board 정보 : EVM C6678 

keystone 인터럽트 관련 참고 사이트 : 

https://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices

gpio 관련 문서 : https://www.ti.com/lit/ug/sprugv1/sprugv1.pdf

TEST_PH1(80PIN)



GPIO Memory Map Address : 

Start : 0x02320000  

End : 0x023200FF 

SIZE : 256

GPIO0 ~ GPIO15

인터럽트로 사용 GPIO -> GPIO14, GPIO15

사용 라이브러리 및 Products : 

Products : c667x PDK(2.0.16), SYS/BIOS (6.76.3.01)

라이브러리 : 

C:\ti\pdk_c667x_2_0_16\packages\ti\platform\evmc6678l\platform_lib\lib\debug\ti.platform.evm6678l.lite.lib

C:\ti\pdk_c667x_2_0_16\packages\ti\csl\lib\c6678\c66\release\ti.csl.ae66

C:\ti\pdk_c667x_2_0_16\packages\ti\csl\lib\c6678\c66\release\ti.csl.intc.ae66


시험 설명 

GPIO#13번핀을 인터럽트 신호 발생원으로 사용하고 GPIO#14, #15번을 각각 인터럽트핀으로 사용한다.

GPIO#13은 Clock함수를 이용하여 일정 주기(100msec)마다 인터럽트를 발생하고 발생된 인터럽트는 EventCombiner를 거쳐 Hwi인터럽트 설정 함수를 호출하여 인터럽트 처리를 한다.

인터럽트 처리는 Global변수를 증가하여 인터럽트 발생횟수를 확인한다.


소스코드 위치 

https://github.com/pcw1029/tms320C6678/tree/main/gpioInterrupt


TMS320C6678문서에 따르면 인터럽트 Event Number를 보면 GPIO핀은 GPIO8 ~ GPIO15을 인터럽트 사용할수 있으며, 이벤트번호 82 ~ 89까지 맵핑되어 있다.

(https://www.ti.com/lit/ds/symlink/tms320c6678.pdf 169페이지 참고)

설정(XGCONF)

  • SYS/BIOS -> Scheduling -> Hwi : 
    • Instance로 이동하여 아래 내용 설정
    • ISR Function이름, Interrupt number를 설정한다. 총 2개의 인터럽트를 생성할것이기 때문에 ADD를 눌러 인터럽트 1개를 더 추가하여 설정한다. [(인터럽트 번호는 각각 4,5를 사용할 것이며 인터럽트 0~3 예약되어 있어 사용할수 없다.)( 인터럽트가 발생되었을때 콜백될 함수는 gpio14Interrupt, gpio15Interrupt로 사용한다.)]
    • Event ID 설정 : 이벤트는 88, 89를 사용할 계획이므로 각각 88, 89를 설정한다. 이벤트 번호는 위에 그림에서 확인할수있고 또는 GPIO번호 + 74를 하면된다.

  • SYS/BIOS : Device Support로 이동하여 Event Combiner를 선택한다. 
    • Module : Add the EventCombiner module to my configuration을 체크
    • Event group 2 Hwi 항목에 6으로 설정 (이벤트 그룹 2를 선택한 이유는 event Combiner의 논리적 표현을 보면 124개의 시스템 이벤트가 있고 이를 4개의 그룹으로 나눴다. 즉 [Group#1 : event#04 ~ event#31], [Group#2 : event#32 ~ event#63], [Group#2 : event#64 ~ event#95], [Group#3 : event#96 ~ event#127]이다. Event 88,89가 GPIO인터럽트로 사용할수 있으면 이는 Event Combiner Group#2에 속해있기 때문이다. 
    • Events : Event 88, 89번의 Unmake를 false->true로 변경하고, 실행 함수명을 설정해준다. 함수명은 hwiCombinGpio14Gpio15다.

  • 프로젝트 생성시 ccs project인경우 task가 기본적으로 추가되어있으며 실험에선 사용하지 않으므로 삭제한다. 실험에서는 Clock함수를 생성하여 사용할것이기 때문이다.

  • SYS/BIOS -> Scheduling -> Clock  :  
    • Module  : Add the Clock support module to my configuration 체크
    • Instance :  Add
      • Function : gpio13InterruptOccursEveryCycle
      • Initial timeout : 50
      • Period : 50
      • Start at boot time when instance is created : 체크

보드 연결 상태


결과 화면




2020년 9월 17일 목요일

라즈베리파이4 시리얼 이름지정

  • 시리얼 정보 보기 : 
    • $ sudo udevadm info -q all -a /dev/ttyUSB0 
명령 실행시 아래와 같이 많은 정보들이 출력된다. 시리얼의 이름을 지정하기 위해서는 알아야 하는 정보는 ATTRS {idVendor} == "0403", ATTRS {idProduct} == "6001", ATTRS {serial} == "A6008isP" 가된다.
여기서 시리얼을 구분하는 정보가 ATTRS {serial}이다.

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="ftdi_sio"
    ATTRS{latency_timer}=="16"
    ATTRS{port_number}=="0"

    • 동일한 USB to Serial의 정보(ATTRS {serial})를 보면 아래와 같다.
root@raspberrypi:/proc/tty/driver# udevadm info -q all -a /dev/ttyUSB0 | grep serial
    SUBSYSTEMS=="usb-serial"
    ATTRS{serial}=="A100XD7O"
    ATTRS{serial}=="0000:01:00.0"
root@raspberrypi:/proc/tty/driver# udevadm info -q all -a /dev/ttyUSB1 | grep serial
    SUBSYSTEMS=="usb-serial"
    ATTRS{serial}=="A500YNK3"
    ATTRS{serial}=="0000:01:00.0"
  • UDEV 규칙 만들기
    • /etc/udev/rules.d 폴더에 99-usb-serial.rules 파일을 만들고 아래와 같이 규칙을 입력해준다.
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A100XD7O", SYMLINK+="POSITION"
  • 변경된 이름확인
    • ls -al /dev/POSITION 
lrwxrwxrwx 1 root root 7 Sep 18 02:14 /dev/POSITION -> ttyUSB0

2020년 9월 16일 수요일

라즈베리파이4 설치 유틸

  • SSH : SD카드의 /boot/폴더 밑에 ssh이름의 빈 파일을 생성
  • tftp : sudo apt-get install tftp
  • vim : sudo apt-get install vim
  •  

라즈베리파이4 SD카드 만들기

  • 라즈베리 파이 4에서 SD카드 이미지 생성을 위해 Raspberry Pi Imager 유틸리티를 사용한다.
  • Raspberry Pi Imager 다운로드 : 
    • 윈도우용 https://downloads.raspberrypi.org/imager/imager_1.4.exe
    • 리눅스용 https://downloads.raspberrypi.org/imager/imager_1.4_amd64.deb
  • 이미지 생성후 콘솔을 이용하기 위해 GPIO14, GPIO15핀의 시리얼 연결
    • 라즈베리파이의 시리얼은 3.3v로 동작한다. 시중에 판매하는 USB to Serial를 이용하게 되면 핀이 망가질수 있다.
  • 콘솔을 이용하기 위해서는 생성된 이미지중 boot폴더에 cmdline.txt, config.txt 파일을 수정해야한다. 
    • config.txt 파일에 아래를 추가
      • dtoverlay=disable-bt
      • enable_uart=1
      • boot_delay=2


2020년 8월 13일 목요일

PETALINUX 사용자 Layer를 이용한 동적 라이브러 및 어플리케이션 생성

petalinux

  • 사용자 Layer 경로 설정
    • petalinux-config 명령을 통해 user layer 0에 위치를 설정한다.
petalinux-config 명령을 통해 user layer 0에 위치를 설정한다.
Yocto Settings --->
    User Layers --->
        ( ) user layer 0

${PROOT}는 petalinux 프로젝트 생성 폴더를 말한다.(petalinux-create -t project -n myZynq --template zynq 명령을 통해 생성된 myZynq 폴더)

내용을 저장하고 나오면 아래와 같이 오류메시지가 나온다. 아직 user layer 위치에 아무것도 없기때문에 나오는 메시지다 
[INFO] sourcing bitbake
ERROR: Failed to source bitbake
ERROR: Failed to config project.
  • 사용자 공간 Layer 작업
    • 위에서 설정한 경로의 폴더를 아래와 같이 구성한다.

    • 각 폴더의 필요한 파일들을 아래와 같이 구성한다.

    • 각 폴더의 내용은 아래와 같다.
    • layer.conf
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
    ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "libcalculator"
BBFILE_PATTERN_libcalculator = "^${LAYERDIR}/"
BBFILE_PRIORITY_libcalculator = "6" 
    • libcalculator_1.0.bb
#
# This file was derived from the 'libcalculator!' example recipe in the
# Yocto Project Development Manual.
#

DESCRIPTION = "Simple libcalculator application"
SECTION = "libs"
DEPENDS = ""
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=96af5705d6f64a88e035781ef00e98a8"

# This tells bitbake where to find the files we're providing on the local filesystem
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"

# Use local tarball
SRC_URI = "file://libcalculator-${PV}.tar.gz"

# Make sure our source directory (for the build) matches the directory structure in the tarball
S = "${WORKDIR}/libcalculator-${PV}"

PACKAGE_ARCH = "${MACHINE_ARCH}"
PROVIDES = "calculator"
TARGET_CC_ARCH += "${LDFLAGS}"
do_install() {
    install -d ${D}${libdir}
    install -d ${D}${includedir}
    oe_libinstall -so libcalculator ${D}${libdir} 
    install -d -m 0655 ${D}${includedir}/CALCULATOR
    install -m 0644 ${S}/*.h ${D}${includedir}/CALCULATOR/
}
FILES_${PN} = "${libdir}/*.so.* ${includedir}/*"
FILES_${PN}-dev = "${libdir}/*.so"

  • 동적 라이브러리 코드 구현
    • 동적 라이브러 위치, 폴더 구성 및 파일은 아래와 같다.

    • 각 파일 내용은 아래를 참고
    • LICENSE
The MIT License (MIT)

Copyright (c) 2014 Dynamic Devices

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all 
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
LICENSE파일의 경우 libcalculator_1.0.bb파일에서 LIC_FILES_CHKSUM으로 검사하기 때문에 한문자, 한 공백까지도 동일해야 한다. 동일하지 않을경우 컴파일 실패가 발생하며 이럴경우 md5sum명령으로 CHKSUM값을 확인하여 libcalculator_1.0.bb파일에 LIC_FILES_CHKSUM의 값을 변경할 필요가 있다. 즉 LIC_FILES_CHKSUM값과 md5sum LICENSE 결과는 동일해야 한다.

    • Makefile
APP = calculator

LIBSOURCES=*.c
OUTS = *.o
NAME := calculator
MAJOR = 1.0
MINOR = 1
VERSION = $(MAJOR).$(MINOR)
       
all: lib$(NAME).so
lib$(NAME).so.$(VERSION): $(OUTS)
    $(CC) $(LDFLAGS) $(OUTS) -shared -Wl,-soname,lib$(NAME).so.$(MAJOR) -o lib$(NAME).so.$(VERSION)

lib$(NAME).so: lib$(NAME).so.$(VERSION)
    rm -f lib$(NAME).so.$(MAJOR) lib$(NAME).so
    ln -s lib$(NAME).so.$(VERSION) lib$(NAME).so.$(MAJOR)
    ln -s lib$(NAME).so.$(MAJOR) lib$(NAME).so
           
%.o: %.c
    $(CC) $(CFLAGS) -c -fPIC $(LIBSOURCES)
      
clean:
    rm -rf *.o *.so *.so.*

    • add.c
/*
 * add.c
 *
 *  Created on: 2020. 8. 13.
 *      Author: pcw1029
 */
#include "add.h"

int add(int val1, int val2)
{
    return val1+val2;
}

    • add.h
/*
 * add.h
 *
 *  Created on: 2020. 8. 13.
 *      Author: pcw1029
 */

#ifndef ADD_H_
#define ADD_H_

int add(int val1, int val2);

#endif /* ADD_H_ */

    • make명령을 실행하여 정상적으로 동적라이브러리가 만들어 지는지 확인한다.

    • make clean으로 생성된 동적 라이브러리 파일과 오브젝트 파일을 삭제하고 폴더를 압축한다.  

최종 폴더 구성및 위치, 파일 구성 및 위치가 아래와 같다.

  • {}project-spec/meta-user/recipes-core/images/petalinux-image.bbappend 파일에 내용 아래 와같이 내용을 추가한다. 기존에 peekpoke, gpio-demo가 자동으로 들어가 있는게 일반적인데 없더라도 신경쓸거없다. 우리는 위리가 추가한 libcalculator만 잘 넣으면 된다.
#Note: Mention Each package in individual line
#      cascaded representation with line breaks are not valid in this file.
IMAGE_INSTALL_append = " peekpoke"
IMAGE_INSTALL_append = " gpio-demo"
IMAGE_INSTALL_append = " libcalculator"
  • petalinux-config -c rootfs명령으로 추가된 libcalculator을 enable시켜준다.
user packages --->

  • petalinux-build명령을 실행하여 해당 동적라이브러리를 컴파일 한다.

  • 정상적으로 빌드가 끝나면 ./build/tmp/sysroots/plnx_arm/usr/lib 아래 정적라이브러리 파일이 생성된다.


* 어플리케이션의 경우 

petalinux syslog 설정 변경

petalinux에서 syslog의 설정을 변경하는 방법

project-spec/meta-user/recipes-core/ 폴더에 아래와 같이 파일과 폴더를 생성한다.
폴더 : busybox, files
파일 : busybox_1.%.bbappend

2020년 6월 15일 월요일

Capter2( const, 실행중인 프로그램의 메모리 구조, 참조자, 참조자와 함수)


  • 키워드 Const
    • const int num = 10;   -> 변수 num을 상수화한다.
    • const int* ptr1 = &val1;  -> ptr1을 통해서 val1의 값을 수정하지 못한다.
    • int* const ptr2 = &val2;  -> ptr2는 상수화 된다. 따라서 val2의 주소외 다른 주소를 못가진다.
    • const int* const ptr3 = &val3;  -> ptr3는 상수화 되고, ptr3을 통해 val3의 값을 수정하지 못한다.

  • 실행중인 프로그램의 메모리 구조
    • 코드 영역 : 메모리의 코드영역은 실행할 프로그램의 코드가 저장되는 영역으로 텍스트영역이라고도 부른다. CPU는 코드영역에 저장된 명령어를 하나씩 가져와 처리하게된다.
    • 데이터 영역 : 프로그램의 전역 변수와 정적(static)변수가 저장되는 영역이다. 데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램 종료시 소멸된다.
    • 스택 영역 : 함수의 호출과 관계되는 지역변수와 매개변수가 저장되는 영역이다. 스택영역은 함수의 호출과 함께 할당되며, 함수호출이 완료되면 소멸한다. 이렇게 스택영역에 저장되는 함수의 호출정보를 스택프레임 이라고 한다. 스택은 푸시동작으로 데이터를 저장하고 팝동작으로 데이터를 인출한다. 가장 늦게 저정된 데이터가 가장 먼저 인출되는 구조이며, 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.
      • 스택 프레임 : 함수가호출되면 스택에는 함수의 매개변수, 호출이 끝나고 돌아갈 반환 주소값, 함수의 선언된 지역변수 등이 저장된다. 이렇게 스택영역에 차례대로 저장되는 함수의 호출 정보를 스택프레임 이라고 한다. 스택프레임으로 인해 해당 함수가 함수의 일을 마친뒤 이전 상태로 돌아갈수 있는것이다.

    • 힙 형역 : 사용자가 관리할 수 있는 메모리 영역이다. 사용자에 의해 메모리를 동적으로 할당하고 해제하며 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.
  • 참조자(Renference) : 할당된 하나의 메모리 공간에 둘 이상의 이름을 부여하는것으로 &연사자를 이용한다.  &연산자는 변수의 주소를 반환하는 연산자 이지만 변수 선언시 사용하게 되면 참조자의 선언이 된다. (ex int &num2 = num1; ) 
    • 참조자는 별칭이다.
    • 참조자의 수에는 제한이 없으며, 참조자를 대상으로도 참조자를 선언할수 있다.
  • 참조자와 함수 : C언어에서 Call-by-reference는 포인터를 이용하여 변수의 값을 수정하였다. 하지만 C++에서는 참조자를 이용하여 Call-by-reference구현할수 있다. 아래 구현 내용을 참고한다. 


2020년 6월 14일 일요일

Chap1(함수오버로딩, 매개변수 디폴트, 인라인 함수, 이름공간)

  • 함수 오버로딩 : 함수의 이름은 동일하지만 매개변수의 개수와 자료형이 다른경우 별개의 함수로 구분하는것. (C언어에서는 함수 이름만을 이용하여 호출대상을 찾기때무에 오버로딩을 허용하지 않지만 C++에서는 함수이름과 매개변수 선언을 보고 호출대상을 찾는다)
Ex>


  • 매개변수 디폴트 : 함수의 매개변수값을 기본으로 지정하여, 함수 호출시 매개변수의 인자값이 없을경우 지정된 값으로 설정된다. 주의  함수 선언부에서 설정해야한다. 
Ex>


  • 매크로함수 장/단점
    • 장점 
    1. 일반 함수보다 매크로함수의 실행 속도가 빠르다. 이유는 일반 함수의 경우 함수호출이 일어나면 매개변수나 호출자의 주소를 스택에 저장하는 행위를 하는 반면 매크로함수의 경우 전처리기에서 호출자를 치환해주기때문에 스택에 저장하는 등의 행위를 피할수 있다.
    2. 자료형에 의존적이지 않다. 
    • 단점 
    1. 매크로 함수의 경우 크기가 증가할 수록 괄호를 많이 써야하기때문에 가독성이 떨어진다.
    2. 디버깅이 어렵다.
  • 인라인(inline)함수 
    • 인라인을 직역하면 프로그램 코드라인 안으로 들어가버린 함수
    • 인라인함수는 매크로와 동일한 일을 한다. 단 일반 함수처럼 정의가 가능하다.
    • 매크로 함수는 전처리기에서 처리가 되지만 인라인함수는 컴파일 단계에서 컴파일러에 의해 처리되기때문에 인라인화가 성능에 해가된다고 컴파일러가 판단되면 컴파일러는 인라인 키워드를 무시하기도 하고, 일반 함수가 인라인화하여 성능향상에 도움이 된다고 판단하면 일반 함수로 인라인화 시키지 않아도 컴파일러에 의해 인라인 함수로 취급된다.


  • 이름공간(namespace)
    • 등장배경 : 예를 들어 은행관리 시스템 관리 프로그램을 만드는데 3개의 회사가 참여하였고 프로젝트 규모가 커서 일을 구분하여 독립적으로 진행하기로 했다고 가정하자. 3개의 회사는 각 각 개발을 완료하였고 3개의 회사가 모여 하나의 프로젝트를 완성하는 단계에서 함수의 이름이 동일하여 컴파일 문제가 발생하게 되었다. 이는 협업 과정에서 모든 함수의 이름을 만들때 규칙이 없었기 때문일 수도 있지만 이런 문제가 발생하게 되었을대 이름공간이 문제를 해결할 수 있다.
    • 사용방법은 아래 코드를 참고한다. 
    • 참고로 동일한 이름공간의 함수들은 이름공간의 명시 없이 사용가능하다.


    • 이름공간의 중첩 : 이름공간은 다른 이름공간 안에 삽입될수있다. 


    • using을 이용한 이름공간 명시 : 키워드 using을 이용하면 이름공간을 지정하지 않고도 함수를 호출할 수 있다. 아래 코드에서 main()함수의 using의 선언한 HybFunc()은 함수, 변수 모두 선언이 가능하다. 단, 지역변수 선언과 마찬가지로 지역을 벗어나면 그 효력을 읽게 된다.


    • 이름공간의 별칭 지정 : 이름공간의 중첩과 같이 여러개의 중첩이 일어난 경우 이름에 별칭을 부여할수도 있다.(개인적으로 이건 좀.... 아닌거같다)


    • 범위지정 연산자의 또다른 기능 : 지역변수의 이름과 전역변수의 이름이 동일한 경우 전역변수는 지역변수에 의해 가려지게 된다. 이런경우 전역변수를 사용할수 있게 해주는것이 범위지정 연산자 이다. 


VITIS Git + Doxygen Config

 Doxygen Configure 1. Vitis 메뉴의 Window->Preference의 C/C++ -> Editor의 Documentation tool comments 기본 설정값을 Doxygen으로 변경 설정 후 함수 바로 위에서 /...