임베디드 C / C ++가 왜 포함되어 있는가?


15

이 질문은 쉽게 대답 할 수 없기 때문에이 질문이 마음에 들지 않았지만 "임베디드 언어를 변경하지 못하게하는 이유는 무엇입니까?"

예를 들어, 임베디드 용 C / C ++가 많이 보입니다 (ADA가 이전에 언급 한 적이 있다고 생각합니까? 내가 틀렸다면 수정하십시오)

그러나 임베디드 세계가 언어를 바꾸는 것을 정확히 막는 것은 무엇입니까? C가 사용하기에 너무 쉬운가요? 아니면 C가 모든 것을 잘 수행하기 때문에 실제로 변경이 "필요"하지 않습니까?

이것은 항상 저를 당황스럽게 만들었습니다. 언어를 몇 가지 언어로 유지하면 표준화가 유지됩니다. 그러나 여전히 문제는 남아 있습니다.

나는 이것이 일종의 주관적인 질문이라는 것을 알고 있지만, 나의 주요 질문은 "왜"이고 "IF / WHEN"이 아닙니다.


2
임베디드 시스템에서보고 싶은 특정 고급 언어가 있습니까? 편집 : 또는 오히려 C가 제공하지 않는 언어 기능에 관심이 있습니까?
Jon L

1
@ JonL-C가 원했던 저급 기능이 많이 있습니다. 큰 정수 내에서 EG 비트 / 니블 / 바이트 / 단어 조작이 향상되었습니다. 더 나은 안전 지원, EG Ada의 기능 유형.
Rocketmagnet

3
임베디드는 엄격하게 C가 아닙니다. 임베디드 시스템을위한 고급 언어는 다음과 같습니다. electronics.stackexchange.com/questions/3423/…
Kellenjb

1
"내장"은 다른 의미를 갖습니다. 토스터를 실행하는 4 비트 마이크로 컨트롤러는 ECU 또는 셋톱 박스와 다릅니다. 이 스펙트럼은 질문에 대답하기 어렵게 만듭니다.
Toby Jaffey

1
그리고 예상대로 이것은 닫혔습니다. 내가 희망했던이 질문은 고품질의 답변을 받고 사람들은 그것을 좋은 질문으로 유지하기 위해 노력할 것입니다. 대신에 우리는 다수의 공여를받는 한 문장 인 많은 답변을 받고 있고, 많은 투표로 전쟁에 대한 공감 전을 벌이는 대답이 있습니다. . 문제는 많은 사람들에게 왜 바뀌지 않았는 지에 대한 많은 다른 정답이 있다는 것입니다.
Kortuk

답변:


18

우선, "임베디드"는 유용한 구분이 아니므로 잊어 버리십시오. 가장 중요한 속성은 "리소스 제한"입니다. 가장 중요한 리소스는 종종 시간이며,이 경우 실시간 시스템에 대해 이야기하지만 메모리 또는 전원이 될 수도 있습니다.

  • 새로운 언어 채택은 어렵고 드물다. 재교육, 새로운 도구 및 새로운 언어로 작업하기에 좋은 방법을 찾아야합니다. 초기 얼리 어답터에게는 비용이 많이 듭니다. 그것은 또한 닭과 계란 문제입니다 : 큰 사용자 기반이 없으면 좋은 도구와 라이브러리가 없지만 큰 사용자 기반은 없습니다. 따라서 새로운 언어는 기존 언어에 비해 큰 이점을 가져야합니다. 그렇지 않으면 기회가되지 않습니다.

  • 언어에서 "최근"의 새로운 개발은 사용 가능한 CPU 성능과 사용자가 필요로하는 것 사이의 격차를 메우고 있습니다. 다시 말해 속도가 비효율적이지만 프로그래머가 더 쉬워서 보상 할 수 있습니다. Java, Python, Perl, Tcl과 같은 언어가 기본적으로 인터프리터 (일부 컴파일 후)에 의해 실행되고 동적 메모리 관리를 많이 사용하는 언어의 등장을 생각하십시오. 그러나 이것은 우리가 a) 더 많은 프로그래밍 노력을 희생하더라도 가용 한 리소스를 최대한 활용하고 b) 예측 가능한 리소스 사용을 원하는 리소스 제한 세계와 잘 맞지 않습니다.

  • C 및 C ++ (또는 적절한 하위 집합)은 여전히 ​​먼저 멀지 않은 예측 가능한 공간 및 시간 요구 사항을 충족시킬 수있는 일반적인 도구 (좋은 도구, 충분한 훈련 된 프로그래머 및 광범위한 라이브러리를 모두 사용할 수 있음)의 최상위 언어입니다. 현재 하드웨어에서 가능한 것. 유일한 경쟁자는 Ada라고 생각하지만 나쁜 시작으로 어려움을 겪었습니다. 첫 번째 구현은 너무 느리고 비효율적이었습니다. 현재 (구현 가능한 구현이 가능하더라도) 언어는 약간 뒤떨어졌습니다. 기능 (C ++과 비교). 개인적으로 나는 이것이 유감이라고 생각합니다. 다른 것들과 동일합니다 .C 또는 C ++에서 수행 된 것보다 Ada로 프로그래밍 된 평면에서 나는 것이 좋습니다.


