'분류 전체보기'에 해당되는 글 260건

  1. 2009.12.24 STM32 Memory Map 1
  2. 2009.12.21 초급 - 비기너 턴, 나비스 턴, 연결된 나비스 턴
  3. 2009.12.21 초급 - 사이드 슬리핑, 펜듈럼, 트래버싱, 갈란드
  4. 2009.12.21 초급 - 장비소개, 착용, 리프트 이용하기
  5. 2009.12.18 connect()
  6. 2009.12.17 펜더, 신중현 트리뷰트 기타 헌정
  7. 2009.12.16 listen() and accept()
  8. 2009.12.15 bind()
  9. 2009.12.15 socket()
  10. 2009.12.12 diff and patch in linux
2009. 12. 24. 14:16

STM32 Memory Map



STM32는 총 4G의 메모리 공간을 갖고, 각각은 512 MB로 된 8개의 블록으로 이루어져 있다.

다음은 4G의 메모리 영역이 각각 어떻게 사용되고 있는지를 보여준다.

코드 영역(0x00000000 ~ 0x1FFFFFFF)은 I-Code bus와 D-Code bus를 사용해 명령어 패치와 데이터 접근을 수행한다.
코드 영역은 프로그램 코드를 실행할 수 있고, 데이터를 저장 할 수 도 있는 영역으로 사용된다. 이 영역에서 캐시 속성은 WT(Write Through)인 쓰기 버퍼 영역이다. 이 곳은 on-chip Flahs memory 가 사용되고 있으며, 현재 본인이 사용하고 있는 보드에는 32KBytes 크기의 Flash memory가 장착되어 있다.
일반적으로 프로그램 코드는  이 코드 영역, SRAM 영역, 또는 외부 RAM(External RAM)영역에 위치할 수 있는데, 일반적으로 코드 영역에 위치시키면 두 개의 분리된 버스 인터페이스(I-Code, D-Code)를 통해 명령어 페치와 데이터 접근을 동시에 수행할 수 있어 좋다고 한다.

SRAM 메모리 영역(0x20000000 ~ 0x3FFFFFFF) 내부 SRAM과 연결하기 위해 존재한다.
이 영역은 쓰기 버퍼 영역이고, 캐시 속성은 WB-WA(Write Back, Write Allocated)이다. 프로그램 코드는 코드 영역과 마찬가지로 SRAM 영역에서도 실행 될 수 있다. 하지만, 코드 영역에서 실행하는 것보다는 느리다고 한다. 그래서, 프로그램 실행코드는 코드 영역에 위치시키고 실행시키기를 권고(?)한다.
이 영역은 on-chip RAM을 사용하기 위한 공간이고 현재 사용하고 있는 보드에는 10 KBytes SRAM이 장착되어 있다. 이 영역은 System bus(시스템 버스)를 통해 접근을 하게 된다. 이 영역에는 32 MB의 Bit Band Alias 영역이 존재한다. Bit Banding에 관한 내용은 여기를 참고하면 될 듯 하다.

주변장치(Peripheral) 영역(0x40000000 ~ 0x5FFFFFFF)은 시스템에 장착되어 있는 주변장치(RTC, I2C, ADC, GPIO, USART 등) 에 대해 접근을 하는 용도로 사용된다. ARM의 경우, 이 영역에 데이터를 쓰고 읽는 방법을 통해 장치를 제어할 수 있다. 예를 들어 LED를 켤 때에는 LED 장치가 물려 있는 GPIO의 핀에 1 혹은 0의 값을 쓰는 것을 통해 LDE를 끄고 켤 수 있다. 이 영역 또한 SRAM 메모리 영역과 마찬가지로 32 MB 의 Bit Band Alias 영역이 존재한다. 주변정치 영역은 System bus(시스템 버스)를 통해 접근을 하게 된다.
이 영역은 캐시 불가능 영역이고, 명령어 코드를 실행할 수 없다(Excute Never).

외부 RAM(External RAM) 영역(0x60000000 ~0x9FFFFFFF)은 외부 RAM을 위해 할당된 1G의 메모리 영역이다.
이 영역 중(0x60000000 ~ 0x7FFFFFFF)은 이 영역은 on-chip 또는 off-chip 메모리를 위한 공간이다. 캐시가능 영역(WB-WA)이고, 코드를 실행할 수 있다.
나머지 영역(0x80000000 ~ 0x9FFFFFFF)은 on-chip 또는 off-chip 메모리를 위한 공간이다. 캐시가능 영역(WT) 이고, 이 영역에서는 코드를 실행할 수 있다.

