4/29/2018

Raspberry Pi 의 Device Tree 및 cmdline 수정

1. Raspberry Pi Booting 및 설정 분석

  • Raspberry Pi Boot관련정보 
  1. cmdline.txt : kernel cmdline 수정가능 
  2. config.txt : Raspberry 설정 파일 
  3. bootcode.bin : Raspberry bootloader로 SoC에의해 Loading 되고 start*.elf를 로딩
  4. start.elf, start_x.elf, start_db.elf, start_cd.elf : firmware로 사용되지만 elf파일형식 
  5. fixup.dat, fixup_x.dat, fixup_db.dat, fixup_cd.dat : start*.elf의 linker file 
  6. *.dtb : Device Tree Blob

  https://wikidocs.net/3198
  https://wikidocs.net/18317


1.1 /boot 파일 확인 

일단 아래를 보면, dtb 파일과 kernel.img가 많아서 현재 사용중인 이미지를 알아야겠다.
추측을 하면 아래의 것을 사용할 것으로 짐작

$ cd /boot
bcm2708-rpi-0-w.dtb     bcm2709-rpi-2-b.dtb       bootcode.bin   fixup_cd.dat  issue.txt         LICENSE.oracle  start.elf
bcm2708-rpi-b.dtb       bcm2710-rpi-3-b.dtb       cmdline.txt    fixup.dat     kernel7.img       overlays        start_x.elf
bcm2708-rpi-b-plus.dtb  bcm2710-rpi-3-b-plus.dtb  config.txt     fixup_db.dat  kernel.img        start_cd.elf
bcm2708-rpi-cm.dtb      bcm2710-rpi-cm3.dtb       COPYING.linux  fixup_x.dat   LICENCE.broadcom  start_db.elf


1.2 DTS 와 DTB 구조 복습 (Device Tree) 

Device Tree 의 기본이해 (관련예제도 링크)
  https://ahyuo79.blogspot.com/2015/08/kernel-boot-kernel-device-tree.html
  https://www.elinux.org/images/a/ad/Arm-soc-checklist.pdf

Device Tree Spec (v0.2 와 v0.1) 및 각 문법 이해 (필독)
  https://www.devicetree.org/specifications/
  https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.2
  https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.1

Device Tree 활용
  https://elinux.org/Device_Tree_Usage


  • DTS의 기본구조 
/ 로 시작하여 model과 아래 좌측을 부터 정의하기 시작하여 구성

  • 상위기본구성 분석
  1. / 의 model= MACHINE 정보이름과 compatibale 에 해당 arch를 선택 (MACHINE 정보)
  2.  #address-cells 1 , #size-cells  1 의 의미는 
    1. child의 address cell u32 갯수와 size cell u32 갯수 말하며 이는 reg에 적용 
  3. memory@0 의 의미는 memory address 0 의미 
    1. reg = <0  0x20000000) address 와 size 
  4. uart@fe00100 의 의미는 uart 의 address는 0xfe00100 
    1. reg = <0xfe001000 0x100 > 은 address 와 size 



  • Sample DTS (Deivce Tree Syntax) 구조 (상위 Spec 문서참조)
아래와 같이 DTS도 Version 이 존재하며, 각 Version 별로 문법이 변경될 것이므로 이부분을 반드시 확인
C와 같이 Preprocessor가 먼저 진행 빌드되므로 이점 주의 
$ vi arch/arm/boot/dts/mysample.dts  //kernel or uboot 
/dts-v1/;  // device tree spec 를 반드시 참조하며, 각 node의 manual 별도로 보자 

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

//커널의  ./include/dt-bindings/  
//커널의 ./scripts/dtc/include-prefixes/dt-bindings    
// dtc는 ./scripts/dtc 에 존재 

#include "sample.dtsi"


// 아래와 같이 C처럼 Preprocess(상위 include)가 동작가능하며, 주석도 /**/ // 둘다 가능

#define TEST  //preprocess 도 동작가능 C처럼 Preprocess가 다른 것 보다 먼저 실행되는 것을 주의  

#if 1 // jhlee 

#endif

#ifndef TEST

#endif

#ifdef TEST

#endif

#if defined(TEST) //jhlee

#else //orgin

#endif




/ {   // / { 는 DTS Main을 의미하며, 만약 sample.dtsi 이 것이 포함이 되어 있다면, 그곳에 위치에 들어간다고 생각하면됨

//보통 Kernel에서 model 에 정보를 넣으면, 부팅시 Machine Name 확인가능 
//조금 고급스럽게 하고자 하면 색 정보도 같이 넣어 만들자  
//sample.dtsi 이미 있지만, 중복으로 넣어 최종이것으로 빌드하면 최종값으로 적용가능  
        //model = "fsl,mpc8572da";     
        //MACHINE 정보 Name이며 마음대로 변경,DT_MACHINE_START (Device Tree용) or MACHINE_START         
        model = "EVM_JHLEE";       
        compatible = "fsl,mpc8572da";       //board 호환성이며, "manufacturer,model" kernel 검색 
};
// }; 는 상위 model 때문에 삽입 

#if 1 //아래 다시 중복설정할 경우 이것이 최종 값으로 결정되며, model만 재선언 (제조사 생략)하여, 내맘대로 변경    
/ {
      // Kernel Boot시 색깔까지 넣어 표시   
      model = "\x1b[1m \x1b[93m  Jeonghun Board Ver 0.0 \x1b[0m"; // Machin Name을 변경      
};
#endif 

// 주석 
/* 주석 */


/* 
보통 gpio node가 구성되고, PINMUX에서 GPIO로 설정하면, User에서 /sys/class/gpio/export 를 이용하여 직접사용가능 
GPIO4_18  보통 (4-1)*32+18 = 114  
GPIO4_19  보통 (4-1)*32+18 = 115
*/
/*
 /sys/class/gpio/export 
 /sys/class/gpio/gpio114/direction
 https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
 항상 compatible 에서 device driver와 연결하므로, Kernel에서 Pinmux를 하였다고, 자동으로 /sys/class/gpio/export에 적용되지 않는다 
 */ 

  • 필요없는 부분 중복된 부분삭제 관련예제
  1. /delete-node/      : node or lable 삭제
  2. /delete-property/ : node 의 property 삭제
  3. /omit-if-no-ref/    : dtc에게 사용하지 않는다면, 삭제 
  https://elinux.org/Device_Tree_Source_Undocumented

상위에서 설명했듯이 중복많이 허용하며, 최종선언된 dts기준으로 파싱을 시작하기때문에 필요없다면, 
나만의 dts를 만들경우 최종 dts include하고 필요없는 것을 정리하도록하자  