+1-좋은 대답. Ada는 흥미로운 언어로 보입니다. 작은 마이크로를위한 Ada 컴파일러가 있습니까?
Oli Glaser

GCC Ada 컴파일러 인 GNAT가 있습니다. 그러나 AFAIK는 마이크로에서 많이 사용되지 않았으므로 실행하기 쉬운 것을 찾는 데 어려움을 겪을 것입니다.
Wouter van Ooijen

그래도 위키 페이지에서 GNAT가 언급 된 것을 보았습니다. 작은 마이크로에 대해서는별로 맞지 않지만 68k, x86, MIPS 등의 미션 크리티컬 한 것들 (예 : DDCI ) 에 대한 약간의 지원 (예상 한대로 )이있는 것 같습니다
Oli Glaser

아래 Deek에서 언급했듯이 SPARK Ada도 있습니다. 나는 그들이 시간이라고 부르는 그 어려운 것들 중 일부가있을 때 그것을 확인해야합니다 ...
Oli Glaser

2
Gnat 형태의 Ada는 Arduino에서 볼 수 있듯이 AVR 마이크로 프로세서에서 잘 작동합니다. 내가 만든 가장 작은 Gnat 실행 파일은 65 바이트였습니다. 물론 아두 이노 스케치가 1K 이상 이었지만 LED가 깜박 거렸다. 내 실행 파일이 600 바이트에 도달했을 때 2 스테퍼 모터를 독립적으로 구동하고있었습니다 ... LED 깜박임이 공식적으로 올바른지 증명하지 않으려면 SPARK가 필요하지 않습니다!
Brian Drummond

9

8 비트 및 16 비트 마이크로 컨트롤러 기반 임베디드 시스템을 사용하면 이러한 매우 작은 스토리지 제한의 제한된 리소스 (약 100 바이트)에 맞는 소프트웨어를 쉽게 개발할 수 있습니다. 저급 8 비트 마이크로 컨트롤러의 경우 의 RAM 일 수 있음) , 코드 저장을 위해 2-8 KiB의 ROM 또는 EPROM / 플래시 포함).

이러한 경우 C 또는 어셈블리와 같은 작은 언어가 가장 일반적으로 사용되는 개발 언어 인 경향이 있습니다. 매우 대략적인 비교로서, 완전한 어셈블러 및 C99 컴파일러는 단일 플로피 디스크에 맞출 수 있지만 최신 C ++ 개발 시스템 (STL 등)에는 여러 MiB 가 필요합니다 .

고급 마이크로 (고급 16 비트 및 대부분 32 비트, 상당히 드문 64 비트) 및 DSP를보고있는 경우임베디드 환경에서 있는 경우 제한이 약화되고 소프트웨어 개발이 대부분의 개발을 구성 할 수 있습니다. C ++과 같은 OOP (Object-Oriented Programming) 언어 및 최신 언어 (Java, Perl, Ruby, Python)와 같은 기능을 갖춘 고급 언어를 포함하여 가장 생산적인 개발 도구를 사용하는 것이 합리적입니다.

어셈블리 및 C에서 사용중인 메모리 양을 예측할 수 있으므로 공간이 제한된 디자인이 가능하지만 템플릿, 예외 처리 및 런타임 바인딩과 같은 고급 기능을 통해 필요한 메모리 공간을 정확하게 알 수 없습니다. 미리 표준 C ++ 프로그램을 위해. 나는 C ++ 의 하위 세트 인 MISRA C ++ 에 대해 충분히 알지 못합니다 .

