임베디드 소프트웨어와 범용 소프트웨어
임베디드 소프트웨어는 보드에서 돌아가는 내장형 소프트웨어를 말한다. OS도 올라가고 GUI도 올라갈 수 있다. 즉, 특정한 목표를 위해 만들어져 보드에서 돌아가는 내장형 소프트웨어를 말한다.
범용 소프트웨어는 다양한 환경에서 돌아가는 범용 소프트웨어를 말한다.
kernel의 핵심
커널이 하는 일중에 가장 중요한 일을 꼽으라면 아무래도 job scheduling을 꼽을 수 있겠다.
그리고 job scheduling을 위해 가장 중요한 것은 단연 context switching이다.
그리고 context switching을 위해 반드시 필요한 것이 process control block이다.
process control block(PCB) for context switching
PCB에 들어있는 정보
-
OS가 관리상 사용하는 정보
- Process state, Process ID
- Scheduling information, Priority
-
CPU 수행관련 hardware 값
- Program counter, registers
-
momory 관련
-
파일 관련
위 정보를 C언어의 struct 구조체로 관리하면서, 이 내용을 복사하여 대피하고 다시 사용하는 식으로 context switching이 이루어진다.
스레드에서도 context switching이 일어난다
스레드도 context switch이 일어난다. 하지만 스레드의 경우 stack영역을 제외한 나머지 영역을 공유하고 있기 때문에 context switching에 걸리는 시간이 엄청 빠른 것이다.
RTOS 셋팅
ioc 파일 셋팅
- 호환성 확보를 위해서 RTOS에는 interface가 정의되어 있다. 어떤 interface를 사용할 것인지 정해줘야 한다.
- 그리고 RTOS의 커널이 job scheduling을 하기 위해서는 Tick이 필요한다. 그 Tick(system clock의 기준시간)을 어디서 얻을건지 정해줘야 한다.(F429ZI 보드의 내장 HW Timer를 사용하면 되는 부분)
- os에서 사용할 Tick으로 그냥 디폴트로 설정되어있는 Systick을 사용하는것은 적절하지 않다. 왜냐하면 Systick은 타이머 우선순위가 굉장히 낮기 때문이다. 그래서 os에 타임슬라이스용 틱을 쓸꺼면 반드시 하드웨어 타이머를 쓰는 것이 좋다.
- Tick은 1ms 혹은 3ms로 정하는데, 이것은 시스템에 따라 다를 수 있다.
- "Middleware and Software" 탭에서 FREERTOS를 선택한다.
- Interface로 CMSIS_V2(cortex microcontroll system interface standard version 2)를 선택한다.
- "System core" 탭에서 SYS를 선택한다.
- Time basesource를 Systck에서 TIMER11(하드웨어 타미어)
- 다시 "Middleware and Software" 탭에서 FREERTOS 돌아온다.
- "Advanced settings"탭에서 Newlib settings에서 USE_NEWLIB_REENTRANT값을 enable로 바꿔준다.
- 그렇게 다 설정을 하고 저장하면 freertos.c와 stm32f4xx_hal_timebase_tim.c가 생성된 것을 확인할 수 있다.
main.c에서 StartDefaultTask()에서 주의할 것
- main.c의 StartDefaultTask() 함수에서 반드시 osDelay(1)이 있어야지 context switching이 일어날 수 있다. 이 시간이 없다면 context switching이 일어날 시간이 전혀 없어서 다른 task로 switching이 될 수 없다. 그러므로 main.c의 StartDefaultTask() 함수에서 osDelay(1)를 절대 빼면 안된다.
- 즉 다시말해, main.c에 생성된 StartDefaultTask()는 RTOS가 제공하는 기본적인 스케쥴링을 위해 디폴트로 존재해야 하는 태스크 함수인 것이다.
void StartDefaultTask(void *argument)
{
for(;;)
{
osDelay(1);
}
}
Thread(Task) 추가하는 법
- cube IDE의 .ioc설정탭에서 GUI를 통해서 Task를 추가할 수 있다.
- "Middleware and Software" 탭에서 FREERTOS를 선택한다.
- "Task and Queue" 탭을 선택해준다.
- Task 부분에서 add버튼을 누르고 생성해주면 된다.
Mutex 추가하는법
- cube IDE의 .ioc설정탭에서 GUI를 통해서 Mutex를 추가할 수 있다.
- "Middleware and Software" 탭에서 FREERTOS를 선택한다.
- "Mutexes" 탭을 선택해준다.
- Task 부분에서 add버튼을 누르고 생성해주면 된다.
extern osMutexId_t myMutex01Handle;
if (osMutexAcquire(myMutex01Handle, 1000) == osOK)
{
...
osMutexRelease(myMutex01Handle);
}
event 추가하는법
- cube IDE의 .ioc설정탭에서 GUI를 통해서 event를 추가할 수 있다.
- "Middleware and Software" 탭에서 FREERTOS를 선택한다.
- "Events" 탭을 선택해준다.
- Task 부분에서 add버튼을 누르고 생성해주면 된다.
TCP/IP 통신을 위한 셋팅
- main.c의 MX_ETH_Init() 함수쪽을 보면 mac address가 제조사 부분은 제대로 되어있는데, 그다음에 내 주소 부분은 00 00 00으로 되어있는 것을 볼 수 있다. 이것을 나의 것에 맞게 바꿔줘야 통신이 된다.
static void MX_ETH_Init(void)
{
...
heth.Instance = ETH;
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x00;
heth.Init.MACAddr = &MACAddr[0];
heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
heth.Init.TxDesc = DMATxDscrTab;
heth.Init.RxDesc = DMARxDscrTab;
heth.Init.RxBuffLen = 1524;
...
}