// 이미 이전에 선언된 uart1 label 의 property의 status를 okay ->disabled 변경 
&uart1 {
   status = "disabled";
};

// 이미 이전에 선언된 uart1 lalel 의 특정 property만 삭제 
&uart1 {
    /delete-property/ fsl,uart-has-rtscts;
};


/* 

node의 구성 은 보통 label: node로  or node로만 구성될 수가 있으며, label에는 &를 사용 

label: node  

adv_bridge0: adv7535@3d {
...
};

adv_bridge1: adv7535@3d {
...
};
*/
 

// node를 삭제방법은 label에는 &사용하며, node 를 직접입력할 경우 &불필요

/delete-node/ &adv_bridge0;
/delete-node/ &adv_bridge1;

  • OS에서는 호환성목적으로 aliases 기능을 사용
각 Chip label 이름이 다 다르게 정의될 수 있으므로, OS가 알수 있도록 이를 변경 
// aliases는 node의 새로 naming 하여 쉽게 node구성하며, 주로 OS 즉 linux 호환성을위해서 사용해준다  
// 구성은 이전과 같이 label에 &사용
aliases {
     rtc0 = &snvsrtc;
     rtc1 = &rtc;
};


chosen {
      bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};

https://elinux.org/Device_Tree_Usage#aliases_Node

  • #xxx-cells 의 의미 
child의 cells 의 갯수를 정의해주는 것으로 기본적인 address-cells 과 size-cells 이 존재한다.
더불어 다양한 #로 시작하는 cells들이 존재 
/dts-v1/;

/ {
    #address-cells = <1>; // address-cells의 의미 child의 reg의 address u32 갯수  
    #size-cells = <1>;    // size-cells 의 의미 child의 reg의 size u32 갯수  

    ...

    serial@101f0000 {
        compatible = "arm,pl011";
        reg = <0x101f0000 0x1000 >; // 상위 address-cells 수(1) 와 size-cells 수(1)로 결정
    };

    serial@101f2000 {
        compatible = "arm,pl011";
        reg = <0x101f2000 0x1000 >;
    };

    gpio@101f3000 {
        compatible = "arm,pl061";
        reg = <0x101f3000 0x1000
               0x101f4000 0x0010>; // 상위 address-cells 수(1) 와 size-cells 수(1)로 결정 연속 2개 
    };

    interrupt-controller@10140000 {
        compatible = "arm,pl190";
        reg = <0x10140000 0x1000 >;
    };

    spi@10115000 {
        compatible = "arm,pl022";
        reg = <0x10115000 0x1000 >;
    };

    ...

https://elinux.org/Device_Tree_Usage#Memory_Mapped_Devices
};

  • range 의 의미 
OS는 virtual address를 사용하며, 이를 위해서 memory map-io로 연결하여 사용한다. 
이때 각 영역의 부분의 정의해주는 것이 range의 기능이다. 
/dts-v1/;

