JNI를 사용하여 GPIO LED 컨트롤

Posted in 단체/ㄴKETI 연수생 by

저번에 작성한 파일은 Syscall을 이용하여 디바이스를 컨트롤했지만 이번에는 sysfs의 attribute를 사용하여 컨트롤 해보자


디바이스 드라이버 컨트롤 4가지 방식 : proc, sysfs, syscall, 디바이스모드 파일 


### FLOW CHART ###

1. 디바이스 드라이버 제작(myled.c)

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/errno.h>

#include <linux/kernel.h>

#include <linux/major.h>

#include <linux/mutex.h>

#include <linux/proc_fs.h>

#include <linux/seq_file.h>

#include <linux/stat.h>

#include <linux/init.h>

#include <linux/device.h>

#include <linux/tty.h>

#include <linux/kmod.h>

#include <linux/gfp.h>

#include <linux/spinlock.h>

#include <linux/delay.h>

#include <linux/platform_device.h>

#include <linux/gpio.h>

#include <linux/sysfs.h>

#include <linux/myled.h>

#include <plat/gpio-cfg.h>

#include <asm/uaccess.h>

static ssize_t set_myled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);

static DEVICE_ATTR(led, S_IWUGO, NULL, set_myled);

static struct myled_platform_data *pdata;

static struct attribute *myled_sysfs_entries[] = {

&dev_attr_led,

NULL

};

static struct attribute_group myled_sysfs_attr_group = {

.name = NULL,

.attrs = myled_sysfs_entries,

};

static ssize_t set_myled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)

{

unsigned int val;

if(!(sscanf(buf, "%d\n", &val))) return -EINVAL;

gpio_set_value(pdata->gpio_tx, ((val != 0) ? 1 : 0));

return count;

}

static int myled_probe(struct platform_device *pdev)

{

int err;

pdata = pdev->dev.platform_data;

err = gpio_request(pdata->gpio_tx, pdata->gpio_tx_bank);

if (err < 0) {

pr_err("myled : failed to request GPIO %d,"

" error %d\n", pdata->gpio_tx, err);

goto fail;

}

gpio_direction_output(pdata->gpio_tx, 0);

return sysfs_create_group(&pdev->dev.kobj, &myled_sysfs_attr_group);

fail:

gpio_free(pdata->gpio_tx);

platform_set_drvdata(pdev, NULL);

return err;

}

static int myled_remove(struct platform_device *pdev)

{

return 0;

}

static struct platform_driver myled_device_driver = {

.probe = myled_probe,

.remove = myled_remove,

.driver = {

.name = "myled",

.owner = THIS_MODULE,

}

};

static int __init myled_init(void)

{

platform_driver_register(&myled_device_driver);

printk(KERN_INFO "============= myled init OK =============\n");

return 0;

}

static void __exit myled_exit(void)

{

platform_driver_unregister(&myled_device_driver);

}

module_init(myled_init);

module_exit(myled_exit);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("GPIO LED TEST");


2. 안드로이드 APK 제작(myled.apk)

    1) Eclipse에서 MyLed 프로젝트를 작성

    2) java 파일에서 public native 반환자료형 함수명(...);으로 C언어로 사용할 함수명을 선언

    3) XML파일을 작성

    4) MyLed 프로젝트 아래에 Eclipse에서 JNI 폴더 생성

    5) 프로젝트\bin\class로 이동 후 Javah -classpath C:\CookAndroid\android-sdk\platforms\

        android-8\android.jar; com.example.myled.MainActivity 실행하여 헤더파일 작성

        [platforms\android-OS버전별 API레벨\android.jar; 패키지명.MainClass명]

        → 이 때 JAVA파일에 선언된 native 함수명을 참조하여 헤더파일을 만드므로 미리 선언해놔야한다.

     6) 프로젝트\bin\class에 생성된 헤더파일을 JNI폴더 아래로 복사

     7) JNI 폴더 아래 myled.c 작성

         JNIEXPORT 반환자료형 JNICALL (위에서 생성된 헤더파일 안에 선언된 함수명 - 동일해야 링크됨)

     8) JNI 폴더 아래 Android.mk 파일 작성

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := myled

LOCAL_SRC_FILES := myled.c

include $(BUILD_SHARED_LIBRARY)

9) Cygwin 창에서 /cygdrive/c/CookAndroid/Project/HelloWorld/JNI로 이동 후

    $/cygdrive/c/CookAndroid/android-ndk-r8b/ndk-build

10) MyLed/libs/armeabi/libmyled.so 파일 생성 확인, MyLed/bin/Myled.apk 생성된 것을 sdcard에 복사후 설치


3. MyLed\JNI\myled.c 소스 파일

#include <stdlib.h>

#include "android_log.h"

#include "com_example_myled_MainActivity.h"


JNIEXPORT void JNICALL Java_com_example_myled_MainActivity_LED_1ON(JNIEnv *env, jobject jObj){

system("echo 0 > /sys/devices/platform/myled.0/led");

}

