빅 엔디안 : 최상위 바이트 주소를 워드 주소로 사용하는 것

리틀 엔디안 : 최하위 바이트 주소를 워드 주소로 사용하는 것


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int main()
{
    int a = 0x12345678;
 
    char *= (char*)&a;
    printf("%x\n"*p);
    printf("%x\n"*(p + 1));
    printf("%x\n"*(p + 2));
    printf("%x\n"*(p + 3));
 
    return 0;
}
cs




1. 파일시스템 일반


파일시스템이 하드디스크에 저장하는 정보는 메타 데이터(meta data)와 사용자 데이터(user data)로 나뉜다.

메타 데이터: 파일이름, 파일의 생성시간, 실제 데이터 블록을 인덱싱 하기 위한 정보 등

사용자 데이터: 사용자가 실제로 기록하려던 내용


보통 파일시스템에서 디스크 블록의 크기는 4KB이다.



2. 디스크 구조와 블록 관리 기법



디스크는 원판(platter), 팔(arm), 헤드(head)로 구성된다.

원판에는 원 모양의 트랙(track)들이 존재하며, 모든 원판에서 같은 위치를 갖는 트랙들의 집합을 실린더(cylinder)라고 한다.


트랙은 다시 몇 개의 섹터(sector)로 구분된다. 섹터는 디스크에서 데이터를 읽거나 기록할 때 기본 단위이며, 일반적으로 512byte이다.


디스크에서 데이터를 접근하는 데 걸리는 시간은 탐색 시간(seek time), 회전 지연 시간(rotational latency), 데이터 전송 시간(transmission time)이라는 세 가지로 구성된다.


탐색시간: 헤드를 요청한 데이터가 존재하는 트랙 위치까지 이동하는데 걸리는 시간

회전시간: 요청한 섹터가 헤드 아래로 위치될 때까지 디스크원판을 회전시키는 데 걸리는 시간

데이터전송시간: 헤드가 섹터의 내용을 읽거나 또는 기록하는데 걸리는 시간



디스크 블록을 할당하는 방법에는 크게 연속(sequential)할당과 불연속(non-sequential)할당 두 가지 방법이 있다.


불연속 할당 방법: 디스크 블록들을 연속적으로 저장하지 않는다. 대신 파일에 속한 디스크 블록들이 어디에 위치하고 있는지에 대한 정보를 기록해 두어야 한다. 이를 위한 방법으로 블록체인 기법, 인덱스 블록 기법, FAT(File Allocation Table)기법 등이 있다.


블록체인 기법: 같은 파일에 속한 디스크 블록들을 체인으로(각 블록에 포인터를 두어 다음 블록 위치를 기록, linked list와 유사) 연결해 놓는 방법이다. lseek()같은 시스템 콜을 사용하여 파일의 끝 부분을 읽으려면 어쩔 수 없이 앞부분의 데이터 블록을 읽어야 하며, 중간 한 블록이 유실된 경우 나머지 데이터까지 모두 잃게 된다.


인덱스블록 기법: 



내부단편화

프로세스가 요청한 메모리보다 큰 메모리를 할당했을 경우에 내부단편화가 발생한다. 즉 실제로 요청한 메모리 보다 할당 단위가 커서 해당 단위 자원 내에서 사용하지 않는 부분이 있을 때 발생한다.


외부단편화

남아있는 메모리의 합에 비해서, 실제 할당 단위가 작아서 메모리를 사용할 수 없는 경우이다. 남은 파티션들이 연속되면 사용할 수 있지만, 그렇지 않으면 할당 단위가 작아서 프로세스가 올라갈 수 없는 형태를 말한다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;
 
int main()
{
    int num1 = 1020;        // 변수 선언
    int &num2 = num1;        // 참조자 선언
 
    num2 = 3047;
 
    cout << "Val: " << num1 << endl;        // 3047
    cout << "Ref: " << num2 << endl;        // 3047
 
    cout << "Val: " << &num1 << endl;
    cout << "Ref: " << &num2 << endl;        // &num1 과 &num2의 값은 같다
                                            
    int &num3 = num2;                        // 참조자를 대상으로 참조자 선언
    cout << "num2: " << num2 << endl;
    cout << "num3: " << num3 << endl;
 
    // int &ref = 20;        // 참조자는 변수에 대해서만 선언 가능
    // int %ref;            // 참조자는 미리 선언했다가 후에 참조 불가, 참조 대상 변경 불가
    // int &ref = NULL;     // NULL로 초기화 불가
 
    int num = 12;
    int *ptr = &num;
    int **dptr = &ptr;
 
    int &ref = num;            // 변수 참조
    int *(&pref) = ptr;        // 포인터 변수 참조
    int **(&dpref) = dptr;    // 더블 포인터 변수 참조
 
    cout << ref << endl;
    cout << *pref << endl;
    cout << **dpref << endl;
}
cs




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
using namespace std;
 