/ {
    compatible = "acme,coyotes-revenge";
    #address-cells = <1>;  //parent의 reg의 address u32 수  
    #size-cells = <1>     //parent의 reg의 size u32 수  
    ...
    external-bus {
        #address-cells = <2>;  //child의 reg의 address u32 수  
        #size-cells = <1>;     //child의 reg의 size u32 수  
 
/*
range(Address Translation) 는 address translation을 위한 list 구성 
   1. the child's #address-cells value(2),  
   2. the parent's #address-cells value(1), 
   3. the child's #size-cells(1) 
마지막 size로 memory map을 하여 영역 넣어구성 아래와 같이 mapping 

- Offset 0 from chip select 0 is mapped to address range 0x10100000 - 0x1010ffff
- Offset 0 from chip select 1 is mapped to address range 0x10160000 - 0x1016ffff
- Offset 0 from chip select 2 is mapped to address range 0x30000000 - 0x30ffffff

*/
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

        ethernet@0,0 {
            compatible = "smc,smc91c111";
            reg = <0 0 0x1000>;  // 상위 child address 2개 와 size 1  
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            #address-cells = <1>; // node child address u32 수  
            #size-cells = <0>;    // node child reg의 e u32 수  
            reg = <1 0 0x1000>;   // 상위 child address  2개 와 size 1  
            rtc@58 {
                compatible = "maxim,ds1338";
                reg = <58>;             //상위 node child (1,0) 
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
            reg = <2 0 0x4000000>;
        };
    };
};
https://elinux.org/Device_Tree_Usage#Ranges_.28Address_Translation.29
https://elinux.org/Device_Tree_Usage#PCI_Host_Bridge
https://elinux.org/Device_Tree_Usage#How_Interrupts_Work



Kernel GPIO 기본사용법
  https://www.kernel.org/doc/Documentation/gpio/gpio-legacy.txt

  • Device Tree 관련문서
Device Tree는 현재 각 Platform Device Driver마다 각각의 설정값들이 존재하는데, 관련부분을 아래에서 검색해서 찾자
  https://www.kernel.org/doc/Documentation/devicetree/bindings/

  • DTB (Flattened Device Tree 라고 불림) 의 구조 





1.3 Device Tree 비교 및 확인 

Raspberry Pi에 dtc 설치 되었는지 확인

  • 사용중인 Device Tree를 확인
/proc/device-tree 정보를 dtc를 이용하여 dts 파일생성방법, 역으로 생성했기때문에 원래사용하던 dts와는 완전동일할 수는 없다.

$ dtc -I fs -O dts -o current.dts /proc/device-tree/ 

  • DTB To DTS로 변경 
dtb 파일을 dts 파일로 역으로 변경했으므로, 상위와 같이 원래 dts와 완전동일할 수가 없음

$ sudo dtc -I dtb -O dts -o bcm2710-rpi-3-b-plus.dts /boot/bcm2710-rpi-3-b-plus.dtb
$ sudo dtc -I dtb -O dts -o bcm2710-rpi-3-b.dts /boot/bcm2710-rpi-3-b.dtb
$ sudo dtc -I dtb -O dts -o bcm2708-rpi-b-plus.dts /boot/bcm2708-rpi-b-plus.dtb

  • DTS 비교 
사용 중인  DTS 상위 DTB 다르기 때문에 일단 상위 /boot의 dtb 사용을 의심.

$ diff -urN current.dts bcm2710-rpi-3-b-plus.dts 
--- current.dts 2019-02-18 23:34:57.966477519 +0900
+++ bcm2710-rpi-3-b-plus.dts 2019-02-18 23:36:18.841755013 +0900
@@ -1,1159 +1,941 @@
 /dts-v1/;
 
+/memreserve/ 0x0000000000000000 0x0000000000001000;
 / {
- compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
- serial-number = "000000003befb7f8";
- model = "Raspberry Pi 3 Model B Rev 1.2";
- memreserve = 0x3b400000 0x4c00000="";
+ compatible = "raspberrypi,3-model-b-plus", "brcm,bcm2837";
+ model = "Raspberry Pi 3 Model B+";

$ diff -urN current.dts bcm2710-rpi-3-b.dts 
--- current.dts 2019-02-18 23:34:57.966477519 +0900
+++ bcm2710-rpi-3-b.dts 2019-02-18 23:42:58.263596240 +0900
@@ -1,1159 +1,940 @@
 /dts-v1/;
 
+/memreserve/ 0x0000000000000000 0x0000000000001000;
 / {
  compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
- serial-number = "000000003befb7f8";
- model = "Raspberry Pi 3 Model B Rev 1.2";
- memreserve = <0x3b400000 0x4c00000="">;
+ model = "Raspberry Pi 3 Model B";
  interrupt-parent = <0x1>;
  #address-cells = <0x1>;
  #size-cells = <0x1>;

$ diff -urN current.dts bcm2708-rpi-b-plus.dts | head -n 30
--- current.dts 2019-02-18 23:34:57.966477519 +0900
+++ bcm2708-rpi-b-plus.dts 2019-02-18 23:51:14.696159160 +0900
@@ -1,1235 +1,1066 @@
 /dts-v1/;
 
+/memreserve/ 0x0000000000000000 0x0000000000001000;
 / {
- compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
- serial-number = "000000003befb7f8";
- model = "Raspberry Pi 3 Model B Rev 1.2";
- memreserve = <0x3b400000 0x4c00000="">;
+ compatible = "brcm,bcm2835";
+ model = "Raspberry Pi Model B+";
  interrupt-parent = <0x1>;
  #address-cells = <0x1>;
  #size-cells = <0x1>;

  • bootcode 분석
현재 사용중인 Device Tree를 정확하게 잘 몰라 다른 bootloader 를 분석했지만, 역시나. grep을 이용하여 dtb를 찾으려해도 찾지를 못했다.

$ hd /boot/bootcode.bin 
...
0000c6e0  75 70 0a 00 46 61 69 6c  65 64 20 74 6f 20 69 6e  |up..Failed to in|
0000c6f0  69 74 69 61 6c 69 73 65  20 6c 69 6e 6b 0a 00 00  |itialise link...|
0000c700  49 6e 69 74 69 61 6c 69  73 65 20 68 75 62 0a 00  |Initialise hub..|
0000c710  46 6f 75 6e 64 20 25 64  20 70 6f 72 74 73 2c 20  |Found %d ports, |
0000c720  6d 75 6c 74 69 5f 74 74  20 3d 20 25 64 0a 00 53  |multi_tt = %d..S|
0000c730  65 74 74 69 6e 67 20 69  6e 74 65 72 66 61 63 65  |etting interface|
0000c740  20 25 64 0a 00 46 61 69  6c 65 64 20 74 6f 20 73  | %d..Failed to s|
0000c750  65 74 20 69 6e 74 65 72  66 61 63 65 20 25 64 0a  |et interface %d.|
0000c760  00 45 6e 61 62 6c 69 6e  67 20 50 4f 52 54 20 50  |.Enabling PORT P|
0000c770  4f 57 45 52 20 6f 6e 20  70 6f 72 74 20 25 64 0a  |OWER on port %d.|
0000c780  00 46 61 69 6c 65 64 20  74 6f 20 73 65 74 20 66  |.Failed to set f|
0000c790  65 61 74 75 72 65 20 48  55 42 5f 46 45 41 54 55  |eature HUB_FEATU|
0000c7a0  52 45 5f 50 4f 52 54 5f  50 4f 57 45 52 20 25 64  |RE_PORT_POWER %d|
0000c7b0  0a 00 57 61 69 74 69 6e  67 20 66 6f 72 20 64 65  |..Waiting for de|
0000c7c0  76 69 63 65 73 20 74 6f  20 72 65 73 70 6f 6e 64  |vices to respond|
0000c7d0  20 74 6f 20 72 65 73 65  74 0a 00 46 6f 75 6e 64  | to reset..Found|
0000c7e0  20 64 65 76 69 63 65 20  6f 6e 20 70 6f 72 74 20  | device on port |
0000c7f0  25 64 0a 00 46 6f 75 6e  64 20 68 69 67 68 73 70  |%d..Found highsp|
0000c800  65 65 64 20 64 65 76 69  63 65 0a 00 48 75 62 20  |eed device..Hub |
0000c810  64 65 76 69 63 65 20 66  6f 75 6e 64 20 61 74 20  |device found at |
0000c820  61 64 64 72 20 25 64 2c  20 65 6e 75 6d 65 72 61  |addr %d, enumera|
0000c830  74 69 6e 67 20 48 55 42  0a 00 44 65 76 69 63 65  |ting HUB..Device|
0000c840  20 66 6f 75 6e 64 3a 20  74 79 70 65 20 3d 20 25  | found: type = %|
0000c850  73 2c 20 61 64 64 72 20  3d 20 25 64 0a 00 4d 61  |s, addr = %d..Ma|
0000c860  73 73 20 73 74 6f 72 61  67 65 00 45 74 68 65 72  |ss storage.Ether|
0000c870  6e 65 74 20 61 64 61 70  74 65 72 00 49 67 6e 6f  |net adapter.Igno|
0000c880  72 69 6e 67 20 6c 6f 77  20 73 70 65 65 64 20 64  |ring low speed d|
0000c890  65 76 69 63 65 0a 00 44  65 76 69 63 65 20 66 61  |evice..Device fa|
0000c8a0  69 6c 65 64 20 74 6f 20  72 65 73 70 6f 6e 64 20  |iled to respond |
0000c8b0  74 6f 20 72 65 73 65 74  0a 00 00 00 79 00 00 00  |to reset....y...|
....

$ strings /boot/bootcode.bin | grep dtb

  • 제공하는 Kernel Image 분석 
/boot/kernel.img 와 kernel7.img는 아래와 같이 다르게 나오며, 압축때문인 것으로 생각이 된다.

$ cat /proc/version 
Linux version 4.14.34-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1110 SMP Mon Apr 16 15:18:51 BST 2018

$ hd /boot/kernel.img | grep 'Linux'

$ strings /boot/kernel.img | grep 'Linux'
Uncompressing Linux...

$ strings /boot/kernel7.img | grep 'Linux'
Uncompressing Linux...


uImage라고 한다면, 64 byte의 헤더를 버려야 하지만, 상위 이미지를 보면 uImage 구조와 다른 것 같다.
zImage라고 생각이 들어 아래와 같이 시도해본다.


uImage 구조체
  http://www.isysop.com/unpacking-and-repacking-u-boot-uimage-files/
  http://forum.falinux.com/zbxe/index.php?document_srl=564748&mid=lecture_tip

zImage 구조
  https://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/kernel-image-file-structure.html

zImage (LZMA)
  https://stackoverflow.com/questions/37672417/getting-kernel-version-from-the-compressed-kernel-image

GPIO
  https://www.kosagi.com/w/index.php?title=Definitive_GPIO_guide
  • 사용중인 Kernel 분석 
사용중인 Kernel은 잘 나온다. (압축이 되지 않았으니 잘나오는 것 같다)

$ sudo strings /dev/mem | grep 'Linux'   
....
Booting Linux on physical CPU 0x0
Linux version 4.14.34-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1110 SMP Mon Apr 16 15:18:51 BST 2018

4/23/2018

Deep/ Machine Learning 자료 와 Cuda 자료 링크들

현재 Deep learning 및 AI 에 관련일을 하지 않기 때문에, 관련부분은 링크로 자료수집하며, 추후 시간이 된다면, 관련교육내용 사항을 정리하자. 
추후 관련일을 하거나 공부할 일 있다면, 그때 다시 재 정리를 하도록 하자. 
  • Machine 과 Deep Learning의 차이 
아래의 그림을 보면, AI에서 Machine Learning으로 그리고 Deep Learning의 변화를 간단히 볼 수있다. 
차이는 존재하겠지만 그 기본은 동일한 것으로 보인다. 

  • Cell 기반의 Layer의 구조 
Machine / Deep Learning의 구조를 보면, 각각의 Cell 로 구성된 Layer들로 구성되며, 이는 인간의 뇌의 뉴런/ Cell을 기본구성으로 생각하고 
이를 만들었다고 하는데, 글을 보면 추상적으로 는 이해가 되지만, 정확히 어떻게 동작되는지는 이해가 되지 않는다. 



  • 인간의 뉴런구조 와 이를 구현하기 위해서 만든 Cell 구조 




  • Tensorflow 와 Keras 기반으로 설명해주는 Deep Learnig MNIST 설명부분 
어느 사이트를 가든 기본으로 설명되는것이 MNIST인데, 이부분을 정확하게 이해하도록해야겠다.
  https://codelabs.developers.google.com/codelabs/cloud-tensorflow-mnist/#0
  http://cs231n.stanford.edu/syllabus.html
  http://neuralnetworksanddeeplearning.com/chap1.html


  • Docker 설치 및 구조
Machine / Deep Learning을 보다 보면, Docker를 자주 사용해야하는데, 관련부분도 자세히 알아야함
  https://datascienceschool.net/view-notebook/661128713b654edc928ecb455a826b1d/


TensorFlow 영어 교육 및 실습

  • 모두를 위한 딥러닝 관련 학습자료 

딥러닝의 Andrew Ng 교수내용이라고 하는데, 내용이 좀 많이 길다.
  http://jaejunyoo.blogspot.com/2017/03/kr-nips-2016-tutorial-summary-nuts-and-bolts-of-building-AI-AndrewNg.html

  • 상위자료 및 다양한 자료들을 수집해놓은 사이트 
  http://hunkim.github.io/ml/


  • Tensorflow 관련내용들 링크 
  https://www.slideshare.net/JunKim22/tensorflow-tutorial-68885890
  https://github.com/golbin/TensorFlow-Tutorials
  https://github.com/uosdmlab/tensorflow-tutorial
  https://www.tensorflow.org/tutorials/

  • Deep learning 와 Cuda관련자료
Deep Learning관련부분을 찾다보면, 연산량때문에 반드시 Nvidia의 Cuda가 나오며, 관련자료들을 링크 
  http://blog.naver.com/PostList.nhn?blogId=sogangori&from=postList&categoryNo=6
  http://blog.naver.com/PostList.nhn?blogId=sogangori&from=postList&categoryNo=7
  http://jaejunyoo.blogspot.com/2017/01/generative-adversarial-nets-1.html
  https://plus.google.com/+JaeJunYoo
  http://blog.naver.com/PostView.nhn?blogId=laonple&logNo=220648539191


  • Yollo and Yollo9000 설명 
설명이 비교적 쉽게되어 있어서 대충은 이해가 가지만, 완벽히는 이해가 되지 않지만, 추상적으로는 알겠다. 
이해가 되지 않는 이유는 보면, 수학함수와 왜 사용을 해야하는지 이해가 되지 않는다. 
  http://blog.naver.com/PostView.nhn?blogId=sogangori&logNo=221011203855&parentCategoryNo=6&categoryNo=&viewDate=&isShowPopularPosts=true&from=search

  • Caffe / Caffe2
  http://caffe.berkeleyvision.org/
 

이쪽 자료가 너무 방대해서 한번에 알기는 너무 힘들며, 라즈베리파이로도 Tensorflow는 지금 현재 지원이 되는 방향으로 간다.
현재 이쪽 흐름이 어떻게 갈지 모르기때문에 추후 지켜보고 전망 후 사용할 플랫폼 결정이 필요하며,
Tensorflow or Caffe 이외 다른 것도 존재하므로, 지금 공부해야할 것을 정하기가 좀 애매하다.
이 모든 것을 공부하기에는 너무 많다.

  • Bigdata 
BigData 부분은 Machine/ Deep Learning의 학습을 위해서 반드시 필요하다. 
  https://ahyuo.blogspot.com/search/label/Bigdata

  • 임베디드 관련보드 기반의 AI 추후 자료찾기 
  1.  TI 기반으로 구성된 보드에서는 AI 관련자료를 찾기가 힘듦
  2.  TI 역시 DSP기반으로 제공할 것 같은데, 이부분도 지속적으로 검색해야함
  3.  NVIDIA의 Jetson TX1/TX2  (Tensorflow 및 TensorRT 지원)
  4.  Zynq (Xilinx Soc)  JetsonTX2 와 비교해봐야함 
  5.  Google기반의 TPU가 지원가능한 SoC가 나올 경우 관련 SoC 검색
  6.  Qualcomm도 DSP 기반으로 상위 플랫폼지원을 한다고 하는데, 추후 검색

4/22/2018

Raspberry-Pi3 관련프로젝트 및 OpenOCD 자료수집

1. Raspberry  Pi3 의 Projects 

Smart Mirror or Magic Mirror라고 불리우는 프로젝트로 라지베리파이를 이용하여 음성인식을하여 
각각 사물을 제어하는 IoT 프로젝트이다. 

나도 한번 만들어보고 싶지만, LCD 패널과 관련부품이 돈이 너무 많이 들어갈꺼 같아 현재 고려만 하고 있다. 

  • Smart Mirror 관련사이트 
  http://blog.embian.com/120
  http://jeongchul.tistory.com/425
  http://mazdah.tistory.com/786
  https://www.magicmirrorcentral.com/complete-raspberry-pi-magic-mirror-tutorial/


  • Smart Mirror 중요동영상 (EASY SMART MIRROR SETUP)
  https://www.youtube.com/watch?v=pcmjht0Hqvw
  https://www.youtube.com/watch?v=wdaBi33nd3k
  https://www.youtube.com/watch?v=cVmDjJmcd2M



1.2 IoT를 구성할 때 필요한 API 를 비롯하여 Device들 

  • Open API 관련 정리
IoT를 구현하기 위해서 연결할  OpenAPI 부분
  http://freemoa-blog.com/639

이외 Smart Plug 기능 및 Google Home에 연결할 수 있는


2. 라즈베리파이에서 Ecplise에 연결하여 테스트 해볼 기능들 

가장 만만한 것이 손쉽게 가능한 것이 GDB Server를 이용하여 Remote Debug일 것이다.

  • Remote GDB 사용 (GDB Server)
  http://geomodule.com/sw-eng-notes/2017/03/25/raspberry-pi-debugging-with-gdb-command-line/


2.1 LTTng 사용방법 모색 

이 전에 TI Chip를 사용했을 때 CCS Linux Version LTTng기능을 지원 한 적이 있어 사용한 경험이 있는데, 라즈베리파이에서도 이를 한번 적용하여 사용해보고 싶다.
추후에 Ecplise에 연결해서 Trace compass의 LTTng를 이용하여 Kernel을 Trace를 한번 해보도록 하자

  • LTTng Tracer Download
LTTng 관련 Tool을 쉽게 Download 가능
  1. LTTng-modules (Linux Kernel 용 Module)
  2. LTTng-UST (User Space Tracer)
  3. LTTng-Tool 상위 두개를 지원하여 Trace하는 Tool 
  https://lttng.org/download/


  • Eclipse LTTng/SourceAnalyzer (Linux Trace Toolkit Next Generation)
Eclipse 기반으로 다양하게 사용되는 것을 확인가능하며 아래의 사이트에서 확인 

  • Eclipse LTTng Kernel Analysis
Eclipse에서 쉽게 추가 가능하며 아래와 같이 Tracecompass Manual 참고  
  http://archive.eclipse.org/tracecompass/doc/stable/org.eclipse.tracecompass.doc.user/LTTng-Kernel-Analysis.html

  • Ecplise 관련 Manual (LTTng)
  https://help.eclipse.org/luna/index.jsp?topic=%2Forg.eclipse.linuxtools.lttng.help%2Fdoc%2FInstallation.html



2.2 OpenOCD (On-Chip Debugger) 사용 방법 모색 

OpenOCD는 JTAG Interface를 통하여 Chip Level에서 Debugging을 하는 것이며, 이를 GDB로 연결하여 보통사용한다.
나의 경우는 주로 Ecpliise 기반의 IDE에서 사용한 것이며, Raspberry Pi3에서도 가능한지 한번 살펴 봐야할 것 같다.

  • OpenOCD란? 
  http://openocd.org/doc/html/About.html
  http://openocd.org/doc-release/README

  • OpenOCD Manual 
  http://openocd.org/doc/html/index.html#Top
  http://openocd.org/doc/html/OpenOCD-Concept-Index.html#OpenOCD-Concept-Index

가장 대표적일 것이 쉽게 사용하는 것이 ST사의 ST-Link 일 것 같다.


2.2.1 JTAG Interface의 변화 

우선 기존의 JTAG과 SWD를 간단히 이해해보도록 하자.
JTAG 설명은 너무많이 나오므로 아래사이트 참조하도록하자 


  • JTAG의 관련설명 
아래의 Wiki에서 쉽게 설명해주고 있어 구지 설명할 필요가 없음 
  https://en.wikipedia.org/wiki/JTAG
  https://ko.wikipedia.org/wiki/JTAG


  • JTAG의 기본구성
기본 구성은 Daisy-chained JTAG (IEEE 1149.1) 형식으로 아래와 같이 Chain 형식으로 연결되어 각 Device 에게 Read / Write를 할 수가 있다. 


https://en.wikipedia.org/wiki/JTAG
여기서 PIN의 기준은 TAP(Test Access Port), Device1,2,3 기준이므로 Pin의 in/out이 달라지므로 혼동하지 말자.

  1. TDI (Test Data In): JTAG의 Output으로 TMS에 따라 command/Data가 결정 
  2. TDO (Test Data Out): JTAG의 Input으로 Device의 Address/Data가 결정 
  3. TCK (Test Clock): JTAG의 Output Clock
  4. TMS (Test Mode Select):  JTAG의 Output TEST Mode 전환 
  5. TRST (Test Reset) optional): 사용은 옵션 JTAG의 Output 

JTAG PIN 

  https://www.electronics-notes.com/articles/test-methods/boundary-scan-jtag-ieee1149/jtag-interface-tap-test-access-port-connector.php

TAP(Test Access Port)의 상태 
  https://en.wikipedia.org/wiki/JTAG#JTAG_facilities


JTAG의 동작방식은 간단하며, TAP의 상태에 따라 TDI에 명령어와 Data를 넣어 TDO로 결과를 가져오는 방식이다.


  • Boundary Scan
JTAG 입장에서 보면 TMS/TCK/TDI에 결정이 되고 , TDO로 결과값을 보는 형식



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

  • JTAG 와 SWD
STM의 ST-Linkv2를 사용하다 보면 JTAG or SWD(Serial Wired Debug)로 선택을 해서 사용한다.
SWD(Serial Wired Debug)로 JTAG의 축소판으로 Pin으로 최소 아래의 3PIN이 필수이며, JTAG Pin과 Match되는 부분은 아래와 같다.

  1. SWCLK(Serial Wire Clock): TCLK
  2. SWDIO(Serial Wire debug Data Input/Output): TMS
  3. SWO(Serial Wire trace Output): TDO

JTAG 과 SWD의 일반적인 Match 일뿐이지 SWDIO와 TMS는 동일하지 않으며, SWDIO는 Input/Output로 사용한다.
JTAG과 SWD 유사할 뿐이지 동작은 조금 다르며, TAP(Test Access Port) 대신 DAP(Debug Access Port)를 용어를 사용하지만, 내부적으로 보면 거의 유사
세부내용
  https://research.kudelskisecurity.com/2019/05/16/swd-arms-alternative-to-jtag/


  • TRACE32의 정보 (JTAG/SWD)
  http://www.trace32.com/archive/view.php?mnu=5&no=48&board=newsletter&uid=840&cp=1&field=&keyword=


  • JTAG과 SWD 차이 
  http://forum.falinux.com/zbxe/?document_srl=796669&mid=lecture_tip&order_type=asc&sort_index=readed_count


2.2.2 OpenOCD 에 사용되는 Hardware 

  • USB기반의 다양한 JTAG Interface가 이를 사용
  1. USB FT2232: USB To Serail로만 사용하는줄 알았는데, USB To JTAG로 가능 
  2. USB J-Link
  3. USB RLINK 
  4. USB ST-LINK
  5. 나머지들 아래참고 
  http://openocd.org/doc/html/Debug-Adapter-Hardware.html#Debug-Adapter-Hardware


  • FT2232 기반의 USB JTAG
  https://nexp.tistory.com/86
  https://www.ftdichip.com/Products/ICs/FT2232D.htm


2.2.3  Raspberry Pi3 의 연결 JTAG 연결방법

현재 생각으로 값싼 ST-Linkv2로 SWD가 지원을 하니, 이를 연결을 해볼 생각이다.
아래와 같이 나와 비슷한 생각을 한 사람이 있어 다행이지만, 테스트를 해보자.

  https://spin.atomicobject.com/2014/04/01/ethernet-adapter-jtag/

  • Raspberry PI3 JTAG Interface (Pin을 확인)
  https://movr0.com/2016/09/02/use-raspberry-pi-23-as-a-jtagswd-adapter/


2.2.4  OpenOCD를 GDB에 연결 

주로 Ecplise기반의 GDB에서 연결하여 사용을하고 있기 때문에 이 부분은 먼저 JTAG 부분먼저 확인을 하고 진행하자

  • STM를 사용할때 ST-Link를 이용하여 OpenOCD에서 GDB연결 
  https://m.blog.naver.com/PostView.nhn?blogId=abby21&logNo=80208277200&proxyReferer=https%3A%2F%2Fwww.google.com%2F


GDB 와 OpenOCD 를 연결하여 IDE에서 많이 Debug를 하고 있으며 대표적인 것이 ST-Link를 이용하는 것일 것 이다.
일단 하고 나의 라즈베리파이에서 OpenOCD를 적용하여 테스트를 진행하도록 하겠다.

Eclipse ARM OpenOCD Plug
  https://gnu-mcu-eclipse.github.io/
  https://gnu-mcu-eclipse.github.io/debug/
  https://gnu-mcu-eclipse.github.io/openocd/
  http://openocd.org/

4/19/2018

Raspberry-Pi3 HDMI 관련 설정

일단 RASPBIAN OS를 설치한 후 /boot로 가서 설정들을 확인하자.
쉽게 설정하고자 한다면,

$ sudo raspi-config // 각 설정  



  • *.dtb : device tree
  • cmdline.txt : kernel command line 쉽게 변경 가능
  • config.txt :  raspberry pi 설정


$ cd /boot/ 
bcm2708-rpi-0-w.dtb     bcm2708-rpi-cm.dtb   bcm2710-rpi-3-b-plus.dtb  cmdline.txt    fixup_cd.dat  fixup_x.dat  kernel.img        overlays      start.elf
bcm2708-rpi-b.dtb       bcm2709-rpi-2-b.dtb  bcm2710-rpi-cm3.dtb       config.txt     fixup.dat     issue.txt    LICENCE.broadcom  start_cd.elf  start_x.elf
bcm2708-rpi-b-plus.dtb  bcm2710-rpi-3-b.dtb  bootcode.bin              COPYING.linux  fixup_db.dat  kernel7.img  LICENSE.oracle    start_db.elf


  • HDMI config.txt 설정 방법 

  https://wikidocs.net/7826
  https://wikidocs.net/3198



리모콘 기능을 위해서 아래와 같이 CEC관련 자료 수집

  • Raspberry PI Turn On HDMI CEC
  https://timleland.com/raspberry-pi-turn-tv-onoff-cec/
  https://www.youtube.com/watch?v=Z-KaPnAGPNQ


4/08/2018

Flat Field Correction (FFC)

1. Flat Field Correction (FFC) 

저조도 관련일을 하다가 우연히 알게된 기능으로 이것에 관해 공부해야 하기에 아래와 같이 정리한다.
다행히 인터넷에 감사하게 정리를 많이 해줘서 쉽게 이해가 가능하다.

FPN (Fixed Pattern Noise Correction)
  https://laonple.blog.me/220808623891
  http://blog.envision.co.kr/19

1.1 발생원인 

이 Noise의 발생되는 주요 원인을 보면 아래와 같다고 한다.

  1. 렌즈의 그림자 영향 
  2. 각 화소감도 차이
  3. 센서의 먼지로 인한 영향 

조명의 밝기의 불균일도 있다고 하는데, 그부분은 잘 모르겠다.
영상을 보면 Fixed Noise 유지한채 영상이 겹쳐보이는 현상으로 보인다.
현재 나의 경우는 먼지 처럼 모두가 점으로 보이는 현상이 보인다.

1.2 FFC 하는 방법 

일단 아래의 글들을 읽어보면 렌즈가 닫혔을 때,  Dark 상태에서 모든 화소의 Offset을 동일하게 맞추는 것이다.

이때 나의 경우는 일반 카메라가 아니 였기에, 아래와 같이 중간치를  얻어 아래와 같이 구하여 이를 기준으로 보정을 하도록 하였다.

FFC의 알고리즘
  https://en.wikipedia.org/wiki/Flat-field_correction
  https://thamescorp.wordpress.com/2016/10/31/%ED%94%8C%EB%9E%AB%ED%95%84%EB%93%9C%EC%BD%94%EB%A0%89%EC%85%98flat-field-correction/

FLIR의 관련내용
  http://www.flirkorea.com/cs/display/?id=61151


4/07/2018

Linker script

1. Linker Script 란? 

Linker Script or Linker Command 라고 불리우며, Compiler에 따라 이 이름은 달라질 수 있다.
기능은 Linker에게 Command/Script로 명령을 주어 관련 Program을 환경설정을 변경하는 것이 주목적이다

일반 애플리케이션 사용자는 사용할 일은 거의 없을 것이라고 생각되며, Kernel / Uboot 같은 소스를 수정하는 사람들이 주로 사용하지만 
요즘은 거의 사용할 일은 없다.
예를 들면, 주로 수정하여 고친다면, Interrupt Service Routine 을 새로 만들어서 SRAM에 올리거나, 
특정 Program 안에, 특정 Address 에 특정 Section을 만들어 할당하거나, 
나만의 Section을 만들어 특정 Address 할당 하는데 주로 사용한다. (ROM/RAM/SRAM)


1.1. Linker Script 기본 Manual

일반적으로 컴파일러는 자동으로 Linker Script를 생성해서 만들어주므로, 크게 신경을 쓰지 않아도 된다. 
하지만, 일반적으로 OS / Boot Loader 및 MCU 기반의 Compiler들은 ELF format을 직접이용하기보다는 특정영역에 확보하고 사용해야하는 프로그램은
관련 세부설정 부분들을 직접정의하고 각 소스에 이를 설정하여 연결한다.

주로확장자는 .ld or lds로 되어있지만, 컴파일러마다 조금씩 다를수 있으며, 이 파일들을 찾아 아래 메뉴얼들과 같이 보며 
기본동작 방식을 이해하면 될 것 같다.
항상 세부적인것은 현재 사용중인 컴파일러 메뉴얼기반으로 봐야함



SECTIONS
{
  . = 0x10000;
  .text : { *(.text) }
  . = 0x8000000;
  .data : { *(.data) }
  .bss : { *(.bss) }
}

  • 상위 SECTIONS 구성
  1. .text: code의 영역
  2. .data: 초기화된 전역변수 or static 변수
  3. .bss : 비초기화된 전역변수 or static 변수
  4. heap: bss 다음으로 연결되어지며, malloc/calloc과 연결 
  5. .noinit: init를 하지 않는 전역변수   
heap은 동적 Memory 저장하며, 일반적으로 stack은 함수호출 및 일반변수의 저장을 담당하며, heap기반으로 구성 
  https://en.wikipedia.org/wiki/Data_segment
  

1.2  GCC의 MACRO attribute

GCC Compiler의 MACRO인 attribute 설정과 Linker Script 밀접한 관계에 있으며, 이는 곳 특정영역에 넣는 것이 가능하다. 
예를드면,  C/C++ Code에 MACRO인 attribute를 설정하여 Linker script와 연결하여 동작가능하다.
이는 GCC 뿐만 아니라 다른 Compiler라도 사용방법은 얼추 비슷하며, Linker Script의 이름은 변경될 수가 있다. (TI Compiler는 Linker Command)
이외 Compiler 전용 MACRO가 있으므로, 그 부분은 각 Complier Manual 참조 

Attribute는 Function 과 Variable 에 사용될 수 있으며, 각각 설정방법은 Manual을 보자.

  • GCC Manual Index
GCC 전체 Manual 에 Index 기능으로 쉽게 보고자하는 파트를 찾을수 있다.
  https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/

  • MACRO  __attribute__
__attribute__로 Section을 설정하여, 함수(Function)과 변수(variable)를 Linker Script의 특정 Section에 할당가능하다. 
Function에 속성을 설정하여 Linker Script와 같이 연동하여 특정영역에 놓을 수도 있으며, 할당크기 및 다양한 설정이 가능하다
Variable , 즉 변수도 Linker Script와 같이 연동하여 특정영역뿐만 아니라 다양한 속성설정이 가능하다.
e.g. __atrribute__(section)
  https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Function-Attributes.html#Function-Attributes
  https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Variable-Attributes.html#Variable-Attributes


  • MACRO #pragmas
  https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Pragmas.html#Pragmas
  https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/ARM-Pragmas.html#ARM-Pragmas



1.3 Kernel Linker Script 분석예제

Uboot/Kernel의 Linker Script를 분석들을 기본적으로 보고 이해를 하면될 것이고 더나아가 ISR 수정하거나, 변경한다면, 관련부분 전용 Linker Script 수정하면 될거 같다.

$ find . -name *.lds
$ vi kernel/arch/arm/boot/compressed/vmlinux.lds
$ vi kernel/arch/arm/kernel/vmlinux.lds

Linker Script 및 Kernel에 자료는 인터넷에 풍부하므로, 정리하지 않고, Link만 연결


  • Makefile 과 Kernel Linker Script 분석
Makefile 과 Linker Script는 밀접하게 연관되어 있으며, 우선적으로 Makefile부터 분석해야, 현재 사용중인 Linker Script도 확인가능 
  https://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/arm.makefile.html

  • Kernel Linker Script 분석한 Blog들
Kernel Linker Script를 보면, 다양한 Section들이 나오며, 각 Section 의미를 알아보고 분석하자.
본인이 원하는 새로운 Section에 새로운 이름으로 만들어 추가도 가능하다. 
아래보기전에, Linker Script Manual부터 확인 
LDFLAGS 와 각 CONFIG기반의 Address 와 소스확인 
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/Makefile

ARM Kernel Image
build 후에는 System.map기반으로 확인하고, boot 관련부분을 확인 
반드시 Kernel CONFIG와 같이 확인
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/boot
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/boot/compressed/Makefile
MMU/SMP/XIP/TCM 등 각 설정기반의 설정확인 
  http://elixir.free-electrons.com/linux/v3.19.7/source/arch/arm/boot/compressed/vmlinux.lds.S

ARM Kernel Vmlinux
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/kernel
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/kernel/Makefile
  http://elixir.free-electrons.com/linux/v3.19.7/source/arch/arm/kernel/vmlinux.lds.S

빌드후, 아래와 같이 arch/arm/kernel/vmlinux.lds 생성

ARM IRQ 관련 부분
  http://elixir.free-electrons.com/linux/v3.19.7/source/arch/arm/kernel/irq.c
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/include/asm/exception.h#L14
  http://elixir.free-electrons.com/linux/v3.19.7/source/arch/arm/kernel/fiq.c

IRQENTRY_TEST
  https://elixir.bootlin.com/linux/v3.19.7/source/arch/arm/kernel/vmlinux.lds.S
  https://elixir.bootlin.com/linux/v3.19.7/source/include/asm-generic/vmlinux.lds.h#L440


  • ARM의 IRQ 부분 
관련된 소스를 간단하게 역추적하면서 어떻게 사용하는 지 분석해보자.

---------------------------arch/arm/kernel/irq.c
asmlinkage void __exception_irq_entry       // Exception 영역으로 
asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
 handle_IRQ(irq, regs);
}
---------------------------arch/arm/include/asm/exception.h
#define __exception __attribute__((section(".exception.text")))  // GCC attribute 관련부분 참조 
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#define __exception_irq_entry __irq_entry
#else
#define __exception_irq_entry __exception
#endif
 
---------------------------include/asm-generic/vmlinux.lds.h

#ifdef CONFIG_FUNCTION_GRAPH_TRACER   // CONFIG가 존재하면 사용함 
#define IRQENTRY_TEXT       \
  ALIGN_FUNCTION();     \
  VMLINUX_SYMBOL(__irqentry_text_start) = .;  \
  *(.irqentry.text)     \
  VMLINUX_SYMBOL(__irqentry_text_end) = .;
#else
#define IRQENTRY_TEXT
#endif

---------------------------arch/arm/kernel/vmlinux.lds.S

.text : {   /* Real text segment  */
  _stext = .;  /* Text and read-only data */
   __exception_text_start = .;
   *(.exception.text)         // 상위 exception 영역 
   __exception_text_end = .;
   IRQENTRY_TEXT      // header file define 되어있음 
   TEXT_TEXT
   SCHED_TEXT
   LOCK_TEXT
   KPROBES_TEXT
   IDMAP_TEXT
#ifdef CONFIG_MMU
   *(.fixup)
#endif
   *(.gnu.warning)
   *(.glue_7)
   *(.glue_7t)
  . = ALIGN(4);
  *(.got)   /* Global offset table  */
   ARM_CPU_KEEP(PROC_INFO)
 }


asmlikage 의 의미 
  http://egloos.zum.com/studyfoss/v/4951809

  • ARM9에서 많이 사용했던 TCM 관련부분 
ARM9에서 TCM(Tightly Coupled Memory)는 주로 SRAM용도로 사용하며, 아래와 같이 ITCM(Instruction)/DTCM(Data)으로 분리하여 사용한다.
ARM9뿐만아니라, Cortex에서도 사용되며, 예를 들면, Deep Sleep용 ISR 기능 뿐만아니라, 다양한 빠른 Latency 목적으로 사용가능하다고 한다.
 
#ifdef CONFIG_HAVE_TCM
 /*
  * We align everything to a page boundary so we can
  * free it after init has commenced and TCM contents have
  * been copied to its destination.
  */
 .tcm_start : {  //.tcm_start는 Instruction으로 시작
  . = ALIGN(PAGE_SIZE);              //PAGE SIZE 할당
  __tcm_start = .;            //__tcm_start  : . 현재 Address 할당 
  __itcm_start = .;                  //__itcm_start : . 현재 Address 할당 (아래참고)   
 }

 /*
  * Link these to the ITCM RAM
  * Put VMA to the TCM address and LMA to the common RAM
  * and we'll upload the contents from RAM to TCM and free
  * the used RAM after that.
  */
 .text_itcm ITCM_OFFSET : AT(__itcm_start)   // AT(ADDRESS)이므로, .text_itcm을 __itcm_start로 연결
 {
  __sitcm_text = .;    // Start ITCM TEXT 
  *(.tcm.text)         // ITCM TEXT로 Instruction  
  *(.tcm.rodata)
  . = ALIGN(4);        // ALIGN 2의 지수로만 할당(공백할당) 
  __eitcm_text = .;    // End ITCM TEXT 
 }

 /*
  * Reset the dot pointer, this is needed to create the
  * relative __dtcm_start below (to be used as extern in code).
  */
 . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm);  // 현재 Address를 변경 사이즈기반 

 .dtcm_start : {   // .tcm_start 뒤에 .dtcm_start 구성 (현재 Address 할당) 
  __dtcm_start = .;
 }

 /* TODO: add remainder of ITCM as well, that can be used for data! */
 .data_dtcm DTCM_OFFSET : AT(__dtcm_start)  // AT(ADDRESS)이므로, .data_dtcm을 __dtcm_start 연결
 {
  . = ALIGN(4);       // 공백할당 2의 지수로만 가능 
  __sdtcm_data = .;   // Start DTCM Data 
  *(.tcm.data)       // TCM Data 
  . = ALIGN(4);
  __edtcm_data = .;  // End DTCM Data  
 }

 /* Reset the dot pointer or the linker gets confused */
 . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm);  // 사이즈 측정하여 현재 Address 변경 

 /* End marker for freeing TCM copy in linked object */
 .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){  // .tcm_end에 itcm 과 dtcm 끝나는 곳으로 설정 
  . = ALIGN(PAGE_SIZE);
  __tcm_end = .;
 }