JNIEXPORT void JNICALL Java_com_example_myled_MainActivity_LED_1OFF(JNIEnv *env, jobject jObj){

system("echo 1 > /sys/devices/platform/myled.0/led");

}


4. MyLed\JNI\Android.mk 소스 파일 (log를 사용하기 위해 2,3줄 추가)

LOCAL_PATH := $(call my-dir)

LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

LOCAL_CFLAGS := -DCONFIG_EMBEDDED\ -DUSE_IND_THREAD\


include $(CLEAR_VARS)

LOCAL_MODULE := myled

LOCAL_SRC_FILES := myled.c


include $(BUILD_SHARED_LIBRARY)


LED GPIO 드라이버 추가하기

Posted in 단체/ㄴKETI 연수생 by

### Flow Chart ###

ㅁㅁㅁ        하드웨어        ㅁㅁㅁ

ㅁㅁㅁ        커널              ㅁㅁㅁ

   - kernel/arch/arm/mach-s5pv210/mach-mango210.c : platform_data 및 platfom_device 생성

   - kernel/drivers/char/IR/ir-nec-encoder.c : driver를 통해 .name이 같은 device를 찾아 data 구조체를 갖고와서 컨트롤 

ㅁㅁㅁ        System call    ㅁㅁㅁ

   - System call을 이용하여 ir-nec-encoder에 정의되어 있는 함수를 호출

ㅁㅁㅁ        Application     ㅁㅁㅁ

   - App에서 System call을 호출하여 커널 디바이스 드라이버를 컨트롤


### 01. Platform data 및 device 생성하기 ###

1. 아래에서 생성할 Platform data 구조체를  : include/linux/myled.h

    → 2번에서 생성할 data 구조체를 정의해놓는다. (참고 : include/linux/smr210_ir_nec_encoder.h)

2. Data 및 Device 생성 : /kernel/arch/arm/mach-s5pv210/mach-mango210.c

    → mango210.c에서 CONFIG_SMR210_IR_NEC_ENCODER 심벌로 정의되어 있는 부분 참고(2부분)

    → 1부분 : Data 구조체와 Device 구조체 생성 // 2부분 *mango210_device[] __initdata에 생성한 Device 추가

    → 새로 정의하는 심벌이름은 CONFIG_MY_GPIO_LED로 하겠다

    → LED 주소값 설정 : (data구조체 변수).gpio_tx = S5PV210_GPH2(0)


### 02. LED 드라이버 추가 ###

1. 위에서 정의한 data와 device를 컨트롤할 드라이버 구현

    → drivers/leds/폴더명 (참조 : drivers/char/IR/Makefile, Kconfig, ir-nec-encoder.c 3파일 Modify)

    → ir-nec-encoder.c 파일이름을 변경 : mv ir-nec-encoder.c myled.c

    → Makefile 수정 : 심볼이름을 위에서 정의한 심볼(CONFIG_MY_GPIO_LED)로 바꾸고 오브젝트 파일을 myled.o로 바꾼다

    → KConfig 수정 : 기존 내용을 다 지우고 아래 내용을 추가해준다 (menuconfig가 CONFIG_라는 이름을 자동으로 붙여줌)

config MY_GPIO_LED

bool "GPH2[0] LED ADD SYMBOL"


2. 드라이버 기능을 myled.c 파일에 선언과 정의

     → 01번에서 정의한 Platform data 구조체를 사용해야 하니 #include <linux/myled.h>를 해준다

     → static struct platform_driver myled_device_driver을 정의해주고 구조체변수들을 입력

     → driver의 구조체변수 .probe, .remove 함수포인터 전달 & .driver = {.name="myled"}은 mach-mango210.c에서 

         "myled"와 같은 드라이버를 찾아서 그 디바이스 주소값을 넘겨준다.(이를 통해 접근하면서 디바이스를 컨트롤)

     → static int __init myled_init() 정의와 안에 platform_driver_register(&myled_device_driver)를 통해 드라이버 등록

     → static void __exit myled_exit() 정의와 안에 platform_driver_unregister(&myled_device_driver)를 통해 드라이버 해제

     → module_init(myled_init) 선언 - insmod로 불려지는 함수, module_exit(myled_exit) 선언 - rmmod로 불려지는 함수 


### 03. Makefile, Kconfig 의존성 해결(Menuconfig 추가하기) ###

1. Makefile 의존성 해결

    → myled의 Makefile이 실행되기 위해 상위 Makefile을 수정해줘야 한다

    → leds/Makefile에 obj-$(CONFIG_MY_GPIO_LED)    += myled/ 를 추가시켜준다

2. Kconfig 의존성 해결

    → make menuconfig 에서 CONFIG_MY_GPIO_LED을 체크하려는 창을 만들려면 myled의 Kconfig를 수정해야한다.

    → if NEW_LEDS 아래에 source "drivers/leds/myled/Kconfig"를 추가해준다

    → 그러면 make menuconfig에서 drivers-LED를 체크해주면 NEW_LEDS가 정의되어 있으니 Source 파일이 활성화되면서 

  우리가 추가해준 myled의 Kconfig가 보인다

    → MY_GPIO_LED 심볼을 활성화하여 CONFIG_MY_GPIO_LED 심볼이 활성화되도록 한다

    → kernel/.config 와 kernel/include/linux/autoconf.h 에서 CONFIG_MY_GPIO_LED 심볼이 추가됐는지 확인