바이트 코드 (Java, Perl, Python)를 실행하는 가상 머신을 기반으로하는 언어는 임베디드 개발자의 경험에서 성숙도가 떨어지며, 이러한 언어는 프로그래머를 특정 하드웨어로부터 격리 시키도록 설계되므로 양심하기가 더 어려워집니다. 그러한 임베디드 하드웨어 시스템의 제한 및 제한. RAM이 GiB가 아닌 경우 MiB를 사용하는 고속 32 비트 프로세서 (예 : ARMv7)에서는 문제가되지 않습니다.

내가 아는 모든 BASIC 구현은 언어 기능이 매우 단순하지만 1960 년대부터 Dartmouth BASIC의 레거시와 거의 동일합니다. 즉, 언어에는 복잡한 런타임 라이브러리 또는 예외 처리가 없으며 인터프리터 또는 컴파일러는 작성하기가 간단하고 파일 크기도 작습니다. 대부분의 마이크로 컨트롤러에는 사용 가능한 BASIC 컴파일러가 하나 이상 있습니다.

C 및 어셈블리가 주로 소형 또는 구형 임베디드 시스템에서 사용되는 이유를 광범위하게 설명하고 최신 중급 및 고급 임베디드 시스템의 한계는 기존 데스크탑 PC와 약간 다릅니다.


5

대부분의 답변은 이미 역사적인 이유를 언급했습니다 (잘 알려진, 모든 사람들이 그것을 사용하고 습관을 바꾸는 것은 쉽지 않을 것입니다). 동의하지만 다른 중요한 이유가 있음을 명심해야합니다.

그것은의 하지 (쿼티 (QWERTY) 키보드처럼) "C 나쁜 또는 오래된 선택하지만 우리는 여전히 습관 그것을 사용"고.

C는 그 자체로 임베디드 개발, 특히 시간이 중요한 애플리케이션에서 매우 적합한 선택입니다. 왜?

  • 실시간 프로그램을 쉽게 구현할 수있을 정도로 수준이 낮습니다. 나노초 단위로 시간을 측정해야하거나 5 마이크로 초마다 인터럽트를 포착해야하거나 정확히 64 바이트의 총 RAM 을 사용해야하는 경우 , 매우 높은 수준의 언어를 사용하면 불가능하거나 해결하기가 매우 어려울 수 있습니다. . C는 고급 언어보다 하드웨어를 훨씬 잘 제어 할 수있게 해줍니다 . 이것은 임베디드와 PC를 개발하는 것 사이의 가장 중요한 차이점 중 하나입니다.

  • 어셈블리에 비해 빠르고 쉽게 코딩 할 수있을 정도로 수준이 높습니다.

따라서 C는 어셈블리의 속도 및 직접 하드웨어 액세스와 고급 언어를 쉽게 읽고 이해하는 것 사이에서 최상의 (또는 최상의 것) 타협입니다.


1
C가 선호하는 주요 측면은 특정 플랫폼에 대한 코드를 최적화하는 동시에 다른 플랫폼에서 그러한 코드를 실행할 수 있다는 것입니다. PIC와 같은 많은 C 명령어는 기계 명령어로 예측 가능하게 변환됩니다. 와 같은 루프 unsigned char i=63,j=128; do {something;} while(--j); while(--i);는로 읽을 수 unsigned int i=16000; do {something;} while(--i);없지만 PIC에서 더 빠르게 실행되고 더 효율적입니다. 코드가 ARM으로 이동 된 경우 두 번째 방법이 더 효율적이지만 첫 번째 방법은 여전히 ​​효과적입니다.
supercat

4

정규 프로그래밍에서 (가장 많이 사용되는) 언어가 (실제로) 변경되지 않는 이유와 정확히 같은 이유입니다.

  1. 방대한 양의 기존 코드 (라이브러리 / 기존 구현)
  2. 이러한 언어 (IDE, 시뮬레이터 등)와 함께 사용할 수있는 큰 도구 세트

4

임베디드 세계에서는 소프트웨어 업데이트를 제공하는 것이 훨씬 어렵거나 불가능할 수 있으므로 정확성을 보장하는 것이 무엇보다 중요합니다. 슬프게도 C는 이와 관련하여 거의 도움이되지 않으며 프로그래머가 빠르고 느슨하게 연주 할 수 있습니다.