외부 장치(External Device) 영역(0xA0000000 ~ 0xDFFFFFFF)은 외부 장치를 위해 할당된 1G의 메모리 공간이다. 이 영역은 순차적이면서 버퍼 기능이 없는 접근을 요구하는 외부 장치들과 공유 메모리를 위해 만들어졌다. 코드 실행 불가한 메모리 영역이다.

마지막 0.5 GB의 메모리 공간(0xE0000000 ~ 0xFFFFFFFF)은 시스템 레벨 컴포넌트들과 내부의 주변장치 버스들, 외부의 주변장치 버스, 그리고 벤더의 특화된 시스템 주변장치들을 위한 메모리 공간이다.
이 영역은 캐시/버퍼 불가능한 영역이고, 전용 주변장치 버스 메모리 범위하에서 순차적으로 접근이 이루어 진다.





'혼자서 놀기... > STM32' 카테고리의 다른 글

STM32 보드에 펌웨어 퓨징  (0) 2009.12.26
STM32 개발 환경  (0) 2009.12.26
Cortex-M3(STM32) System Architecture  (0) 2009.10.06
STM32F103C6T6  (0) 2009.10.05
Cortex M3 - Bit Banding  (0) 2009.09.29
2009. 12. 21. 12:47

초급 - 비기너 턴, 나비스 턴, 연결된 나비스 턴



다음 tv팟에서 가져온 스노우보드 초급 강좌..

1. 비기너 턴


2. 나비스 턴



다음 동영상에서 '스노우보드 강좌'를 검색하면 위의 강좌 동영상을 볼 수 있다.
동영상 만드신 분.. 동영상 게재에 문제가 되면 말씀해주세요... 삭제하겠습니다!!


2009. 12. 21. 12:37

초급 - 사이드 슬리핑, 펜듈럼, 트래버싱, 갈란드



다음 tv팟에서 가져온 스노우보드 초급 강좌..

1. 사이드 슬리핑


2. 펜듈럼


3. 트래버싱


4. 갈란드



다음 동영상에서 '스노우보드 강좌'를 검색하면 위의 강좌 동영상을 볼 수 있다.
동영상 만드신 분.. 동영상 게재에 문제가 되면 말씀해주세요... 삭제하겠습니다!!


2009. 12. 21. 10:33

초급 - 장비소개, 착용, 리프트 이용하기



다음 tv팟에서 가져온 스노우보드 초급 강좌..

1. 장비 소개


2. 장비 착용


3. 기본 자세


4. 베이직 모빌리티



다음 동영상에서 '스노우보드 강좌'를 검색하면 위의 강좌 동영상을 볼 수 있다.
동영상 만드신 분.. 동영상 게재에 문제가 되면 말씀해주세요... 삭제하겠습니다!!

2009. 12. 18. 09:30

connect()



TCP 기반의 클라이언트 프로그램의 구현순서는 간단하다
  1. 소켓 생성
  2. 연결 요청
  3. 데이터 송수신
  4. 연결 종료
TCP 기반의 서버 프로그램과 비교해 볼 때 소켓 생성, 데이터 송수신, 연결 종료는 공통되는 부분이고, 다른 부분은 단지 '연결 요청'이다.

서버 프로그램에서 연결 요청 대기를 하고 있을 때 비로소 클라이언트 프로그램에서는 연결 요청을 할 수 있는 것이다. 연결 요청은 'connect()' 함수를 사용한다.

#include <sys/types.h>
#include <sys/socket.h>

int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);

  • sockfd - 통신을 위해 생성한 소켓의 파일 디스크립터
  • serv_addr - 연결 요청을 할 서버의 주소정보를 가진 구조체 변수의 포인터
  • addrlen - 연결 요청을 할 서버의 주소정보를 가진 구조체 변수의 크기

connect() 예제
...
int sock;
struct sockaddr_in serv_addr;
...
// 클라이언트 소켓 생성
sock = socket(PF_INET, SOCK_STREAM, 0);       
...
// connect()로 연결 요청
if(connect(sock, (struct sockaddr* ) &serv_addr, sizeof(serv_addr)) == -1)
...








'Programmings > TCP/IP socket programming' 카테고리의 다른 글

listen() and accept()  (0) 2009.12.16
bind()  (0) 2009.12.15
socket()  (0) 2009.12.15
2009. 12. 17. 12:59

펜더, 신중현 트리뷰트 기타 헌정



한국 기타리스트의 최고봉이신 '신중현' 선생님.. 드디어 세계적인 기타리스트의 반열에 오르신듯 합니다.