### 04. System Call 추가하기 ###

1. System Call 번호 할당 : $ /kernel/arch/arm/include/asm/unistd.h (각 시스템 호출의 고유 번호가 정의되어 있음)

    → 새로 추가할 System call의 고유번호 정의 추가 : #define __NR_my_gpio_led                                [__NR_심볼명]

2. System Call 테이블에 처리 함수 등록 : $ /kernel/arch/arm/kernel/calls.S

    → System Call 처리함수 등록 : CALL(sys_my_gpio_led)                                                      [CALL(sys_심볼명)]

    → entry-common.S파일에서 ENTRY(sys_call_table)이 calls.S를 include하고 있기 때문에 calls.S를 수정하는 것

3. 처리 함수 구현 : /kernel/kernel/my_gpio_led.c                                                                                 [파일명.c]

    → System Call 이 발생했을 때 수행될 함수를 구현

    → asmlinkage 반환자료형 sys_my_gpio_led(...) { 내용 } : 2번에서 CALL로 등록한 이름과 동일해야 함 [sys_심볼명]

4. Makefile 수정 : /kernel/kernel/Makefile 에 3번에서 구현한 '파일명.c'의 오브젝트 파일을 생성할 수 있도록 조건 추가

    → obj-y    = ***.o ***.o my_gpio_led.o                                                                                           [파일명.o]

5. Kernel 컴파일 수행 및 커널 이미지 복사 : ./fastbuild ( make && cp zImage ../../sdboot/zImage )

6. Kernel 이미지 퓨징 : sudo ./sdwriter_maple210 sdb


### 05. Android App 추가하기 : System call Test ###

1. Application 작성 : Android_work/external/디렉토리

    → external에 새로운 작업 디렉토리를 만든다

    → 작업디렉토리에 소스파일(my_gpio_led.c)를 만들고 System call를 호출한다(syscall(__NR_my_gpio_led))

2. 안드로이드 어플 Makefile 작성 : Android_work/external/디렉토리/Android.mk

    → 파일명.c은 위에서 작성한 소스파일명과 동일, 모듈이름은 안드로이드 프롬프트에서 실행할 명령어

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_C_INCLUDES:= \

$(LOCAL_PATH)/include \

$(LOCAL_PATH)/android

LOCAL_SRC_FILES:= \

my_gpio_led.c                                                                                                          [파일명.c]

LOCAL_MODULE:= my_gpio_led                                                                                     [실행 명령어]

include $(BUILD_EXECUTABLE)

3. 컴파일 및 설치 : Android_work/

    → 컴파일 한 후 실행파일을 rootfs/system/bin에 복사

$ . build/envsetup.sh

$ chooseproduct sec_smdkv210

$ mmm external/디렉토리/

$ cp out/target/product/smdkv210/system/bin/my_gpio_led rootfs/system/bin

4. rootfs 를 묶어서 sdboot로 이동 : Android_work/rootfs/

    → rootfs 폴더에서 $ tar cvfz ../../sdboot/maple210_android210.tgz .

    → Kernel 이미지와 안드로이드 이미지 퓨징 $ sudo ./sdwrite_maple210 sdb

5. 테스트

    → sh-4.0 # 모듈명

Linux 명령어

Posted in 단체 by

● LINUX 명령어 요약

1.기본 명령어

date : 현재의 날짜와 시간을 단말기 화면에 표시

who : 리눅스 시스템에 로그인 되어 있는 사용자들에 대한 정보를 화면에 표시

date;who;cat > sample.c : 한 줄에 두 개 이상의 명령어를 동시에 입력하고자 할 경우 명령어와 명령어 사이를 ; 으로 구분한다

cal 8 1998 : unix 시스템에 내장되어있는 달력을 화면에 출력

cat address.list : 파일의 내용을 화면에 출력한다

man date : 예약어나 명령어에 대한 온라인 매뉴얼

ls: 현재 위치한 디렉토리 아래에 있는 파일 및 서브디렉토리의 정보를 나열 <옵션>

-l: 파일의 모든 정보 출력

-c: 최근 변경한 시간 순서대로 출력

-d: 디렉토리 명만 출력

-F: 파일의 특성을 출력( /디렉토리 *실행화일)

-a: dot(.)으로 시작하는 파일의 이름을 포함한 모든 내용을 출력

alias dir ls -alF : 자주 쓰이는 명령어 ls를 다른 형태의 명령어 dir로 바꿀 때..

pwd : 현재 작업 디렉토리 출력 명령어

cd : 디렉토리 변경 명령어

2.디렉토리 관리 및 파일 관리 명령어