임베디드 시스템에 C를 사용하는 것은 고통스럽고 const, reference, stringer typing 등과 같은 제약 조건의 형태로 제공되는 많은 이점을 위해 적어도 C ++로 이동할 수 있기를 바랍니다.

나는 그 변화가 상업적으로 실행 가능하지 않기 때문에 단순히 C에 갇혀 있다고 대답합니다. 모두 C를 알고 있으며, 많은 컴파일러,이를위한 라이브러리 및이를 생성하는 도구가 있습니다. 새로운 언어로, 우리는 처음부터 시작할 것입니다.

그래서 사람들이 여전히 PHP를 사용 하는 것 같습니다 .

PHP 더블 클로 망치.


당신이 질문에 대해 토론하고 싶다면 의견이나 메타를 사용하십시오. 좋은 질문을 위해 사용자를 가볍게 두드 리거나 의견을 올리려면.
Kortuk

당신은 항상 파스칼을 사용할 수 있습니다-당신이 찾고있는 추가 제한이있는 것 같습니다 :-). 또는 어떤 형태의 슈퍼-린트.
Russell McMahon

2
C의 중요한 이유 중 하나는 C ++ 컴파일러보다 기본 C 컴파일러를 작성하는 것이 훨씬 쉽다는 것입니다. 더 중요한 일이 저를 떠나기 전에 한동안 일했습니다. 재미있는 것들! C ++ 컴파일러를 작성 하시겠습니까? 어. 그래도 C ++을 사용자로 선호합니다.
darron

1
@RussellMcMahon-사용중인 MCU 용 Pascal 컴파일러가 없기 때문에 Pascal을 사용할 수 없습니다.
Rocketmagnet

@ 대런-아주 좋은 지적입니다. 그러나 gpp와 같은 훌륭한 오픈 소스 C ++ 컴파일러가 있습니다. 백엔드 만 작성하면됩니다.
Rocketmagnet

4

SPARK Ada에 대해 들어 본 사람이 없습니까?

항공 전자 공학 및 의료 장비와 같은 기타 안전에 중요한 응용 프로그램과 같은 임베디드 시스템을위한 Ada 언어 및 관련 개발 도구의 "작은"버전입니다.

연구에 따르면보다 안정적인 SPARK 코딩으로 C / C ++에 비해 처리 속도가 5-10 % 감소합니다.

임베디드 시스템에서 C의 확산은 경제적 이유 때문이라고 생각합니다.

  • 이미 존재하며 대부분의 응용 프로그램에서 일반적으로 작동 가능합니다. 대부분의 응용 프로그램은 중요하지 않으므로 세탁기가 오버런되면 아무도 죽지 않습니다.

  • SPARK 툴셋 자체는 추가 비용이 될 것이며 교육 직원이이를 사용할 수 있습니다.

  • SPARK (또는 다른 비 C 언어)의 임베디드 컨트롤러 / 관리 시스템에 추가 된 이점은 소비자의 눈에 제품 가격에 필요한 프리미엄을 정당화하기에 충분하지 않을 수 있습니다. 더 낮은 가격으로.

  • AdaCore 회사는 대중 시장 응용 프로그램에 너무 깊이 들어 가지 않도록주의해야합니다. 이러한 응용 프로그램은 핵심이 아닌 문제를 처리하기 위해 기술 지원 직원이 크게 증가해야하기 때문입니다. AdaCore는 높은 수준의 전문 기술 회사로서 자부심을 갖고 첨단 기술 회사에 제품과 서비스를 제공합니다. 주요 이해 당사자가 실제로 원하지 않는 한 언어가 새로운 시장에 침투하는 것은 드문 일입니다.

따라서 @ Wouter, 당신은 Ada 임베디드 코드를 원하기 때문에 하늘에서 죽을 걱정을 할 필요가 없습니다!

이미 몇 년 동안 비행기 시스템에있었습니다. 페이스 메이커도 마찬가지입니다.

그러나 식기 세척기, 건축 서비스 제어 시스템, 실험실 용광로 컨트롤러 및 기타 엄격하게 규제되지 않는 경기장의 경우 경제적으로 가치가 있습니까?


흥미롭고 고마워요. SPARK에 대해 들어 보지 못했을 것입니다.
Oli Glaser

