STM32 - 원자형 USART 실험에서 printf의 방향을 바꾸어 분석

5970 단어 내장형
원자형의 USART 코드 중 일부는 잘 못 본 것 같아요
#if 1
#pragma import(__use_no_semihosting)             
//                           
struct __FILE 
{ 
    int handle; 
    /* Whatever you require here. If the only file you are using is */ 
    /* standard output using printf() for debugging, no file handling */ 
    /* is required. */ 
}; 
/* FILE is typedef’ d in stdio.h. */ 
FILE __stdout;       
//  _sys_exit()              
_sys_exit(int x) 
{ 
    x = x; 
} 
//   fputc   
int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);//    ,         
    USART1->DR = (u8) ch;      
    return ch;
}
#endif 

참고 자료: RealView 컴파일 도구 개발 설명서 RealView 컴파일 도구 라이브러리 및 부동 소수점 지원 설명서 아래 코드 분석:

1. #if 1


쓸데없는 말은 영원히 옳은 것으로 판단하는 것과 같다

2. #pragma import(__use_no_semihosting)


이 말을 이해하려면 먼저 반 호스트의 개념과 반 호스트 환경이 아닌 응용 프로그램을 어떻게 구축하는지 알아야 한다

2.1 절반 호스트 개념


반 호스트는 ARM 타겟에 사용되는 메커니즘으로, 나중에 애플리케이션 코드의 입출력 요청에서 디버거를 실행하는 호스트로 전송됩니다.예를 들어, 이 메커니즘을 사용하면 printf ()와scanf () 같은 C 라이브러리의 함수를 사용하여 호스트의 화면과 키보드를 사용할 수 있으며, 대상 시스템에 화면과 키보드를 설치하지 않고 호스트의 화면과 키보드를 사용할 수 있다.
이런 메커니즘은 개발할 때 사용하는 하드웨어는 보통 최종 시스템의 모든 입력과 출력 장치가 없기 때문에 매우 유용하다.반호스트는 호스트로 하여금 이 장치들을 제공하게 할 수 있다.

2.2 1/2 호스트 환경이 아닌 어플리케이션 구축


반호스트 기능을 사용하지 않으려면 반호스트 함수에 대한 모든 호출을 삭제하거나 반호스트 함수가 아닌 함수를 사용하여 다시 실행해야 한다.반호스트 기능을 사용하지 않는 애플리케이션을 구축하려면 다음과 같이 하십시오.

2.2.1 목표와 관련된 기능을 실현하기 위해 원본 파일을 만든다.


예를 들어 반 호스트에서 호출하거나 목표 메모리에 의존하는 함수를 사용합니다.

2.2.2 장차use_no_semihosting 기호를 원본 파일에 추가합니다.

                     ,         :
•        IMPORT __use_no_semihosting
• C    #pragma import(__use_no_semihosting)。



IMPORT __use_no_semihosting              。   , #pragma
import(__use_no_semihosting)         C     。          
        。

2.2.3 새로운 대상을 응용 프로그램과 연결한다.


2.2.4 대상 관련 어플리케이션을 만들 때 새 구성을 사용합니다.


2.2.2에서 알 수 있듯이 이 말은 응용 프로그램이 반호스트를 사용하는 함수를 포함하지 않도록 한다

3. printf 다시 구현()


printf () 라는 고급 함수는 목표와 관련된 함수를 호출하여 실행하고 printf () 를 다시 실현하려면 저급 함수를 다시 정의해야 한다
필요한 함수를 다시 실현하다
__FILE:파일 구조
__stdout: __FILE 유형의 표준 출력 객체
fputc(): 파일에 문자 출력
ferror(): 파일 입출력 중에 누적된 오류 상태를 반환합니다.

3.1 demo()


RealView 컴파일 도구 - 라이브러리 및 부동 소수점 지원 안내서의 demo
#include 
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
int fputc(int ch, FILE *f)
{
/* Your implementation of fputc(). */
return ch;
}
int ferror(FILE *f)
{
/* Your implementation of ferror(). */
return 0;
}
void test(void)
{
printf( “Hello world
” ); }

3.2 __FILE; __stdout; fputc()


이전의 분석을 통해 원자형이 에 대해 이해할 수 있다FILE; __stdout 코드가 무슨 뜻이에요?
재정의FILE; __stdout;

3.3 fputc 재정의()


3.3.1 상태 레지스터(USART SR)


비트 7:
TXE: 전송 데이터 레지스터 비어있음(Transmit data register empty)
TDR 레지스터의 데이터가 하드웨어에 의해 위치 이동 레지스터로 옮겨질 때 이 위치는 하드웨어에 의해 설정됩니다.USARTCR1 레지스터의 TXEIE가 1이면 중단이 발생합니다.USART에 대한DR 쓰기 작업을 수행하여 위치를 지웁니다.
0: 데이터가 위치 이동 레지스터로 옮겨지지 않았습니다.
1: 데이터가 위치 이동 레지스터로 옮겨졌습니다.

3.3.2 데이터 레지스터(USART DR)


비트 31:9:
보존 비트, 하드웨어 강제 0
비트 8:0
DR[8:0]: 데이터 값(Data value)
보내거나 받은 데이터가 포함되어 있습니다.이것은 두 개의 레지스터로 구성되어 있기 때문에 하나는 발송용(TDR), 하나는 수신용(RDR)으로 구성되어 있으며, 이 레지스터는 읽기와 쓰기 기능을 겸비하고 있다.

3.3.3 fputc()

int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);//    ,         
    USART1->DR = (u8) ch;      
    return ch;
}

이전 문자가 USART1을 통해 전송될 때까지 기다린 후 USART1을 통해 문자를 보내는 것과 같다

3.3 __sys_exit()


__sys_exit () 는 라이브러리 함수 종료 함수입니다. 모든 라이브러리에서 종료는 를 호출합니다.sys_exit()
여기에 반 호스트 모드를 사용하지 않도록 다시 정의합니다

좋은 웹페이지 즐겨찾기