지난 16일 세계적인 기타회사인 '펜더(Fender)'에서 신중현 커스텀을 제작해 헌정하는 식이 있었습니다.
펜더에서 직접 커스텀을 제작해 헌정한 사례는 여태껏 '에릭 클랩튼', '제프 벡', '잉베이 맘스틴', '스티비 레이 본', '에디 반 헤일런' 이렇게 다섯명 밖에는 없었다고 합니다. 하지만 이번에 신중현 선생님이 펜더로 부터 커스텀 기타를 헌정 받음으로 이제 여섯명이 되는 것입니다.
또한 아시아 인으로 펜더로 부터 기타를 헌정받은 사례는 처음이라 더욱 뜻 깊다 할 수 있습니다.

신중현 선생님 펜더 기타 헌정 기사
http://media.daum.net/entertain/others/view.html?cateid=100030&newsid=20091215210615450&p=sbsi

국내의 많은 기타리스틀이 참석을 해서 축하해주는 모습을 보니, 50여년 동안 음악을 하시면서 참 많은 후배들에게 존경의 대상이셨구나 하는 생각이 들었습니다. 저 또한 왠지 모르게 기분이 막 업되고, 뿌듯하고, 자랑스럽고 합니다.

전 세계에 수많은 기타리스트가 있습니다.
그리고 개중에는 날고 긴다는 분들도 많이 있습니다.
하지만 누구에게나 이런 영광이 주어지는 것은 아닐 것입니다.
한국의 음악이 또 한국의 음악을 연주하는 사람이 이제는 세계에 내 놓아도 손색이 없음을 보여주는 것 같습니다.

한없이 자랑스러운 신중현 선생님, 앞으로도 기타를 잡으시는 그 순간까지 선생님의 열정을 기대해 봅니다.

2009. 12. 16. 09:30

listen() and accept()



socket() 함수를 통해 통신을 위한 소켓을 생성하고, bind() 함수를 통해 소켓에 주소를 할당 한 다음 해야할 일은 어디선가로 부터의 통신 연결 요청에 대해 대기하고 있어야 한다.
이 때 연결 요청 대기상태로 만들어주는 함수가 'listen()' 함수이다.

#include <sys/types.h>

int listen (int s, int backlog);

s - 연결 요청을 받아들일 소켓의 파일 디스크립터(서버 소켓)
backlog - 연결 요청 대기 큐의 크기
리턴값 - 성공 시 0, 실패 시 -1을 리턴

listen() 함수는 SOCK_STREAM과 SOCK_SEQPACKET 에만 사용된다.


실제 네트워크 상에서 소켓을 이용한 통신이 이루어지는 순서를 보자.

'서버측'의 프로그램은 socket() 함수를 통해 통신을 위한 소켓을 하나 생성한다. 이는 클라이언트의 연결을 받아들이기 위한 용도로 사용된다. 주소정보를 sockaddr_in 구조체에 채워 넣은 후 bind() 함수를 사용해 소켓에 서버측 프로그램의 주소정보를 할당한다. 그리고 클라이언트의 연결 요청이 있기 전까지 서버측의 프로그램은 listen() 함수를 통해 응답 요청에 대한 대기상태로 들어간다.

'클라이언트측'의 프로그램은 socket() 함수를 통해 통신을 위한 소켓을 생성하고, connect() 함수를 통해 서버측 프로그램에 연결을 요청한다. 이러한 클라이언트 프로그램의 요청에 대해 서버측 프로그램은 backlog 크기의 연결 요청 대기 큐에 클라이언트측 프로그램의 요청을 밀어넣고, accept() 함수를 사용하여 클라이언트측 프로그램과 연결을 하고 통신을 하게 된다.
backlog는 최대 접속할 수 있는 클라이언트의 수를 의미한다. backlog를 5로 설정했을 때 연결 요청 대기 큐에는 5개 까지의 클라이언트 프로그램의 요청이 들어갈 수 있다.

이때 서버측 프로그램은 새로이 소켓을 하나 생성하게 된다.
처음 만들어진 소켓은 통신을 위해 클라이언트 측의 요청을 대기하기 위한 용도의 소켓이고, accept() 시 생성되는 소켓은 클라이언트와 실제 데이터를 주고 받는 통신을 하기 위해 사용되는 용도의 소켓이다.

다음은 'accept()' 함수의 프로토타입이다.

#include <sys/types.h>
#include <sys/socket.h>

int accept (int s, struct sockaddr *addr, int *addrlen);

s - 연결 요청을 받아들일 소켓의 파일 디스크립터(서버 소켓)
addr - 연결 요청을 수락할 클라이언트측 프로그램의 주소정보를 가진 변수의 포인터
addrlen - 두번째 인자 addr 포인터가 가리키는 구조체의 크기
리턴값 - 성공 시 클라이언트와 데이터를 주고받기 위해 사용될 소켓의 파일 디스크립터, 실패 시 -1