// Call-by-value 함수
// 주소 값을 이용해 함수의 외부에 선언된 변수에 접근하는 형태가 아님
int* SimpleFunc(int *ptr)
{
    return ptr + 1;
}
 
// Call-by-reference
void SwapByRef(int &ref1, int &ref2)
{
    int temp = ref1;
    ref1 = ref2;
    ref2 = temp;
}
 
// const로 참조자를 선언시, 참조자 ref를 통한 값의 변경을 허용하지 않음
void HappyFunc(const int &ref)
{
 
}
 
 
// 반환형이 참조형
int& RefRetFuncOne(int &ref)
{
    ref++;
    return ref;
}
 
// 반환형이 값
int RefRetFuncTwo(int &ref)
{
    ref++;
    return ref;
}
 
// 지역 변수를 참조형으로 반환하면 안된다.
int& RefRetFuncThree(int n)
{
    int num = 20;
    num += n;
    return num;
}
 
int main()
{
    int val1 = 10;
    int val2 = 20;
    SwapByRef(val1, val2);
    cout << "val1: " << val1 << endl;
    cout << "val2: " << val2 << endl;
 
 
    // 반환형이 참조형인 경우, 반환 값을 무엇으로 저장하느냐에 따라 결과에 차이가 있다.
    int num1 = 1;
    int &num2 = RefRetFuncOne(num1);    // 참조형으로 반환된 값을 참조자에 저장
    int num3 = RefRetFuncOne(num1);        // 참조형으로 반환된 값을 변수에 저장
 
    num1++;
    num2++;
    num3++;
    cout << "num1: " << num1 << endl;
    cout << "num2: " << num2 << endl;
    cout << "num3: " << num3 << endl;
 
    // 반환형이 값인 경우, 값이 반환되므로 반드시 변수에 저장해야 한다.
    int num4 = 1;
    int num5 = RefRetFuncTwo(num4);
 
    num4 += 50;
    num5 += 100;
    cout << "num4: " << num4 << endl;
    cout << "num5: " << num5 << endl;
 
    // int &num6 = RefRetFuncTwo(num4);        // 에러
 
    int &num7 = RefRetFuncThree(10);        // 지역 변수는 소멸되므로 참조형으로 반환하면 안된다.
    cout << "num7: " << num7 << endl;
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
 
int Adder(const int &num1, const int &num2)
{
    return num1 + num2;
}
 
int main()
{
    const int num = 20;
//    int &ref = num;                    // 에러 참조 불가
 
    const int &ref = num;            // 상수화된 변수에 대한 참조자 선언
 
    const int &ref2 = 50;            // 상수 참조 가능, 임시 변수 상수화
 
    cout << Adder(34<< endl;    // const의 상수 참조
}
cs


1
2
3
4
5
const int num = 10;                // 변수 num을 상수화
const int *ptr = &val;            // 포인터 ptr을 이용해서 val1의 값을 변경할 수 없음
int *const ptr2 = &val2;        // 포인터 ptr2가 상수화 됨
const int *const ptr3 = &val3;    // 포인터 ptr3가 상수화 되었으며, ptr3를 이용해서 val3의 값을 변경할 수 없음
 
cs

 

 

----------------------------------------------------------------------------------

-- Company: 

-- Engineer: 

-- 

-- Create Date:    01:23:35 06/05/2013 

-- Design Name: 

-- Module Name:    main - Behavioral 

-- Project Name: 

-- Target Devices: 

-- Tool versions: 

-- Description: 

--

-- Dependencies: 

--

-- Revision: 

-- Revision 0.01 - File Created

-- Additional Comments: 

--

----------------------------------------------------------------------------------

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;


---- Uncomment the following library declaration if instantiating

---- any Xilinx primitives in this code.

--library UNISIM;

--use UNISIM.VComponents.all;


entity main is

    Port ( CLK_50M : in  STD_LOGIC;

           RF_START : in  STD_LOGIC;

           RF_UPDOWN : in  STD_LOGIC_VECTOR (1 downto 0);

           MOTOR : out  STD_LOGIC_VECTOR (7 downto 0);

           SEGMENT : out  STD_LOGIC_VECTOR (6 downto 0));

end main;


architecture Behavioral of main is

signal rf_start_clk : std_logic;

signal rf_cnt : integer range -1 to 10 := 0;

signal rf_updown_clk : std_logic;

signal motor_clk : std_logic;

signal phase_cnt : std_logic_vector(2 downto 0);

signal phase_out : std_logic_vector(7 downto 0);

signal step_cnt : integer range 0 to 50000;

signal step_max : integer range 0 to 50000;

signal stop : std_logic;

signal start : std_logic;


begin

-----------------------------------------------------------------------------

--------------------------- Motor Clock Generator -------------------------------

----------------------------------------- MOTOR CLOCK : 50M/125000/2 = 200Hz

-----------------------------------------------------------------------------

process(start,CLK_50M)

variable cnt : integer range 0 to 125000;

begin

if start = '1' then

cnt := 0;

motor_clk <= '0';


elsif rising_edge(CLK_50M) then

if cnt >= 124999 then

cnt := 0;

motor_clk <= not motor_clk; 

else 

cnt := cnt + 1;

end if;

end if;

end process;

-----------------------------------------------------------------------------

----------------------------- Motor Phase Count -----------------------------

-----------------------------------------------------------------------------

process(start,motor_clk,phase_cnt)

begin

if start = '1' then

phase_cnt <= (others => '0');  

elsif rising_edge(motor_clk) then

phase_cnt <= phase_cnt+1;

end if;

end process;

-----------------------------------------------------------------------------

----------------------------- Motor Phase Out -------------------------------

--------------------------------------------------------------- 1-2상 여자 방식

-----------------------------------------------------------------------------

process(start,phase_cnt)

begin

if start = '1' then

phase_out <= (others => '0');

else

case phase_cnt is

when "000" =>

phase_out <= "10000001";

when "001" =>

phase_out <= "11000011";

when "010" =>

phase_out <= "01000010";

when "011" =>

phase_out <= "01100110";

when "100" =>

phase_out <= "00100100";

when "101" =>

phase_out <= "00111100";

when "110" =>

phase_out <= "00011000";

when "111" =>

phase_out <= "10011001";

when others =>

phase_out <= "00000000";

end case;

end if;

end process;

-----------------------------------------------------------------------------

--------------------- RF UPDOWN SWITCH CLOCK Generator ---------------------- 

-------------------------------------------------------------- 50M/5M/2 = 5Hz

-----------------------------------------------------------------------------

process(CLK_50M)

variable cnt : integer range 0 to 5000000;

begin

if rising_edge(CLK_50M) then

if cnt >= 4999999 then

cnt := 0;

rf_updown_clk <= not rf_updown_clk;

else

cnt := cnt + 1;

end if;

end if;

end process;

-----------------------------------------------------------------------------

------------------------------ RF UP DOWN COUNT -----------------------------

-----------------------------------------------------------------------------

process(rf_updown_clk,RF_UPDOWN,stop,step_cnt)

begin

if rising_edge(rf_updown_clk) then

case RF_UPDOWN is

when "01" => rf_cnt <= rf_cnt + 1;

when "10" => rf_cnt <= rf_cnt - 1;

when others => null;

end case;

end if;

if rf_cnt < 0 then

rf_cnt <= 9;

elsif rf_cnt > 9 then

rf_cnt <= 0;

end if;

if stop='1' then

step_max <= rf_cnt * 400;

end if;


end process;

-----------------------------------------------------------------------------

---------------------------------  SEGMENT  ---------------------------------

-----------------------------------------------------------------------------

process(rf_cnt,stop,step_cnt)

begin

if stop='1' then

case rf_cnt is

when 0 => SEGMENT <= "0111111";

when 1 => SEGMENT <= "0000110";

when 2 => SEGMENT <= "1011011";

when 3 => SEGMENT <= "1001111";

when 4 => SEGMENT <= "1100110";  

when 5 => SEGMENT <= "1101101";

when 6 => SEGMENT <= "1111101";

when 7 => SEGMENT <= "0000111";

when 8 => SEGMENT <= "1111111";

when 9 => SEGMENT <= "1100111";

when others => SEGMENT <="0000000";

end case;

elsif stop='0' then

if step_cnt>0 and step_cnt<399 then

SEGMENT <= "0111111";

elsif step_cnt>=399 and step_cnt<799 then

SEGMENT <= "0000110";

elsif step_cnt>=799 and step_cnt<1199 then

SEGMENT <= "1011011";

elsif step_cnt>=1199 and step_cnt<1599 then

SEGMENT <= "1001111";

elsif step_cnt>=1599 and step_cnt<1999 then

SEGMENT <= "1100110"; 

elsif step_cnt>=1999 and step_cnt<2399 then

SEGMENT <= "1101101";

elsif step_cnt>=2399 and step_cnt<2799 then

SEGMENT <= "1111101";

elsif step_cnt>=2799 and step_cnt<3199 then

SEGMENT <= "0000111";

elsif step_cnt>=3199 and step_cnt<3599 then

SEGMENT <= "1111111";

elsif step_cnt=3599 then

SEGMENT <= "1100111";

end if;

end if;

end process;

-----------------------------------------------------------------------------

--------------------- RF START SWITCH CLOCK GENERATOR -----------------------

-------------------------------------- RF CLOCK : rf_clk : 50M/25000/2 = 1kHz

process(CLK_50M)

variable cnt : integer range 0 to 25000;  

begin

if rising_edge(CLK_50M) then

if cnt >= 24999 then

cnt := 0;

rf_start_clk <= not rf_start_clk; 

else 

cnt := cnt + 1;

end if;

end if;

end process;

-----------------------------------------------------------------------------

------------------------------ RF START SWITCH ------------------------------

-----------------------------------------------------------------------------

process(rf_start_clk)

variable cnt : integer range 0 to 100;

begin

if RF_START = '0' then

start <= '0';

cnt := 0;

elsif rising_edge(rf_start_clk) then

cnt := cnt + 1;

if cnt = 100 then

start <= '1';

cnt := 0;

end if;

end if;

end process;

---------------------------- 1바퀴만 회전 후,정지 -----------------------------

process(start,motor_clk,step_cnt,stop)

begin

if start='1' then

stop <= '0'; step_cnt <=0;

elsif rising_edge(motor_clk) then

if step_cnt >= (step_max-1) then

stop <= '1';

step_cnt <= 0;

else

step_cnt <= step_cnt + 1;

end if;

end if;

end process;

-----------------------------------------------------------------------------

MOTOR(7) <= phase_out(7) when stop = '0' else '0';

MOTOR(6) <= phase_out(6) when stop = '0' else '0';

MOTOR(5) <= phase_out(5) when stop = '0' else '0';

MOTOR(4) <= phase_out(4) when stop = '0' else '0';

MOTOR(3) <= phase_out(3) when stop = '0' else '0';

MOTOR(2) <= phase_out(2) when stop = '0' else '0';

MOTOR(1) <= phase_out(1) when stop = '0' else '0'; 

MOTOR(0) <= phase_out(0) when stop = '0' else '0';

-----------------------------------------------------------------------------


end Behavioral;

 

 

 

 

result.mp4

 



2013 Makerfaire에 참가하기 위해서 준비중인 작품~!

아이들을 위한 저금통 "부자되거루"



   


부자되거루의 머리위에 동전 투입구가 있고

휨센서와 서보모터를 이용해서 500원짜리와 동전을 분류할 수 있다.



분류된 동전은 아래 같은 구조물로 들어가고 돈을 모두 모았을 때 배가 열리면서 돌려준다.


   


이제 동작을 위한 회로 사진이다.

Makerfaire 성격에 맞게 Arduino Mini를 사용하여 제작하였다.


      


하나의 보드에 서보모터, 금액표시 LCD, 금액 저장 SD카드를 모두 연결할 수 있게 제작했다.



LCD는 캥거루와 자연스럽게 어울리도록 꾸며보았다. 저금 할때마다 금액이 표시된다.


SD카드의 txt파일에 목표금액을 넣고 캥거루에 끼운 뒤 전원을 켜면 동작을 시작한다.

저금 금액역시 SD카드에 바로바로 저장되기 때문에 껐다켜도 그대로 저장되어있다.

목표금액과 저금금액이 일치했을 때만 배가 열리면서 동전을 돌려준다.

동전은 아이가 계산하기 쉽고 저금하기 쉽도록 100원과 500원을 분류해서 돌려준다.

+ Recent posts