일부 연구에 따르면 C의 기존 응용 프로그램에 비해 속도가 향상되는 것으로 나타났습니다. "Ironsides"DNS 서버를 살펴보십시오.
Brian Drummond

3

C의 인기에 대한 주된 이유는 첫 번째입니다. C가 인기 있고 많은 사람들이 그것을 알고 두 번째입니다. Java, C # 및 C ++의 많은 측면과 같은 새로운 인기 언어는 임베디드 작업에 적합하지 않습니다. 기본적으로 내가 언급 한 3 개의 다른 언어는 동적 메모리에 많이 의존합니다. 동적 메모리는 프로그램으로 비 결정적 실행을 제공하는 객체, 동적 메모리를 가져 오는 객체, 큰 메모리 요구 사항 (OO의 가장 중요한 측면 중 하나가 더 많은 수의 클래스), 컴파일 시간의 인기가 높아지고 (많은 임베디드 플랫폼이 자체 C 코드를 전혀 컴파일 할 수도 없습니다) ...

Java 또는 C #과 함께 제공되는 많은 라이브러리가 많은 수의 임베디드 프로젝트에 쓸모가 없다는 사실도 있습니다.

반면에 파스칼이나 베이직과 같은 오래된 언어가 있습니다. 내 관점에서 볼 때 C는 자체적으로 "산업 표준"언어가되었으며 오늘날 많은 프로그래머와 엔지니어가 C를 배우기 때문에 인기가 없습니다. 일부 학교에서는 파스칼 또는 베이직도 배우지 않습니다. 오늘날 많은 언어가 C와 유사한 구문을 가지고 있으며 파스칼을 사용하는 것이 C 프로그래머에게는 이상하게 느껴질 수도 있습니다.

FORTRAN에 관해서는, 그것이 틈새 분야에 들어 갔으며, 사용하기에 적합한 생태계가있는 지역에서 일하는 엔지니어와 과학자들이 주로 사용한다고 생각합니다. 임베디드 시스템에서 사용되지 않는 특별한 이유 (파스칼 및 베이직에 대해 언급 한 이유 제외)는 보이지 않습니다.

이 답변에서 나는 주로 작은 시스템에 중점을 두었습니다. GNU / 리눅스 나 다른 유닉스 파생물과 같은보다 복잡한 운영 체제를 사용하는 많은 임베디드 장치가 있으며,이를 프로그래밍하기 위해 어느 정도의 대중적인 언어를 사용할 수 있습니다.


1
C가 인기가 있기 때문에 C가 인기가 있습니까? :-)
stevenvh

2
@stevenvh 네, 맞습니다. 일종의 긍정적 인 피드백 루프입니다. 인기가 높을수록 인기가 높아집니다.
AndrejaKo

3

C는 매우 간단한 언어이며 여러 차례에 걸쳐 어셈블리 언어 . C 구문은 기계 수준의 구문에 상당히 직접 매핑되므로 위의 어셈블리 코드를 제공 할 수있는 최소한의 추상화 수준입니다.

이와 같은 여러 가지 이유로 인해 새로운 칩에서 C 컴파일러를 구현하는 것은 매우 쉽습니다. 대부분의 작업은 이미 완료되었고, 복잡성이나 잘못된 일이 거의 없으며, 낮은 수준의 제어를 통해 하드웨어의 단점을 상당히 쉽게 처리 할 수 ​​있습니다.

C ++은 C의 소스 코드 변환 계층으로 구현 될 수 있습니다 (실제로 원래 사용 되었음). C 컴파일러를 사용하여 C ++ (또는 최소한 일부 버전)을 무료로 얻을 수 있습니다.

C 및 C ++를 사용하면 새로운 칩에 필요한 모든 것을 부트 스트랩 할 수있어 논리적으로 시작할 수 있습니다.


3

다른 사람들이 언급하지 않은 몇 가지 이유 :

  • 문제 공간 : C는 작고 간단한 시스템에 적합합니다. 외부 신호에 반응하고 몇 개의 숫자를 밀어 넣으면 C가 다소 잘 작동합니다 (복잡한 데이터 구조, malloc, 복잡한 오류 처리 없음).

  • 생산량 : 생산량이 많으면 프로그래밍 비용이 한 번에 발생하므로 각 하드웨어 장치를 절약하고 프로그래머에게 더 많은 비용을 지출하는 것이 경제적으로 합리적입니다.