mkdir : 디렉토리 생성 명령어 (%mkdir [option] [directory name]

rmdir : 디렉토리 삭제 명령어

<옵션>

- r: rm -r test ; test의 하위디렉토리와 파일을 전부 삭제

- i: rm -i test ; 삭제 여부를 사용자에게 물어 본다

cat : 파일을 작성하거나 파일의 내용을 간단하게 출력

cat test1.c cat > test1.c

touch : 내용이 없는 빈 파일을 생성, 이미 생성된 파일의 수정 시간 갱신 touch [option] [시간] [파일명]

more [file name] : 한 번에 한 화면씩 파일의 내용을 표준 출력

-내용을 보지 않고 종료시 q 나 Q 키를 누른다

page [option] [file name] : 한 번에 한 화면씩 파일의 내용을 표준 출력(=== %pg)

nl [file name] : 지정한 파일의 내용을 츨력할 때 맨 앞에 행 번호를 붙쳐서 출력

file test.c : test.c라는 파일의 형태를 출력

cp :시스템내에 있는 특정 파일을 복사

- mkdir temp :temp라는 디렉토리 생성

- cp sample test temp :temp라는 디렉토리 밑에 sample 과 test 라는 파일을 복사

- mkdir example

- cp -r temp example --temp라는 디렉토리 아래에있는 모든 내용을 example디렉토리에 복사

mv [file name1] [file name2]: file name1을 file name2로 이름 변경

mv [file1] [file2] [directory1]: file1, file2를 directory1으로 이동

mv [directory1] [directory2]:directory1의 모든 내용을 directory2로 이동

-->명령어 cp, mv, rm에서 option -i는 사용자에게 여부를 묻는 옵션입니다

rm test1 test2 test3 : test1,test2,test3 파일을 삭제

rm -r quit : quit 디렉토리 및 모든 내용을 삭제

ln test1 test2 : test1과 test2라는 2개의 파일을 연결

(unlink ; 연결 해제)

find: 사용자가 지정한 특정 범위에 해당하는 모든 파일을 검색 - find / -name test1.c -print ; 최상위 루트 디렉토리부터 검색하여 검색된 파일을 한 행에 하나씩 표준 출력

find . -name test1.c -print ; 현재의 작업 디렉토리에서 검색 find / -size +1000 -print ; 최상위 루트에서 크기가 1000블록 이상인 파일 검색

find . -size -1000 -print : 현 디렉토리에서 크기가 1000블록 이하인 파일 검색

find . -mtime +10 -print : 10일 이전에 수정된 파일 검색

find . -mtime -10 exec rm {} \: ; 10일 이내에 수정한 파일을 검색하여 모두 지운다

chmod : 파일 및 디렉토리에 이미 정해진 접근 허가 모드를 변경

- 사용 형식: %chmod [ugoa] [+-=] [rwx] [file name]

u: 파일 소유자, g: 그룹, o: 기타 사용자, a: 모든 사용자

+: 사용허가부여, -: 사용허가박탈, =: 허가 취소

r: 읽기 허가, w:쓰기 허가, x: 실행 허가

특정 사용자를 지정하지 않으면 모든 사용자를 의미한다

chmod go+r test.c ; 소유자 그룹과 기타 사용자에게 읽기 허가

chmod ugo-w test.c ; 소유자,그룹,기타 사용자에게 읽기 허가 박탈

chmod +x test.c

chmod o -rwx test.c

r = 4, w = 2, x =1

chmod 744 test.c

-rwxr--r-- 1 edul user 235 Oct 15 13:23 test.c

chmod 724 test.c

-rwx-w-r-- 1 edul user 235 Oct 15 13:23 test.c

* : dot(.)을 제외한 모든 문자와 대응하며 모든 파일명을 대표하는

메타 문자 %ls *a* , %ls t*

? : " " " 임의의 한 문자만을 대신





3.입력과 출력에 관한 명령어

입력> 출력 >>

date > date.out : 이전 내용이 지워지고 새로운 내용이 저장

date >> date.out : 이전 내용과 함께 새로운 내용 첨가

file test.out : test 파일을 입력으로 받아서 file 명령을 실행하고

-cat test.out: test.out에 출력

test: Ascll text

2>>, 2> : 오류 출력 제지정

tty : 현재 사용하고 있는 단말 장치의 이름을 경로와 함께 표준 출력

lpstate : 프린터의 현제 상태 (활성화: enable, 비활성화: disable)

lp -c temp.c : 내용이 변경되어도 문제가 지속되지 않도록미리 출력될 파일을 복사

lp -n7 /etc/lp/temp : 7장 프린트

lp -m temp.c : 출력이 끝난후 사용자에게 전자우편을 보냄

lp -t"chon bing hee" : test.out ; chon bong hee라는 표제를 달아 줌

cancel [print name] : 프린터 취소

disable -c [print name] : 지정한 프린터에서 현제 출력중인 작업 취소

disable -w laser-3 : 모두 인쇄한 다음 프린터를 disable 상태로 만든다

disable -c -r "out of paper" laser-1 : 주석을 달아 놓는다

grep [option] 형태 [화일명] : 정규식을 이용 패턴 지정

-grep -i tom sample.c : sample.c 라는 파일에서 tom 이라는 문자열을 대소문자 구분 없 이 검색

-grep -n tom sample : 행 번호와 함께 출력

-grep -i "tom is" sample : 공백은 " "로 표기

-grep -v tom sample : tom이라는 형태를 포함하지 않는 행을 출력

fgrep helo test1 test2 : 복수개의 파일 지정,단순한 문자열 검색

egrep "mary {su | mj)" sample : sample 파일에서 mary su 와 mary mj를 포함하는 행 을 동시 검색 다양한 정규식 사용

cut -c10-17 sample : sample 파일에서 칼럼 단위10-17을 절단

-cat sample

computer science

computer graphics

-cut -c10-17 sample : sample 파일에서 칼럼 단위10-17을 절단 -cat sample : sample 출력결과 > science graphics

paste : 파일 합성 명령어 (-d: 구분자를 지정)

-cat aaa

qqq

www

-cat bbb

eee

rrr

paste -d; aaa bbb

qqq;eee

www;rrr : ; 으로 구분자를 지정

cmp test1 test2 : 서로 다른 두 파일을 비교

dircmp test test : 서로 다른 두 디렉토리 비교

4.백업 및 복사에 관한 명령어(rfd:디스켓, rct:카트리지테이프, rmt: 테이프)

하드 ----> 디스켓

tar -cvf /dev/rfd0c test1 (c: 저장되는 파일들이 디스크의 처음 부터 기록, v:기록되는 화일명 화면 출력)

tar -tvf /dev/rfd0c : 디스켓의 파일 목록 확인

디스켓 ----> 하드

tar -xvf /dev/rfd0c test1 : 지정한 파일 복원

동일한 하드에서 %tar -cvf test1.tar test1 compress test.c (파일 압축)

uncompress test.c.Z (압축 풀기)

test.c.Z (파일 생성)

zcat test.c.Z (파일 보기)

pack test.c (파일 압축)

unpack test.c.z :test.c.z (파일 생성)

pcat test.c.z (파일 보기)

Non-preemptive(비선점) : 커널 모드

kernel : 생성되는 프로세스마다 PCB 부여하고 관리



5.멀티 태스킹에 관련된 명령어

Multitask

foreground : 하나의 명령이 실행되어 결과를 출력할때까지 다른 명령을 수행 할 수 없다

background : 하나의 명령을 수행시킨후 그 수행의 종료 이전에 다른 명령을 수행 하는 것

---> 명령어 끝에 &로 표시 (cc -o test1 test1.c &)

ps -l : 프로세스에 관한 모든 상태 정보 출력

ps -e : 현제 실행중인 모든 프로세스에 관한 정보 출력

ps ps -t 00 : 지정된 터미널에서 실행중인 프로세스에 관한 정보 출력

nice [-정수값:1~39 , 20으로 설정] 명령어 -->우선 순위 변경 명령어

정수값이 높을수록 우선 순위가 낮다 (nice -10 cc -o test test1.c)

at : 수행 시간 지정 명령어 -->at 11:30 pm

cc test.c

<옵션>

-r: 이전에 지정된 작업 취소

-l : 지정된 작업 번호 출력

(sleep 20; cc -o sample sample.c)& -->백그라운드 실행, 20초 뒤 프로그램 컴파일 (sleep 10; ps -el) --> 10초후 모든 프로세서 상태 출력

time cc -o test test.c --수행 시간 출력 명령어

Running : 현제 백그라운드 수행중인 상태

Stopped : fg로 수행되다가 ^D로 잠시 중단된 상태

Terminated : Kill 명령을 사용해 강제로 종료된 상태

Done : 백그라운드 프로세서의 수행이 완전히 종료된 상태

Exit : 백그라운드 프로세서가 수행도중 오류 때문에 빠져 나온 상태

jobs : 백그라운드로 수행중인 모든 프로세서의 상태 출력

fg %1(작업 번호) : 백그라운드로 수행중인 작업을 포그라운드로 전환

bg %1( " ) : 포그라운드로 " " 백그라운드로 전환

wait [작업번호] : 백그라운드 실행 종료

kill [번호] : 프러세서 강제 종료 명령어

---> 강제 종료가 안될 경우 -9옵션을 사용 %kill -9 1239

nohup cc -o sample1 sample1.c & 1132[PID번호] ---> 백그라운드로 실행, 로그 아웃이나 중지 신호후에도 프로세서의 수행 계속



6.shell 관련 명령어

alias : UNIX 명령어 이름에 쉘이 인식할 수 있는 새로운 이름, 즉 별칭을 지정하는 것

- alias readmail cat /usr/mail/chonbh

- alias dir ls -al

-alias type cat

쉘 Bourne쉘 (sh), C 쉘 (csh) , K 쉘 (ksh)

setenv PS1 "bonghee>"

echo $PS1

bonghee> : 기본 프로프트 정의

ctrace ---c : 프로그램의 추적

cb [화일명.c] : c프로그램의 형식을 정돈

lint [option] [파일명] : compile error 검사

cc test.c

a.out ---> 생성

cc :c컴파일러

CC :c++ , x-windows

 

참조 : http://anuis.andong.ac.kr/%7Ekih/linux1.html

 

출처-쉽게 풀이된 LINUX 명령어 활용 사전 (PS:서점가면 팜)


[C/C++] C++ 수업내용 Pointer

Posted in 단체/ㄴ대학 전공 수업 by

#include <iostream>

using namespace std;

int main(){

  
 char s1[10];
 char *s2 = "Hello!";

 s1 = s2;                     // s1도 주소이고 s2도 주소인데 왜 Error가 날까?
                                     s1은 포인터가 아닌 배열자체 이므로 s2의 주소를 s1에
                                     넣는다고 하면 배열의 구조가 없어지게 되고 포인터가
                                     되므로 선언한 것과 모순되기 때문에 Error가 나는 것이다.
 

/*
char s1[10] = "Hello!";
 char *s2;

 s2 = s1;                     // s1의 구조는 배열이지만 s1자체로는 주소를 의미하므로 
                                     s2 포인터 자체에 입력이 가능하다.
*/

 //for(int i=0; (s1[i] = s2[i])!='\0'; i++);
                                 // s2 포인터의 배열은 * (s2 + i) 를 의미(대채가능)하므로
                                     선언가능하다.

 //for(; (*s1++ = *s2++)!='\0';);
                                 // *s1++ 이 안되는 이유는 배열의 이름(s1)는 Constant이기
                                     떄문이다. 즉 참조만 가능하고 수정은 불가능하다.
                                     위의 *s1++은 s1++이 먼저 실행되기 떄문에 주소값 자체를
                                     수정하는 것이라서 Error가 난다.
 
 cout<<"s1 = "<<s1<<endl;
 cout<<"s2 = "<<s2<<endl;

 return 0;
}

-------------------------------------------------------------------------------
#include <iostream>

using namespace std;

int main(){

 char s1[10] = "Hello!";
 char *s2;

 s2 = s1;
 
 cout<<"s2 = "<<s2<<endl;
 cout<<"s2 = "<<*s2<<endl;
 cout<<"s2 = "<<&s2<<endl;

 return 0;
}

결과값 :
s2 = Hello!
s2 = H
s2 = 0012FF70
Press any key to continue

[C/C++] C++ 수업내용 10/2

Posted in 단체/ㄴ대학 전공 수업 by

const 변수로 선언된 students, exams을 2차원 배열로 동적 할당을 하여 입력한 시점에서 2차원 배열이 설정하도록 하였다.    

   #include <iostream>
     
    using std::cout;
    using std::endl;
    using std::cin;
    using std::fixed;
    using std::left;
     
    #include <iomanip>
   
    using std::setw;
    using std::setprecision;
   
    // function prototypes
    int minimum( int **, int, int );
    int maximum( int **, int, int );
    double average( int [], int );
    void printArray( int **, int, int );

    int main()
    {
       int students;   // number of students
       int exams;      // number of exams
       int i=0, j=0;

       cin>>students;
       cin>>exams;

       // initialize student grades for three students (rows)
       int ** studentGrades = new int* [students];

       for(i=0; i<students; i++)
            studentGrades[i] = new int [exams];
      
       for(i=0; i<students; i++)
           for(j=0; j<exams; j++)
               cin>>studentGrades[i][j];
   
       // output array studentGrades
       cout << "The array is:\n";
       printArray( studentGrades, students, exams );
   
       // determine smallest and largest grade values
       cout << "\n\nLowest grade: "
            << minimum( studentGrades, students, exams )
            << "\nHighest grade: "
            << maximum( studentGrades, students, exams ) << '\n';
   
       cout << fixed << setprecision( 2 );
   
       // calculate average grade for each student
       for ( int person = 0; person < students; person++ )
          cout << "The average grade for student " << person
               << " is "
               << average( studentGrades[ person ], exams )
               << endl;

       if(studentGrades){
           for(i=0; i<students; i++)
               delete[] studentGrades[i];
           delete[] studentGrades;
       }
   
       return 0;  // indicates successful termination
   
    } // end main
   
    // find minimum grade
    int minimum( int ** grades, int pupils, int tests )
    {
       int lowGrade = 100; // initialize to highest possible grade
   
       for ( int i = 0; i < pupils; i++ )
   
          for ( int j = 0; j < tests; j++ )
   
             if ( grades[ i ][ j ] < lowGrade )
                lowGrade = grades[ i ][ j ];
   
       return lowGrade;
   
    } // end function minimum
   
    // find maximum grade
    int maximum( int ** grades, int pupils, int tests )
    {
       int highGrade = 0;  // initialize to lowest possible grade
   
       for ( int i = 0; i < pupils; i++ )
   
          for ( int j = 0; j < tests; j++ )
   
             if ( grades[ i ][ j ] > highGrade )
                highGrade = grades[ i ][ j ];
   
       return highGrade;
   
    } // end function maximum
   
    // determine average grade for particular student           
    double average( int setOfGrades[], int tests )              
    {                                                           
       int total = 0;                                           
                                                                
       // total all grades for one student                      
       for ( int i = 0; i < tests; i++ )                        
          total += setOfGrades[ i ];                            
                                                                
       return static_cast< double >( total ) / tests;  // average
                                                                
    } // end function maximum
        
  // Print the array
  void printArray( int ** grades, int pupils, int tests )
  {
     // set left justification and output column heads
     cout << left << "                 [0]  [1]  [2] ";
 
     // output grades in tabular format
     for ( int i = 0; i < pupils; i++ ) {
 
        // output label for row
        cout << "\nstudentGrades[" << i << "] ";
 
        // output one grades for one student
        for ( int j = 0; j < tests; j++ )
           cout << setw( 5 ) << grades[ i ][ j ];
 
     } // end outer for
 
  } // end function printArray

-------------------------------------------------------------------------------
원본

    #include <iostream>
    
    using std::cout;
    using std::endl;
    using std::fixed;
    using std::left;
     
    #include <iomanip>
   
    using std::setw;
    using std::setprecision;
   
    const int students = 5;   // number of students
    const int exams = 3;      // number of exams
   
    // function prototypes
    int minimum( int [][ exams ], int, int );
    int maximum( int [][ exams ], int, int );
    double average( int [], int );
    void printArray( int [][ exams ], int, int );

    int main()
    {
       // initialize student grades for three students (rows)
       int studentGrades[ students ][ exams ];
      
       for(int i=0; i<students; i++)
           for(int j=0; j<exams; j++)
               cin>>studentGrades[i][j];
   
       // output array studentGrades
       cout << "The array is:\n";
       printArray( studentGrades, students, exams );
   
       // determine smallest and largest grade values
       cout << "\n\nLowest grade: "
            << minimum( studentGrades, students, exams )
            << "\nHighest grade: "
            << maximum( studentGrades, students, exams ) << '\n';
   
       cout << fixed << setprecision( 2 );
   
       // calculate average grade for each student
       for ( int person = 0; person < students; person++ )
          cout << "The average grade for student " << person
               << " is "
               << average( studentGrades[ person ], exams )
               << endl;
   
       return 0;  // indicates successful termination
   
    } // end main
   
    // find minimum grade
    int minimum( int grades[][ exams ], int pupils, int tests )
    {
       int lowGrade = 100; // initialize to highest possible grade
   
       for ( int i = 0; i < pupils; i++ )
   
          for ( int j = 0; j < tests; j++ )
   
             if ( grades[ i ][ j ] < lowGrade )
                lowGrade = grades[ i ][ j ];
   
       return lowGrade;
   
    } // end function minimum
   
    // find maximum grade
    int maximum( int grades[][ exams ], int pupils, int tests )
    {
       int highGrade = 0;  // initialize to lowest possible grade
   
       for ( int i = 0; i < pupils; i++ )
   
          for ( int j = 0; j < tests; j++ )
   
             if ( grades[ i ][ j ] > highGrade )
                highGrade = grades[ i ][ j ];
   
       return highGrade;
   
    } // end function maximum
   
    // determine average grade for particular student           
    double average( int setOfGrades[], int tests )              
    {                                                           
       int total = 0;                                           
                                                                
       // total all grades for one student                      
       for ( int i = 0; i < tests; i++ )                        
          total += setOfGrades[ i ];                            
                                                                
       return static_cast< double >( total ) / tests;  // average
                                                                
    } // end function maximum
        
  // Print the array
  void printArray( int grades[][ exams ], int pupils, int tests )
  {
     // set left justification and output column heads
     cout << left << "                 [0]  [1]  [2] ";
 
     // output grades in tabular format
     for ( int i = 0; i < pupils; i++ ) {
 
        // output label for row
        cout << "\nstudentGrades[" << i << "] ";
 
        // output one grades for one student
        for ( int j = 0; j < tests; j++ )
           cout << setw( 5 ) << grades[ i ][ j ];
 
     } // end outer for
 
  } // end function printArray

[C/C++] c++ 2차원 배열 동적 할당

Posted in 단체/ㄴ대학 전공 수업 by

#include <iostream>

using namespace std;

int main(){
    int i=0, j=0;
    int students, exams;

    cin>>students;
    cin>>exams;

    int **std = new int* [students];
    for(i=0; i<students; i++)
        std[i] = new int[exams];

    for(i=0; i<students; i++)
        for(j=0; j<exams; j++)
            std[i][j] = j;

    for(i=0; i<students; i++){
        for(j=0; j<exams; j++)
            cout<<std[i][j];
        cout<<endl;
    }

    if(std){
        for(i=0; i<students; i++)
            delete[] std[i];
        delete[] std;
    }

    return 0;
}

결과값 :

5 3                   // 입력 값 : 5 3
012                  // 출력값들
012
012
012
012
Press any key to continue

[C/C++] 랜덤(random) 값의 발생과 초기화

Posted in 단체/ㄴ대학 전공 수업 by

1. VC++ 컴파일러 환경에서 랜덤 값을 발생시키기 위한 함수로 rand()를 제공한다.
   rand()함수는 0부터 RAND_MAX(32767로 정의)까지의 숫자 중에서 임의의 숫자를
   돌려준다.

2. RAND_MAX는 헤더 파일 <stdlib.h>에 아래와 같이 상수로 정의되어 있다.
            #define RAND_MAX 0x7FFF

3. rand() 함수를 초기화해주지 않으면 매번 실행할 때마다 똑같은 순서의 숫자들이
   생성된다. 따라서 rnad() 함수를 사용하기 전에 srand() 함수를 이용해서 초기화를
   해야 한다. srand() 함수는 seed로 임의의 정수를 지정할 수 있는데, time() 함수로
   시스템의 시간을 구한 후 이를 seed 값으로 사용하면 항상 seed가 달라지기
   때문에 일반적으로 아래와 같이 사용한다.
            seed = time(NULL);
            srand(seed);
            == srand(time(NULL)); 위의 2개를 이와 같이 써도 무방하다.

4. rand(), srand() 함수를 사용하기 위해서는 반드시 <stdlib.h> 파일을 헤더 파일로
   삽입해야 한다. 또한 time() 함수를 사용하기 위해서는 반드시 <time.h> 파일을
   헤더 파일로 삽입해야 한다.

5. 특정 범위의 랜덤 값을 발생시키기 위해서는 나머지 연산자와 덧셈을 이용한다.
  - 0부터 9까지의 숫자를 발생  : rand() % 10                     // 0~9
  - 1부터 10까지의 숫자를 발생 : (rand() % 10) + 1             // (0~9)+1 => 1~10
  - a부터 b까지의 숫자를 발생  : (rand() % (b-a+1)) + a     // (0~b-a)+a => a~b

[C/C++] delay, Sleep, toupper, tolower 함수

Posted in 단체/ㄴ대학 전공 수업 by

Ⅰ. Delay 함수 & Sleep 함수

1. delay()

 - 원형 void delay(unsigned milliseconds); // milliseconds 는 1/1000초

 - ex) delay(1000);         // 1초 동안 지연

2. Sleep()

 - 원형 void sleep(unsigned seconds); // seconds 는 1초

 - ex) sleep(10);         // 10초 동안 지연

