NO.1 레이디그레이 400
03 Apr 2021- 촬영 기간 : 2018~2021
- 카메라 : 로모그래피 심플유즈
- 필름 : 레이디그레이 400(Lady Grey 400)
개발 환경
메모리는 크게 3가지 영역으로 나뉨.
text 영역 메모리 설계
text | 1MB | 0X00000000~0X000FFFFF |
동작모드 스택을 메모리에 설계
USR,SYS | 2MB | 0X00100000~0X002FFFFF |
SVC | 1MB | 0X00300000~0X003FFFFF |
IRQ | 1MB | 0X00400000~0X004FFFFF |
FIQ | 1MB | 0X00500000~0X005FFFFF |
ABT | 1MB | 0X00600000~0X006FFFFF |
UND | 1MB | 0X00700000~0X007FFFFF |
테스크 스택, 전역변수, 동적 할당 영역 설계
테스크 스택 | 64MB | 0X00800000~0X047FFFFF |
전역 변수 | 1MB | 0X04800000~0X048FFFFF |
동적 할당 | 55MB | 0X04900000~0X07FFFFFF |
Entry.S
익셉션 벡터 테이블
#include "ARMv7AR.h" ;동작모드 전환 비트 헤더파일
#include "MemoryMap.h" ;메모리맵 주소 헤더파일
.text
.code 32
.global vector_start
.global vector_end
vector_start:
LDR PC, reset_handler_addr
LDR PC, undef_handler_addr
LDR PC, svc_handler_addr
LDR PC, pfrch_abt_handler_addr
LDR PC, data_abt_handler_addr
B .
LDR PC, irq_handler_addr
LDR PC, fiq_handler_addr
reset_handler_addr: .word reset_handler
undef_handler_addr: .word reset_handler
svc_handler_addr: .word reset_handler
pfrch_abt_handler_addr: .word reset_handler
data_abt_handler_addr: .word reset_handler
irq_handler_addr: .word reset_handler
fiq_handler_addr: .word reset_handler
vector_end:
reset_handler:
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_SVC ;SVC 동작모드 비트
MSR cpsr, r1 ;cpsr에 동작모드 비트를 설정
LDR sp, =SVC_STACK_TOP ;스택포인터에 SVC스택 탑 메모리 주소 설정
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_IRQ
MSR cpsr, r1
LDR sp, =IRQ_STACK_TOP
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_FIQ
MSR cpsr, r1
LDR sp, =FIQ_STACK_TOP
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_ABT
MSR cpsr, r1
LDR sp, =ABT_STACK_TOP
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_UND
MSR cpsr, r1
LDR sp, =UND_STACK_TOP
MRS r0, cpsr
BIC r1, r0, #0X1F
ORR r1, r1, #ARM_MODE_BIT_SYS
MSR cpsr, r1
LDR sp, =USRSYS_STACK_TOP
BL main
dummy_handler:
B .
.end
스택은 메모리를 반대방향으로 사용하기 때문에 스택의 꼭대기 주소를 스택포인터로 지정한다.
ARMv7AR.h
동작모드 전환 비트 헤더파일
#define ARM_MODE_BIT_USR 0X10
#define ARM_MODE_BIT_FIQ 0X11
#define ARM_MODE_BIT_IRQ 0X12
#define ARM_MODE_BIT_SVC 0X13
#define ARM_MODE_BIT_ABT 0X17
#define ARM_MODE_BIT_UND 0X1B
#define ARM_MODE_BIT_SYS 0X1F
#define ARM_MODE_BIT_MON 0X16
MemoryMap.h
메모리맵 주소, 사이즈, 스택 탑 위치 헤더파일
#define INST_ADDR_STATRT 0
#define USRSYS_STACK_START 0X00100000
#define SVC_STACK_START 0X00300000
#define IRQ_STACK_START 0X00400000
#define FIQ_STACK_START 0X00500000
#define ABT_STACK_START 0X00600000
#define UND_STACK_START 0X00700000
#define TASK_STACK_START 0X00800000
#define GLOBAL_STACK_START 0X04800000
#define DALLOC_STACK_START 0X04900000
#define INST_MEM_SIZE (USRSYS_STACK_START - INST_ADDR_STATRT)
#define USRSYS_STACK_SIZE (SVC_STACK_START - USRSYS_STACK_START)
#define SVC_STACK_SIZE (IRQ_STACK_START - SVC_STACK_START)
#define IRQ_STACK_SIZE (FIQ_STACK_START - IRQ_STACK_START)
#define FIQ_STACK_SIZE (ABT_STACK_START - FIQ_STACK_START)
#define ABT_STACK_SIZE (UND_STACK_START - ABT_STACK_START)
#define UND_STACK_SIZE (TASK_STACK_START - UND_STACK_START)
#define TASK_STACK_SIZE (GLOBAL_STACK_START - TASK_STACK_START)
#define DALLOC_MEM_SIZE (55*1024*1024)
//스택 사이의 패딩(padding)을 위한 4바이트 비우기
#define USRSYS_STACK_TOP (USRSYS_STACK_START + USRSYS_STACK_SIZE - 4)
#define SVC_STACK_TOP (SVC_STACK_START + SVC_STACK_SIZE - 4)
#define IRQ_STACK_TOP (IRQ_STACK_START + IRQ_STACK_SIZE - 4)
#define FIQ_STACK_TOP (FIQ_STACK_START + FIQ_STACK_SIZE - 4)
#define ABT_STACK_TOP (ABT_STACK_START + ABT_STACK_SIZE - 4)
#define UND_STACK_TOP (UND_STACK_START + UND_STACK_SIZE - 4)
Makefile
ARCH = armv7-a
MCPU = cortex-a8
CC = arm-none-eabi-gcc
AS = arm-none-eabi-as
LD = arm-none-eabi-ld
OC = arm-none-eabi-objcopy
LINKER_SCRIPT = ./milktea.ld
MAP_FILE = build/milktea.map
ASM_SRCS = $(wildcard boot/*.S)
ASM_OBJS = $(patsubst boot/%.S, build/%.os, $(ASM_SRCS))
C_SRCS = $(wildcard boot/*.c)
C_OBJS = $(patsubst boot/%.c, build/%.o, $(C_SRCS))
INC_DIRS = include
milktea = build/milktea.axf
milktea_bin = build/milktea.bin
.PHONY: all clean run debug gdb
all: $(milktea)
clean:
@rm -fr build
run: $(milktea)
qemu-system-arm -M realview-pb-a8 -kernel $(milktea) -nographic
debug: $(milktea)
qemu-system-arm -M realview-pb-a8 -kernel $(milktea) -S -gdb tcp::1234,ipv4
gdb:
arm-none-eabi-gdb
$(milktea): $(ASM_OBJS) $(C_OBJS) $(LINKER_SCRIPT)
$(LD) -n -T $(LINKER_SCRIPT) -o $(milktea) $(ASM_OBJS) $(C_OBJS) -Map=$(MAP_FILE)
$(OC) -O binary $(milktea) $(milktea_bin)
build/%.os: $(ASM_SRCS)
mkdir -p $(shell dirname $@)
$(CC) -march=$(ARCH) -mcpu=$(MCPU) -I $(INC_DIRS) -c -g -o $@ $<
build/%.o: $(C_SRCS)
mkdir -p $(shell dirname $@)
$(CC) -march=$(ARCH) -mcpu=$(MCPU) -I $(INC_DIRS) -c -g -o $@ $<
여러개의 QR코드를 동시에 생성하고 출력하기 쉽도록 한장으로 편집이 되게끔 하는 목적으로 진행. ***
선택메뉴
QR코드 데이터 입력 ex) hello
결과물
QR코드 여러개 데이터 입력
결과물
실행폴더내에 QR코드 데이터가 입력된 텍스트 파일 저장
읽으려는 텍스트 파일명을 입력(‘.txt’ 제외하여 입력)
결과물
각종 보드의 핀맵이나 정의들을 항상 찾기 번거로워 배경화면에서 바로 이용할 수 있는 방안을 고민해서 만들어 보았다.
드래그 앤 드랍으로 화면을 구성해준다.
속성창을 통해 스크립트 편집을 할 수 있다.
메인 배경(wallpaper) 스크립트
'use strict';
let timer=0;
shared.work_state=0; //shared=외부 변수 참조
shared.bt_state=0;
/**
* @param {Boolean} value - for property 'visible'
*/
//레이어 메인 반복문
export function update(value) {
switch(shared.bt_state)
{
case 'ardu on':
fade_in("UNO");
fade_in("NANO");
break;
case 'ardu off':
fade_out("UNO");
fade_out("NANO");
break;
default:
console.log('break');
break;
}
return value;
}
//fade in
export function fade_in(value) {
if(thisScene.getLayer(value).alpha<=1) //alpha=투명도
{
timer+= engine.frametime; //월페이퍼 엔진 프레임타임
thisScene.getLayer(value).alpha=timer*0.7;
}
console.log('fade_in'); //콘솔 확인용
console.log(value);
}
//fade out
export function fade_out(value) {
if(thisScene.getLayer(value).alpha>=0)
{
shared.work_state=1;
timer-= engine.frametime;
thisScene.getLayer(value).alpha=timer*0.7;
}
else
{
shared.work_state=0;
shared.bt_state=0;
}
console.log('fade_out');
console.log(value);
}
버튼(arduino_bt) 스크립트
'use strict';
/**
* @param {Boolean} value - for property 'visible'
*/
export function update(value) {
return value;
}
/**
* @param {Boolean} value - for property 'visible'
*/
//레이어 초기화
export function init(value) {
thisScene.getLayer("UNO").alpha=0; //투명도 0
thisScene.getLayer("NANO").alpha=0;
thisScene.getLayer("UNO").visible=true; //보이기 허용
thisScene.getLayer("NANO").visible=true;
return value;
}
/**
* @param {ICursorEvent} event
*/
//레이어 클릭 이벤트 함수
export function cursorClick(event) {
if(shared.work_state==0){
if(shared.bt_state=='ardu on') //외부 변수에 클릭 레이어 저장
shared.bt_state='ardu off';
else if(shared.bt_state==0)
shared.bt_state='ardu on';
console.log("ardu on");
}
}
스크립트 실행