- JoyStick
- JoyStick의 input은 아날로그 시그널이므로 이를 컴퓨터가 이해할 수 있도록 디지털 시그널로 바꿔줘야 한다.
- ADC(Analog-to-Digital Converters)는 아날로그 시그널로 들어오는 voltage 값을 디지털(bit sequence)로 바꿔준다.
- 연속적인 analog값을 일정 주기로 sampling해서 디지털로 변환할 수 있다. 이때 sampling의 주기가 짧을수록 더 정교한(원래 아날로그 값과 비슷한) 데이터를 표현할 수 있다.
- sampling의 주기에 따라 같은 아날로그 시그널도 서로 다른 여러 개의 디지털 시그널로 표현될 수 있다.
-
- ADC에 사용 가능한 bit 수에 따라서도 디지털 시그널의 정교함이 달라진다. 0-10 사이의 값을 가지는 아날로그 시그널을 디지털화할 때, 12bit를 사용한다면 4096가지 다른 지점을 표현할 수 있고, 3bit를 사용한다면 8가지 다른 지점을 표현할 수 있게 된다.
- Obtaining ADC values by Joystick
/*Store ADC14 conversion results: ADC를 통해 입력받은 현재 위치를 아날로그->디지털로 전환한다.*/
/*그리고 이 디지털 값을 resultsBuffer[]에 저장한다.*/
resultsBuffer[0] = ADC14_getResult(ADC_MEM0); /*x좌표 위치 저장*/
resultsBuffer[1] = ADC14_getResult(ADC_MEM1); /*y좌표 위치 저장*/
/*%5d 사용: resultsBuffer는 integer값임을 알 수 있다.*/
sprintf(string, "X: %5d", resultsBuffer[0]);
Graphics_drawStringCentered(&g_sContext,
(int8_t *)string,
8,
64,
50,
OPAQUE_TEXT);
sprintf(string, "Y: %5d", resultsBuffer[1]);
Graphics_drawStringCentered(&g_sContext,
(int8_t *)string,
8,
64,
70,
OPAQUE_TEXT);
- sprintf() function
- printf는 출력하고자 하는 값을 display에 나타내는 반면, sprintf는 출력값을 쓰고자 하는 string에 값을 저장한다.
- sprintf 예시 1)
char mesg[20];
char hello[10] = "hello";
char world[10] = "world";
sprintf(mesg, "%s, %s!", hello, world);
printf("%s\n", mesg);
/*출력값: hello, world!*/
- sprintf 예시 2)
#include <stdio.h>
#define MAX 20
int main(void){
char first[MAX];
char last[MAX];
char formal[2*MAX+10];
double prize;
puts("Enter your first name:");
gets(first);
puts("Enter your last name:");
gets(last);
puts("Enter your prize money:");
scanf("%lf", &prize);
sprintf(formal, "%s, %-19s: $%6.2f\n", last, first, prize);
puts(formal);
return 0;
}
- Real-Time Operating Systems(RTOS)
- RTOS가 필요한 이유
- Task scheduling과 I/O handling이 자동으로 된다.
- Task scheduling: To handle multiple tasks with different invocation rates or priorities(우선순위 기준으로 task 수행 - 동일한 우선순위를 가진다면 time slice를 한번씩 돌아가면서 실행한다.)
- I/O handling: To handle multiple interrupts from internal and/or external events(interrupt를 통해 하던 일을 중단하고 프로세스 내에 어떤 일을 수행하도록 끼워넣을 수 있다.)
- 프로그래머가 while문을 작성하면, while문 내의 코드들이 순서대로 실행된다. 따라서 최악의 경우, 지금 막 condition을 check하는 코드를 지났는데 input값이 변경될 수 있다. 이러면 while문을 끝까지 돌고 다음 while문 주기가 돌아와서야 변경된 input값이 반영된 결과를 얻을 수 있다.
- GUI는 OS가 아니다. main OS는 보통 커널이라고 부른다. 이 커널 위에 GUI만 바꾸면 새로운 OS처럼 보이도록 할 수 있다.
- Android는 Linux 커널 기반의 OS이다. Ubuntu와 Andriod는 동일하게 Linux 기반의 OS인데, GUI만 다른 경우에 해당한다.
- RTOS Application Code Example
void main(void){
/*Initialize(but don't start)the RTOS: RTOS를 application레벨에서 사용한다고 설정*/
InitRTOS();
/*RTOS가 어떤 동작을 할 것인지 설정. OS는 등록된 task를 어떤 scheduling을 사용해 실행할 것인지 결정함*/
StartTask(RespondToButton, HIGH_PRIORITY);
StartTask(CalculateTakeLevels, LOW_PRIORITY);
/*RTOS 실행시키기(this function never returns)*/
StartRTOS();
- RTOS: Tasks
- Task들은 우선순위 순서대로 scheduling된다.
- 각 Task들은 unique하게 가지는 context가 있다. (이 부분은 다른 task에 의해 접근이 불가하다.)
- register values
- program counter
- stack
- 여러 개의 task가 priority에 따라 하나씩 실행된다. (Multitasking) 이때 사용되는 방법은 priority-driven scheduler이다. prioirty순으로 실행할 task가 선택된다. 특정 task의 priority가 현재 수행하는 task보다 높아지면 현재 수행하던 것을 멈추는 방법이 있고, 현재 수행 task가 끝날 때까지 기다린 후 수행하는 방법도 있다.
- 만약 동일 priority를 가지는 여러개의 task가 존재한다면 time-slicing을 통해 1ms씩 context 로딩->수행-> context저장의 과정을 거친다.
- Preemption
- Preemptive RTOS: 더 높은 priority의 task가 나타나면 기존에 돌고 있던 task의 context를 저장하고 중단한 후 새로운 task를 실행한다.
- Non-preemptive RTOS: 더 높은 priority의 task가 나타나면 기존에 돌던 task를 모두 마친 후 새 task를 실행한다.
- Scheduler
- Scheduler는 현재 진행중인 task와 새로운 task간의 priority 비교, 다음 실행할 task 지정 등의 일을 한다. 따라서 좁은 관점에서 scheduler 또한 하나의 task라고 할 수 있겠다.
- 각 task들은 다음 특성 값을 가진다:
- priority
- state(running/ready/blocked/interrupted)
- 여러 개의 task들이 하나의 global memory에 접근할 수 있으므로 특정 task가 global memory값을 수정하는 와중에 다른 task가 값을 읽어들인다면 두 task간의 정보 차이가 발생할 수 있다. 이는 공유 자원인 global memory에 하나 이상의 task가 동시에 접근했기 때문이다. 이런 문제를 피하기 위해서 flag을 설정한다.
- global memory에서 생기는 이런 문제를 사거리의 다른 방향에서 여러 대의 차가 접근하는 경우에 대입해서 이해해볼 수 있다. 이 경우 사거리의 중심부에서 차가 충돌하는 경우를 피하기 위해 flag를 설치한 후 이 flag을 먼저 가져간 차량이 먼저 사거리를 지나도록 하면 된다. flag을 가진 차량이 사거리를 지난 후에는 flag가 원위치로 돌아간다.
- mutual exclusion: 하나의 task만이 critical section에 접근할 수 있다. 위의 사거리 예시에서는 깃발이 위치한 영역에 한번에 한 대의 차량만이 접근할 수 있다는 의미이다.
- critical section: 코드 상에서 resource가 공유되고 있는 부분.
- Semaphore
- Flag = Semaphore
- 여러 개의 flag(semaphore)가 존재할 수도 있다.(binary semaphore의 경우 깃발이 1개)
- Get and Give: semaphore를 가져오는 것/원위치에 가져다 놓는 것
- Take and Release
- Pend and Post
- P and V
'Embedded System' 카테고리의 다른 글
[Lab 10] (0) | 2022.12.05 |
---|---|
[Lecture 11] LCD (1) | 2022.12.05 |
댓글