#include<windows.h> 해야한다...


Ⅱ. toupper 함수 & tolower 함수

1. toupper() - 소문자를 대문자로 변환
2. tolower() - 대문자를 소문자로 변환

[과제] Automatic Photo Pop-up

Posted in 단체/ㄴ대학 전공 수업 by

컴퓨터 그래픽스 첫번째 과제...
컴퓨터 그래픽에 관한 최신기술을 조사하여 ppt로 작성하는 것인데요.
검색하면서 찾아보는데, 그래픽 카드가 어쩌구... 이런 내부적인 기술만 나오고
외적으로 머머가 발전했다~ 이런건 교수님이 말한것 빼곤(말한건 안된다해서),
아무리 찾아봐도 안나오는것 같네요... ㅡㅡ;
찾다찾다, 신기한 기술 2D 이미지를 3D화 시켜주는 기술을 찾았습니다. lol
기술이 좀 어설픈 감이 없지않아 있지만 그래도 할게없으니... 이걸로 선택해서 검색하며 자료를 모아보는데, 다 내용이 영어야!!
내용 해석이 안되서 ppt와 내용을 고x대학 어느분이 Automatic Photo Pop-up에 대한 ppt 하신걸 가지고와 인용해서 사용좀 했습니다. JungLee님 사랑해요♡~