2

C / C ++가 가장 낮은 수준의 고급 언어이기 때문이라고 생각합니다.


1

실제로 소형 임베디드 시스템의 경우 C는 C ++보다 훨씬 인기가 있습니다. 그리고 그 이유는 다른 언어를 사용하지 않는 것과 같습니다. C와 다른 대부분의 기능을 제공하지 않는 한 C ++에는 런타임이 필요합니다.

어셈블리 외에도 C는 네이티브 코드로 컴파일하는 유일한 언어 이며 있는 런타임을 가지는 것은 선택 사항입니다. 따라서 제한된 환경 (조립품을 사용하는 경우 제외)에서 가장 작은 설치 공간과 가장 빠른 실행 시간이 보장됩니다.

반면에 중소형 임베디드 시스템 (더 많은 메모리와 시계, 더 큰 단어 크기를 의미 함)에서 C (또는 C ++)가 널리 퍼져 있다고 말하지 않습니다. Python, Forth, 심지어 Java를 지원하는 시스템을 보았습니다.

그러나 물론 위에서 언급 한 것과 같은 이유로 C / C ++을 사용할 수있는 옵션이 거의 항상 있습니다. 그리고 선택권이 있고 이미 C에 익숙한 소규모 임베디드 사용자라면 왜 다른 언어를 선택하겠습니까?


4
C ++은 많은 오버 헤드를 생성 할 수 있지만 MSP430에 사용 된 완전히 호환되는 C ++ 컴파일러에는 런타임이 필요하지 않았으며 C ++은 네이티브 코드로 컴파일했습니다. 죄송합니다. 다른 사람에게 장애가 있다고 말하면 귀하를 다운 보트했습니다. 내가 틀렸다고 확신하는 참조를 제공하여 downvote를 제거 할 수 있습니다 (어려울 것입니다. 프로젝트에 대해 컴파일 된 C ++의 어셈블리 목록을 읽었으며 효율적으로 컴파일하는지 확인하십시오). 또는 제거 할 답변을 삭제할 수 있습니다 당신의 명성에 영향을 미칩니다 (이 시점에서 +8 순 담당자를
받더라도

3
나는 Kortuk에 전적으로 동의합니다. C ++의 일부 부분은 광범위한 런타임 지원이 필요하지만 그렇지 않은 부분은 여전히 ​​훨씬 나은 C (및 완전히 OO)입니다. 이 하위 집합에 대한 제한은 일부 컴파일러 및 링커 스위치에 의해 쉽게 적용됩니다. 일부 부분에서 (예를 들어, 두려운 printf) C ++은 런타임 지원이 훨씬 적을 수있는 언어 잠재력을 가지고 있습니다 (std :: cout 만 작은 시스템을 염두에두고 구현 한 경우 ...)
Wouter van Ooijen

1
@ Kotuk, 거기에 명확하지 않은 것이 유감이지만, "C는 유일한 언어입니다 ..."라고 말했을 때 C ++에 두 가지가 모두 없다는 것을 의미하지는 않습니다 .C가 두 가지의 조합을 가지고 있음을 의미했습니다. C ++에는 그중 하나가 있습니다. 나는 런타임 부분에 중점을 두었다. 또한 런타임없이 C ++을 사용하는 것이 완전히 불가능하다는 말은 아니지만 매우 드 unusual니다. 예를 들어 런타임없이 예외 처리 및 RTTI와 같은 것을 가질 수있는 방법을 알 수 없으며 매우 중요한 기능입니다. 그러나 나는 이것을 표현한 방식으로 오해가 생겼을 경우 사과드립니다.
fceconel

@fceconel, 런타임 환경에서 C ++을 사용한 적이 없으며 여기에서 임베디드 시스템에 대해 논의하고 있으며 내 마이크로 컨트롤러에서 런타임을 사용한 적이 없습니다. 이 질문은 조금 다를 수 있습니다. 읽었을 수도 있습니다. C / C ++가 C ++ 대신 C가 아닌 왜 유일하게 일반적인 선택인지 묻습니다. 나는 cout이 마이크로에서 결코 일어나지 않을 정도로 간단한 것을 사용한다는 것을 인정할 것입니다. 화면이 아닌 몇 개의 무료 핀이 있습니다.
Kortuk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.