accept() 함수는 연결지향 소켓타입 (SOCK_STREAM, SOCK_SEQPACKET, SOCK_RDM)에 사용된다.

'Programmings > TCP/IP socket programming' 카테고리의 다른 글

connect()  (0) 2009.12.18
bind()  (0) 2009.12.15
socket()  (0) 2009.12.15
2009. 12. 15. 10:30

bind()



통신을 위한 소켓을 생성하고나면, 소켓에 주소를 할당해야 한다. 이때 사용하는 함수가 'bind()' 이다.

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);

  • sockfd - 주소를 할당하고자 하는 소켓의 파일 디스크립터
  • myaddr - 할당하고자 하는 주소정보를 가지고 있는 구조체 변수의 포인터
  • addrlen - 인자로 전달되는 주소정보 구조체의 길이
  • 리턴값 - 성공 시 0, 실패 시 -1 을 리턴

두 번째 인자 myaddr는 struct sockaddr* 형이지만, 실제는 sockaddr_in을 형변환 한 것이다.
sockaddr_in을 살펴보면...

struct sockaddr_in {
    sa_family_t     sin_family;        // 소켓 타입
    uint16_t           sin_port;          // 연결에 사용되는 포트 번호
    struct in_addr  sin_addr;         // 연결을 받아들일 주소
    char               sin_zero[8];    // 사용되지 않음
}

struct in_addr {
    uint32_t    s_addr;                  // IPv4 인터넷 주소
}


소켓 생성을 해서 소켓에 주소를 할당하는 bind() 까지의 예

...   
int serv_sock;
char *serv_ip = "127.0.0.1";
char *serv_port = "9190";
struct sockaddr_in serv_addr;

serv_sock = socket(PF_INET, SOCK_STREAM, 0);        /* 소켓 생성 */
if(serv_sock == -1)
// error 처리..
 
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;                               // 소켓 타입
serv_addr.sin_addr.s_addr = inet_addr(serv_ip);         // IP 주소
serv_addr.sin_port = htons(atoi(serv_port));               // 포트 번호 

if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)     /* 소켓에 주소 할당 */
// error 처리..
...


추가 #1.
소켓에 사용되는 모든 데이터는 Big Endian으로 동작한다. 일반적으로 사용하는 기계가 Little Endian 인경우가 대부분이고, 혹시나 모르기 때문에 소켓에 사용되는 데이터(IP 주소, 포트 번호 등)은 네트워크 바이트 순서(Big Endian)으로 변경해 주어야 한다.
이 때 사용되는 함수가 htons(), ntohs(), htonl(), ntohl() 이다.
h - host byte
n - network byte
l - long (32bit)
s - short (16bir)
htons()라고 한다면 short형의 host byte를 short형의 network byte로 변경해준다는 의미이다.
[참고] Endian에 대해서는 이곳을 참고!!!

추가 #2.
IP 주소를 보면 127.0.0.1 과 같은 형태인 것을 볼 수 있다. 하지만 실제 사용될 때에는 unsigned long 형으로 표현이 된다.
127.0.0.1 과 같은 형태를 'Dotted-Decimal Notation'이라고 부르며, 이는 위의 예제 소스에서 확인 할 수 있듯 문자열이다. 이를 unsigned long 형으로 바꾸어주는 함수가 'inet_addr()' 이다.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

unsigned long inet_addr (const char* string);


추가 #3.
위의 예제 소스를 보면 IP 주소를 직접 입력했다. 하지만 직접 IP 주소를 입력할 경우 다른 기계에서 동작을 할 수 없게 된다. 각 기계마다 IP 주소가 동일한 것이 아니기에...
이 때 'INADDR_ANY' 라는 상수를 통해서 현재 시스템의 IP를 자동으로 찾아서 할당해 주는 방법을 사용할 수 있다.

...   
char *serv_port = "9190";
struct sockaddr_in serv_addr;
...
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;                                         // 소켓 타입
serv_addr.sin_addr.s_addr = inet_addr(INADDR_ANY);         // IP 주소
serv_addr.sin_port = htons(atoi(serv_port));                          // 포트 번호 
...


 

'Programmings > TCP/IP socket programming' 카테고리의 다른 글

connect()  (0) 2009.12.18
listen() and accept()  (0) 2009.12.16
socket()  (0) 2009.12.15
2009. 12. 15. 10:02

socket()



