로봇제어
==================================Outline====================================
웹 프로그래밍
- GPIO를 통한 웹서비스 메시지 제어
----------------------------------------------------------------------------
//PiFace는 따로 장치를 구입해서 장착해야되기 때문에 교재의 해당 부분은 넘어가도록 한다.
교재 p/200
웹 프로그래밍
네트워크를 사용하기 위해서는 웹 서비스를 제공하는 서버가 필요하다.
플라스크는 파이썬을 위한 마이크로 웹 프레임워크로 Werkzeug, Jinja2를 기반으로 하는 오픈소스 서비스이다.
윈도우의 경우 IIS(Internet Information Services)를 제공한다. 무료로 제공되는 서비스 중에 톰캣이 있다.
//Apache Tomcat - http://tomcat.apache.org/
HTML은 변수를 사용할 수 없음으로 소스코드가 고정 되어 있다. 변수를 사용하여 유동성 있는 서비스를 제공하기 위해서는 ASP, JSP, PHP으로변수를 적용한 후 다시 HTML로 변환해야 한다.
서비스 제공자 - ASP: Microsoft
JSP: JAVA
PHP: C문법 적용
일반적으로 웹 서비스를 제공하기 위해서는 웹을 표현하는 html과 ASP, JSP, PHP 중 택 1하여 사용하여야 한다.
//ASP는 window운영체제를 사용해야 하지만 JSP와 PHP는 운영체제를 가리지 않고 사용할 수 있다.
- GPIO를 통한 웹서비스 메시지 제어
GPIO제어를 통한 웹서비스 메시지를 제어하는 것을 해보자.
p/202~p/211을 참고한다.
우선 파이선PIP를 설치한다.
apt-get install python-pip
python-pip 설치 후 플라스크를 설치한다.
pip install flask
교재 p/203의 "hello_flask.py"를 작성한다.
[hello_flask.py]
입력을 마친 후 실행시킨다.
입력한 IP와 포트번호를 웹에 입력하면 자신이 설정한 메시지가 뜬다.
웹에서 해당 서비스를 요청한 경우 이를 라즈베리파이에서 확인할 수 있다.
플라스크 서버에 HTML 웹페이지를 구성하고, 웹브라우저를 통해 클라이언트가 접속했을 때 서버의 시간을 출력해 보자.
교재 p/205에 나와있는 "gettime.py"를 작성하고 작성한 파일과 동일한 위치에 "templates"라는 폴더를 만든다. 그런 다음 main.html 파일을 작성하여 만든 폴더에 넣는다.
[gettime.py]
[main.html]
플라스크를 기반으로 GPIO 포트 모니터링
플라스크를 이용하여 웹을 통해 라즈베리 파이를 제어해본다. 핀에 on/off 상태를 웹서버에서 확인할 수 있도록 만든다.
port 23, 24, 25를 사용하도록 한다.
[gpio.html]
[check_switch.py]
==================================Outline====================================
메모리 출력 함수 'memory_display'----------------------------------------------------------------------------
메모리 출력 함수 'memory_display'
메모리를 헥사뷰로 출력하는 함수 'memory_display'를 만들어보자.
//'memory_modify'함수를 복사해서 필요한 부분만 수정하면 편하다.
사용자가 출력하고자하는 메모리의 시작 위치를 입력 받은 후 헥사뷰를 실행시켜 16씩 출력 시킨다. 페이지를 초과하는 경우 사용자로부터 아무키나 입력받으면 다음 페이지를 출력 시키고 ‘q' 혹은 'Q' 입력할 시 출력을 멈춘다.
void memory_display(){
unsigned int uiAddr;
unsigned int uiVal;
char cInput;
while(1)
{
printf("Please input an address to display [%08X - %08X] : ", vpMem_start, vpMem_end);
scanf("%x", &uiAddr);
if('\n'==getchar());
if(uiAddr < (unsigned int)vpMem_start || uiAddr > (unsigned int)vpMem_end)
{
printf("Wrong address \n");
continue;
}
break;
}
while( (uiAddr)< ( (unsigned int)vpMem_end ) )
{
hexaview((void *)uiAddr, 16*16);
uiAddr = uiAddr + (16*16);
if(uiAddr>(unsigned int)vpMem_end)
{
printf("Memory displayed\n");
return;
}
printf("Please enter any to continue(stop for 'Q')\n");
cInput = getch();
if(cInput == 'q' ||cInput == 'Q')
{
printf("Memory display interrupted\n");
return;
}
}
return;
}
헥사뷰 주소 값이 ‘vpMem_end‘를 초과할 경우 해당 자리에서 헥사뷰를 멈추도록 코딩한다.
이를 위해 헥사뷰를 수정한다.
void hexaview(void * vP, unsigned int uiLen)
{
unsigned int uiCnt;
unsigned int uiLine;
printf("===============================================================================\n");
printf(" Address Hexa ASCII \n");
printf("-------------------------------------------------------------------------------\n");
for (uiLine = 0; uiLine < uiLen; uiLine += 16)
{
if(vP > vpMem_end)
return;
printf(" %08X ", vP);
for(uiCnt=0; uiCnt<16; ++uiCnt)
{
if(vP > vpMem_end)
{
while(uiCnt<16)
{
printf(" ");
vP = (char *)vP + 1;
++uiCnt;
}
break;
}
printf("%02X ", *((unsigned char *)vP));
vP = (char *)vP + 1;
}
vP = (char *)vP - 16;
putchar(' ');
for(uiCnt=0; uiCnt<16; ++uiCnt)
{
if(vP > vpMem_end)
{
putchar('\n');
return;
}
if (32 > *((unsigned char *)vP))
{
putchar('.');
}
else if(127 < *((unsigned char *)vP))
{
putchar('.');
}
else
{
printf("%1c", *((unsigned char *)vP));
}
vP = (char *)vP + 1;
}
putchar('\n');
}
putchar('\n');
return;
}
실행시킨 화면은 다음과 같다.
//코딩을 할 때 변수와 함수명의 형식에 일관성이 있어야 한다.
프로그램 실행 함수 ‘program_execute'
로드함수를 사용하여 프로그램을 메모리에 적재한 후, 이것을 실행시키는 ‘program_execute'를 만들어보자. 사용자가 입력하는 명령어는 'GO'이다. 전역 변수를 만들어 주고 로드 상태에 따라 해당 변수의 값을 바꿔준다.
#define LOAD_ON 1
#define LOAD_OFF 0
unsigned int uiLoad;
‘program_execute'가 실행되면 로드 되어 있는 프로그램이 실행되고 난 후 다시 메뉴로 돌아가야 한다. 이를 위해 어셈블리 코드로 만든 ’stst‘, ’ldst‘함수를 사용한다.
레지스터 변수들을 담고 있는 ’context’를 ‘stTempState‘라는 이름으로 선언해준다. 이 구조체는 로드된 프로그램을 실행시키고 다시 메뉴로 돌아갈 수 있게 만들어주는 징검다리 역할을 한다.
구조체의 ‘esp’에는 ‘vpStack’, ‘eip’에는 ‘vpCode’(로드된 프로그램), ‘eax’에는 ‘stOld_state’의 주소를 담아준다.
세팅을 끝낸 ‘stTempState‘를 ’ldst‘의 인자로 전달한다. 'eip'가 적재된 프로그램의 코드 영역을 가리키고 있음으로 프로그램이 실행된다. 프로그램이 수행되고 나면 레지스터를 ’stOld_state’에 저장된 상태로 되돌려 주어야 한다. ‘stOldState’를 'eax'에 넣어준 것이 바로 'stOldState'가 가진 레지스터의 상태로 복구 시켜주기 위함이다.
void program_execute()
{
context stTempState;
if(uiLoad == LOAD_OFF)
{
printf("No loaded program.\nPlease load program by using 'LOAD' command.\n");
return;
}
memset(&stTempState, 0, sizeof(context));
stTempState.esp = (unsigned int)vpStack;
stTempState.eip = (unsigned int)vpCode;
stTempState.eax = (unsigned int)(&stOld_state);
ldst(&stTempState);
printf("System Panic!\n");
return;
}
적재된 프로그램 실행 후 레지스터를 ‘stOldState’의 값으로 복구 시키기 위해 어셈블리로 'init'함수를 만들어준다. C에서도 호환하여 사용하기 위해 언더바(_)를 붙혀준다.
(진행중)
.386
.MODEL FLAT
PUBLIC _INIT
EXTERN _smart1:NEAR32
EXTERN _ldst:NEAR32
.code
_start:
_INIT PROC NEAR32
push eax ;'&stOldState' 저장
call _smart
call _ldst
_INIT ENDP
'코스웨어 > 15년 스마트컨트롤러' 카테고리의 다른 글
20151027 - 5번 - 김성주 - 어셈블리 소스 파일 (0) | 2015.10.27 |
---|---|
20151027_ContextSwitchig_소스&결과 (0) | 2015.10.27 |
20151027 -여지윤- 소스파일 (0) | 2015.10.27 |
20151026-23번-업무일지-이량경_ASM { go함수 } , linux { 웹페이지를 통해 LED제어 } (13) | 2015.10.27 |
20151022-22번-우대희 LOAD함수 구현 (5) | 2015.10.23 |
load함수(우대희군이 알려준 방법으로 구현) (2) | 2015.10.23 |
load함수 참고하세요.. (6) | 2015.10.23 |
20151020-21번-여지윤 GPIO6/모니터프로그램 (15) | 2015.10.21 |