HW개발자를 위한 Software 워크숍

박동희


시간표


첫날 일정


첫날 워크숍 노트

HW개발자를 위한 Software 워크숍 노트: 첫날

http://dh8.kr/workshop/swworkshop/note/day1.html


자기소개


원하는 것 공유


임베디드 하드웨어/소프트웨어 개발 시작하기

처음 시작할때는 취미 플래폼 체크: Rpi, Arduino, Particle, Mbed

  1. C언어 배우기
  2. 기초 전자이론(전압, 전류, 파워, 저항, 옴의법칙)
  3. 납땜, 멀티미터, 디버거, 오실로스코프(또는 로직 애널라이져)
  4. 마이크로컨트롤러와 툴체인 선택. 개발보드
  5. 부품 선택 구매(digikey, mouser), 그리고 데이터 쉬트 읽기.

컴퓨터의 역사

목표: 컴퓨터가 어떻게 동작하는지 알 수 있다.

자코드 방직기 (Jacquard loom) 1804


배비지 머신 1833


기계식 컨트롤러(컴퓨터)

출처: http://www.flickr.com/photos/28556101@N00/8837851912/


폰노인만 구조

폰노인만 구조
폰노인만 구조

참고: 폰노인만 구조 –위키페디아

CPU 프로그래밍의 원리


소프트웨어는 어떻게 하드웨어를 동작 시키는가? 기계는 프로그램을 어떻게 해석 할까?

  1. CPU에 대해서 알아보고
  2. CPU가 코드를 실행하는 것을 시뮬레이션 해보자.
  3. 컴파일 과정을 알아보자.

CPU: Central processing unit

컴퓨터안에 있는 하드웨어로, 기본연산, 논리, 입출력을 계산하는 프로그램의 명령에 따라 일을 하는 하드웨어

참고: AVR(atmega128기준) 프로그램 접근은 16비트 버스, 데이터 접근은 8비트 참고: images/wXcJN0V.png

AVR Block Diagram


CPU 용어

레지스터: 특수 목적으로 저장하는 메모리


CPU 용어2

CPU 내부에 있는 모듈

하드웨어(CPU)에서 코드(Instruction) 실행


CPU가 어떻게 코드를 실행는가? 컴파일

byte a = 1;
byte b = 2;
byte c;

void add(void)
{
    c = a+b;
    return
}

C코드 (c = a+b;) 컴파일 결과: 어셈블리

0x1000        LOAD     0x2000
0x1002        ADD      0x2002
0x1004        STORE    0x2004

AVR은 8비트 CPU지만 opcode의 크기는 16비트 이다. PC도 16비트



LOAD 0x2000


ADD 0x2002


STORE 0x2004


컴파일

코드가 메모리에 올라가기전에 어떤일이 일어나나?

컴파일: 프로그래밍 언어를 CPU 명령어(Instruction)의 나열(코드)로 바꾼다.

컴파일: C->Assembly->기계어

c = a + b; // C언어 
ADD R2, R1, R0 // R2 = R1 + R0; 어셈블리
0xEB010200 // ARM 기계어 코드, 32bits

링킹: 컴파일된 여러개의 파일을 하나의 코드로 합친다. (예: startup.s + main.c -> main.out )

>

로딩: 컴파일된 코드를 CPU에 적재!

참고: 컴파일/링킹: http://blog.feabhas.com/2012/06/the-c-build-process/


임베디드 소프트웨어의 컴파일, 펌웨어 업로드

  1. PC에서 컴파일 하여, 타겟 보드의 명령어 집합(instruction set)인 펌웨어를 생성한다.
  2. 타겟보드에 Debug interface를 통해서 펌웨어를 업로드 한다.


프로그램 (소프트웨어)


MCU (microcontroller unit)

한칩에 연산을 하는 코어, 메모리, 그리고 프로그래밍 가능한 입출력 주변기기를 가지고 있는 작은 컴퓨터

폰노인만 구조: 내장 메모리 순차 방식!


임베디드 소프트웨어?


임베디드 소프트웨어 어떻게 시작하는게 좋을까?

임베디드 소프트웨어는 왜 C? 인가?


mbed : http://mbed.org/

http://developer.mbed.org/platforms/mbed-LPC1768/

lpc1768 datasheet

lpc1768 user manual


lpc1768 memory map

MCU에서 소프트웨어는 메모리를 제어 하여 주변장치를 제어하고, 연결한다.

그러니깐 메모리 맵이 …


메모리 용어 정리: Stack, Heap

Flash, Sram, 레지스터

Stack과 Heap은 Sram의 영역을 나누어서 사용 한다.

.bss 초기화 되지 않은 전역 변수 .data 초기화된 전역변수값 저장 .rodata 초기화된 const 전역변수값 저장


lpc1768 instruction set


설치

다운로드

다음 주소에 있는 파일을 다운로드 받는다.


컴파일/실행

  1. mbed_nxp1768 폴더로 이동
  2. BuildShell.cmd 명령을 실행. (환경변수 설정)
  3. 명령어 창이 뜨면 samples\HelloWorld 폴더로 이동 (cd samples\HelloWorld)
  4. makefile 수정
  5. make (컴파일)
  6. make upload
  7. 보드의 reset 버튼 누르기