통신을 하기 위해선 소켓을 생성해야 한다. 소켓은 통신을 위한 엔드포인트 정도로 생각하면 될 듯 하다.
소켓을 생성하기 위해서 socket() 이란 함수를 사용한다. socket()를 통해 시스템 내부적으론 소켓을 생성하고, 생성된 소켓을 조작하기 위한 파일 디스크립터를 리턴한다.

#include <sys/types.h>
#include <sys/socket.h>

int socket (int domain, int type, int protocol);

  • domain - 통신을 하기 위해 사용할 프로토콜 체계(Protocol Family)
  • type - 소켓에서 사용하게 될 데이터 전송 타입
  • protocol - 통신을 하기 위한 프로토콜
  • 리턴값 - 성공 시 int형 파일 디스크립터, 실패 시 -1 리턴

일반적으로 아래와 같이 TCP socket 또는 UDP socket 를 생성하여 사용하게 된다.
...
int tcp_sock, udp_sock;
tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
...

리턴값으로 파일 디스크립터를 받게 되는데, 리눅스에서 현재 사용하고 있는 디스크립터(0, 1, 2 이외의 )가 있다면 그 다음 숫자부터 차례로 디스크립더를 리턴받게 된다.

'Programmings > TCP/IP socket programming' 카테고리의 다른 글

connect()  (0) 2009.12.18
listen() and accept()  (0) 2009.12.16
bind()  (0) 2009.12.15
2009. 12. 12. 22:50

diff and patch in linux



'diff'는 두 파일간의 차이를 보여주는 프로그램이다.
원본 파일이 있고, 그 파일을 수정한 다른 파일이 있다면 그 파일간의 바뀐점이 무엇인지 알고 싶을 때 사용할 수 있다. 혹은 여러사람이 작업을 할 때 기존의 파일을 수정하였을 때 어떤 부분이 바뀌었는지도 확인 할 수 있다.

아래와 같이 diff 라면 명령어를 사용하여 확인 할 수 있다.
$ diff a파일 b파일

변화가 있는 부분을 파일로 저장하기 위해선..
$ diff a파일 b파일 > 파일.diff
혹은
$ diff -u a파일 b파일 > 파일.diff
을 사용할 수 있다.

diff 사용 예...
$ vi hello.c
#include <stdio.h>

void main()
{
    printf(hello);
}

$ vi hello2.c
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello \n");
    return 0;
}

$ diff -u hello.c hello2.c > hello.diff
$ cat hello.diff
--- hello.c 2009-12-12 21:46:38.000000000 +0900
+++ hello2.c    2009-12-12 21:48:32.000000000 +0900
@@ -1,6 +1,7 @@
#include <stdio.h>

-void main()
+int main(int argc, char **argv)
{
-    printf(hello);
+    printf("hello \n");
+    return 0;
}

디렉토리를 비교하려면,
$ diff -urN A디렉토리 B디렉토리


'patch' 는 diff 명령을 통해 만들어진 파일을 적용하는 명령이다.
위에서 작성한 hello.c 파일과 hello2.c 파일의 바뀐점이 diff 명령을 통해 hello.diff 파일에 적용되고, hello.diff 파일을 사용하여 hello.c파일을 hello2.c파일과 동일하게 패치 한다.
$ patch -p0 < hello.diff
위와 같이 패치를 하게 되면, hello.c 파일이 hello2.c 와 동일한 파일로 패치되어 있는 것을 확인할 수 있다.

patch 에서 'p0'라는 옵션이 있는데.. 이 옵션은 diff를 할 때 파일이 놓인 경로의 깊이를 나타내는 것으로 볼 수 있다. 위의 diff 명령은 동일한 디렉토리 내에서 파일을 diff 한 것이지만, 일반적으로 프로젝트를 하게 되면 동일한 디렉토리가 아닌 project1/ project2/ 와 같이 다른 디렉토리도 작업을 하게 될 것이다.
$ diff -urN project1/ project2/ > project.diff
$ cat project.diff
diff -urN project1/hello.c project2/hello.c
--- project1/hello.c
+++ project2/hello.c
...

$ cp project.diff project1/
$ cd project1
$ patch -p1 < project.diff

위처럼 경로명이 몇단계로 이루어지느냐에 따라 p0, p1, .. 을 결정 할 수 있게 된다.
경로명을  몇꺼풀 벗길 것인가.. 라는 얘기이다.
위의 예처럼 -p0 옵션을 사용하면, 한 꺼풀도 안벗기고 패치한다. 동일한 디렉토리위 내용을 패치한다고 할 수 있다.  위의 예와 같이 하면 -p1 옵션을 사용해서 패치하게 된다.