#endif



  • Davinci Deep Sleep Source (TCM이용)
오래전에, 이것때문에 TI에서 교육을 받은 적이 있는데, 이렇게 오픈되어있다니 좋다 
소스의 내용은 Sleep할때는 DRAM을 Self Refresh로 변경하여 Deep Sleep으로 가며, 
깨어날때는 DRAM을 사용할 수 없으니, TCM기반의 ISR로 SDRAM 설정변경해주는고 원래대로 돌아가는 방식 
  https://www.mail-archive.com/davinci-linux-open-source@linux.davincidsp.com/msg04407.html

  • setup_irq
  http://elixir.free-electrons.com/linux/v3.19.7/source/kernel/irq
  http://elixir.free-electrons.com/linux/v3.19.7/source/kernel/irq/manage.c
  http://elixir.free-electrons.com/linux/v3.19.7/ident/setup_irq

  • request_irq
  http://elixir.free-electrons.com/linux/v3.19.7/ident/request_irq
  http://elixir.free-electrons.com/linux/v3.19.7/source/include/linux/interrupt.h#L128
  https://free-electrons.com/docs/

  • IRQ Proc 정보 등록
  http://elixir.free-electrons.com/linux/v3.19.7/source/kernel/irq/proc.c



2. 특정 Address에 원하는 Data 넣기 