표준 입출력 Standard Input Output

  1. mbed uart 드라이버 설치: mbedWinSerial_16466.exe
  2. teraterm–4.76 실행: ttermpro.exe
  3. teraterm 으로 mbed 연결 : File -> New Connection -> Serial -> mbed Serial Port
  4. teraterm 설정: Setup -> Terminal -> Under “New-line”, set Receive to “LF”

C 프로그래밍 언어!

github.com 가입 (구글 크롬에서만 가능)


구조: 나는 살아 있어!

#include <stdio.h>
int main()
{
    printf( "I am alive!  Beware.\n" );
    return 0;
}

C언어 기본 구조 설명


디버깅: 에러로 배우는 프로그래밍

  1. 의도적으로 에러 만들기.
  2. 에러 나는 이유 찾기.
  3. 기록하기 http://pad.dh8.kr/p/lgswws (가정, 관찰, 다음 행동)
  4. 기록한 내용 공유

참고:

GCC Compiler error


C언어의 데이터 타입

int(정수), float(실수), char(문자)

질문: 왜 타입을 쓰나?

C언어의 데이터 표현

정수(음수),실수(소수), 문자를 메모리에 저장하는 형식.


변수

Code:

type varName = data;

Example:

  1. int age = 3;
  2. float length = 2.4;
  3. char alphabet = 'c';

출력

  1. printf("age = %d\n", age)
  2. printf("length = %f\n", length)
  3. printf("length = %d\n", (int)length)
  4. printf("alphabet = %c\n", alphabet)

실습해보기


C언어에서 변수, 연산자


비교연산(*)

논리 연산


조건문

if (condition1)
{
    // if condition1 is true
    // do this code
}
else if (condition2)
{
    // if condition2 is true
    // do this code
}
else
{
    // do this code instead
}

실습해보기

Good morning!, Good afternoon!, Good evening!, Good night!

int time;
printf("What time is it now?\n");
scanf("%d", &time);
printf("%d\n",time);

if (   )
{

}
else if (   )
{

}
else
{

}

함수 function

함수를 이용하여 나만의 명령어를 만든다.

정의문법:

결과값의타입 함수이름(입력값의타입 입력값) {

return 결과값;
}

함수 예제

int add(int x, int y) {
    int result;
    result = x + y;
      printf("%d + %d = %d", x, y, result);
    return result;
}

사용:

y = add(2,3);
printf("%d",y); // 5

해보기


C언어의 지역변수, 전역변수: Scope

함수 내부에 있느냐 함수 밖에 있느냐로 지역변수, 전역 변수를 구분.

지역변수

```

int multiply(int x, int y) {
    int result;
    result = x * y;
    return result;
}

```


전역변수

```

int result;
int multiply(int x, int y) {
    result = x*y;
    return result;
}
int main()
{
    printf(“result: %d”, result);
}

```

http://assembly.ynh.io 온라인 C->assembly 컴파일러


함수: 퀴즈

isLeapYear() 함수의 내용을 채우시오.

윤년: 1년이 366일이 되는 해가 윤년이다.

그레고리력의 윤년 규칙

  1. 연수가 4로 떨어지는 해는 윤년 (2004, 2008, 2012)
  2. 이중에 100으로 떨어지는 해는 평년(2100, 2200, 2300)
  3. 그중 400으로 나누어 떨어지는 해는 윤년(1600, 2000, 2400)

1태양년 = 365일 5시간 48분 46초


조건문: 윤년

10분, github.com에 가입한 후 gist.github.com에 풀이 코드 올리기. 짝 공유. ‘gist 사용하기 위해서는 구글 크롬 필수’

  1. 함수의 이름은 isLeapYear 이다.
  2. 입력: 타입은 정수형 이름은 year 이다.
  3. 출력: 윤년이면 정수 1을 출력, 아니면 정수 0을 출력한다.
#include "stdio.h"

int main()
{
    int year;
    printf("Enter any year: ");
    scanf("%d", &year);
    if(isLeapYear(year)) {
        printf("%d is leap year!\n", year);
    } else {
        printf("%d is not leap year!\n", year);
    }
    return 0;
}   

알고리즘 퀴즈 FizzBuzz

FizzBuzz 수열규칙을 읽고, fizzbuzz() 함수의 내용을 채우시오. 확인 힌트: 손코딩. 시간: 15분

  1. 1 부터 100 까지의 숫자를 화면(터미널)에 출력한다.
  2. 그러나, 3의 배수인 수 대신 “Fizz” 출력
  3. 또한, 5의 배수인 수 대신 “Buzz” 출력
  4. 그리고, 3과 5의 배수인 수 대신 “FizzBuzz” 를 출력.

..

#include <stdio.h>
void fizzbuzz(int n) {
    // 아래 코드를 고쳐서 fizzbuzz 수열을 출력하시오.
    print("%d\n", 1);
}

int main (void)
{
    int i;
    fizzbuzz(100);
    return 0;
}   

알고리즘 퀴즈: Prime Factor (소인수 분해)

Prime Factor 소인수 분해 참고: http://mathbang.net/200 (소인수분해 정의)

자연수 n 을 입력 받았을때 , n 의 소인수 분해 숫자(소수)를 출력하는 함수 void prime_factor (int n) 를 만들어 봅시다. 예를 들어

하도록 만들어 봅시다.

#include <stdio.h>

void primefactor(int number) {
    // 아래 코드를 추가 하여 prime factor가 출력하시오.
}

int main (void)
{
    int i;
    primefactor(1);
    primefactor(2);
    primefactor(30);
    primefactor(75);
    return 0;
}