이 파일에 모든내용이 다들어있는거 같은데 읽질 못해서...ㅜ




Ⅰ. 알고리즘 개요 및 효과

 ⑴ 한 장의 이미지로부터 3차원 모델을 자동생성
     → 여러 개의 빌보드(Billboard) 이용
     → 아동용 Pop-up Book Illustration 효과
 ⑵ 장면 내의 방향으로부터 판단되는 기하 클래스를 모델링
     → 입력 이미지의 각 부분을 Labeling
       cf) 바닥면, 하늘, 수직면, ...
 ⑶ 광범위한 장면에 대하여 매우 잘 동작함
 ⑷ 모든 이미지에 대하여 잘 동작하는 것은 아님

     → 접근방식의 내재적인 모호함과 통계적인 속성 떄문


Ⅱ. 발생되는 문제

 ⑴ 복잡한 장면
     ex) 수많은 나무나 사람이 포함된 장면
          → 일일이 레이블하기 어려움
 
⑵ 경사진 면에 대한 고려 부재
 ⑶ 다중의 Ground-Parallel 면에 대응하기 어려움

      ex) 계단
 ⑷ 레이블 오류
 ⑸ 수직 영역으로 표기된 부분의 중복
 ⑹ 수평선 추청 오류
 
 

Ⅲ. 결론 및 향후연구
 
 ⑴ 실외의 2차원 이미지에서 보기에 그럴듯한 3차원 물체를 자동 생성
 ⑵ 아직 자동 Single-View 복원에서 풀어야 할 문제가 많음

     → Segmentation 기법 향상
     → 이미지로부터 수직영역의 회전 방향 추정
     → 실내의 장면에까지 확장