variable attribute 와 Linker script를 이용하여, 본인이 원하는 위치에 데이타를 저장이 가능하다.


  • 저장할 Data를 Code에 Variable Attribute를 이용하여 Section 선언
 unsigned char data[48]  __attribute__((section(".mySection")))  = {0}; 


  • Variable Attribute 와 같이 Linker Script 수정 
Linker Script에서 관련 Section에 0x80200000 에 위치하도록 설정하고 KEEP를 사용하자.

SECTIONS    //SECTIONS Command로 나만의 Region 만들고 이를 Memory 내에 구성된 이름에 할당 
{
  .mySegment 0x80200000 : 
  {
     KEEP(*(.mySection))
  } 
}

SECTIONS Command 
  http://korea.gnu.org/manual/release/ld/ld-mahajjh/ld_3.html#SEC18

  • MPU의 예제구성 
MPU의 경우는 아래와 같이 MEMORY Layout이 정의되어있으므로, 이 부분 확인 

MEMORY           //MEMORY Command기반으로 각 Segment/Name 정의 (주소,길이,RWX) 
{
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K           // RAM Segment (Read and Write and Excute) 
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 64K        // FLASH Segment (Read and Excute) 
}

SECTIONS
{
  .... // 다른 Segment로 구성하고 나의 영역만들고, 이를 FLASH Segment/Name 할당해서 연결 
  .mySegment 0x80200000 : 
  {
     KEEP(*(.mySection))                // 상위소스에서  __attribute__를 이용하여 이곳에 할당 
  } >FLASH 
} 

MEMORY Command

상위내용
  https://stackoverflow.com/questions/4067811/how-to-place-a-variable-at-a-given-absolute-address-in-memory-with-gcc