메뉴 건너뛰기

NEOS White Paper

주의 : 본 기능은 NEOS V5에만 적용됩니다.

 

1. Open429I-C Overview

Cortex-M4에서 NEOS Serial Device Driver 개발하는 방법에 대하여 설명합니다.

이 글에서 설명에 사용한 reference board 는 waveshare의 Open429I-C 입니다. 이 보드는 다음과 같은 자원을 가지고 있습니다.

  • - MCU : STM32F429IGT6
  • - core : cortex-M4 32bit RISC
  • - memory: 1024 Flash, 256+4kB SRAM
  • - 2 x USART, 2 x SPI, 1 x ETH, 1 x I2C, etc.
  • - 아래의 그림은 Open429I-C의 간략한 block diagram 입니다.

스크린샷 2016-04-05 오후 12.21.35.png

 

 

 

Open429I-C 보드는 위의 block diagram에서 보듯이, 2개의 Serial port 가 있습니다. USART1은 debug port로 사용하며, USART3는 WIFI Module을 연결하여 사용할 것입니다. 따라서 USART1 은 canonical mode로, USART3은 raw mode 로 사용하여야 합니다.  USART3을 canonical mode 로 사용하게 될 경우, input data들이 echo로 output으로 나가게 되기 때문에, wifi module과 정상적인 통신을 기대할 수 없습니다.

 

2. NEOS 에서의 serial device driver

그럼, neos에서의 serial driver 와 os 의 관계에 대하여 살펴보겠습니다. 이 문서에서는 raw mode에 대하여서만 설명합니다.

  • 2.1 Raw mode, Interrupt mode Tx

스크린샷 2016-04-05 오후 12.35.56.png

  • 2.2 Raw mode, Polling mode Tx

스크린샷 2016-04-05 오후 12.36.10.png

  • 2.3 Raw mode, Interrupt mode Rx

스크린샷 2016-04-05 오후 12.36.19.png

  • 2.4 Raw mode, Polling mode Rx

스크린샷 2016-04-05 오후 12.36.27.png

 

3. Serial Device Driver Porting

3.1 Serial Device Driver BSP

이제 serial device driver를 개발하려면, 어떤 파일을 사용하여 porting을 하여야하는지 설명하겠습니다.

해당 bsp의 serial device driver의 초기화 및 configuaration 은 bsp/(bsp name)/bspSioConfig.c 에서 합니다. open429I-C보드의 경우, bsp/open4x9i/bspSioConfig.c에서 serial device driver 초기화 및 설정값들을 넣어줍니다. serial의 baudrate, clock, rs485 control pin등을 Stm32f4xxSioConfigDef structure인 open429SioConfig에서 설정해주었습니다. open429i-c보드의 경우, usart가 2개가 설계되어있어서, CONFIG_PARAM_CONSOL_TTY_NUM은 prjParams.h에서 2로 define 되어있습니다.

 

스크린샷 2016-04-05 오후 12.44.06.png

 

3.2 Serial Device Driver GPIO 설정

BspSioHwInit()함수에서 보듯이, serial device driver를 초기화하려면, 가장 먼저 해당 serial port의 gpio를 초기화 하여야합니다.

open429i-c보드는 USART1은 PA10, PA9, PA11, PA12을 사용하며, USART3은 PD9, PD8, PD11, PD12, PD10을 사용합니다.

PAx는 GPIOA port group를 의미하고, PDx는 GPIOD port group을 의미합니다. 따라서, 제일 먼저 할 일은, GPIOA 와 GPIOD의 clock 을 enable해주어야합니다. 이는 STM32F429IGT6의 RCC_AHB1ENR register에서 설정합니다. 아래 그림의 GPIODEN, GPIOAEN bit를 1로 설정합니다.

 

스크린샷 2016-04-05 오후 12.55.24.png

 

GPIO clock을 enable하였으면, 이제 설계에 따라 다음과 같은 항목들을 각 register에 설정하여야하며, 그 option은 다음과 같습니다. 해당 register의  address나 bit field STM32F429 data sheet를 참조하며 이 문서에서는 생략합니다.

  • - port mode register: Input mode, General purpose output mode, Alternate function mode, Analog mode
  • - port output type register: Output push-pull. Output open-drain
  • - port pull-up/pull-down: No pull-up-pull-down, Pull-up,Pull-down, Reserved
  • - port output speed: Low, Medium, High, Very High speed
  • - alternate function: A0 ~ AF15

예를 들어 open429i-c보드의 경우 AF7을 사용합니다. 이는 다음의 그림과 같이 STM32F429 data sheet에 정해져있는 option입니다. 우리는 STM32F429에서 제안하는 몇가지의 option중에 사용하는 보드의 하드웨어 설계에 맞추어 선택하면 됩니다.

스크린샷 2016-04-05 오후 1.04.16.png

 

 

3.3 Serial Device Driver USART 설정

이제 GPIO설정은 끝났습니다. USART의 설정을 시작합니다.

USART도 GPIO와 마찬가지로 clock enable을 합니다. clock enable이 되지 않은 상태에서는 register에 값을 write하여도 설정값이 적용되지 않습니다. STM32F429 는 USART1은 APB1, USART3은 APB2에 위치하므로, 이 두 bus clock을 enable 합니다.

스크린샷 2016-04-05 오후 1.10.46.png

 

앞서 본 것처럼, Neos의 serial device driver는 TTY driver와 연동하여 동작합니다. 따라서 TTY driver에서 serial deivce driver를 호출할 수 있도록 SIO channel interface에 serial device driver에서 구현한 Tx/RX IO  함수 및 ioctl 함수를 아래의 그림과 같이 SIO channel 에 함수포인터로 연결 시켜주어야 합니다. 아래는 STM32F429의 serial device driver file 인 stm32f4xxSio.c의 Stm32f4xxSioDevInit() 함수에 구현되어 있습니다.

스크린샷 2016-04-05 오후 1.15.29.png

 

STM32F429의 USART의 register로는 Status register, Data register, Baud rate register, Control register 1, Control register 2, Control register 3. Guard time and prescaler register가 있습니다. 이중 초기화 및 설정에 사용되는 register는 Baud rate register, Control register 1, Control register 2, Control register 입니다.

Control regster 1(CR1)에서는 다음과 같은 사항을 설정합니다. 초기화 시작하면서 uart는 disable로 설정합니다. interrupt handler를 연결한 후에, enable 시켜줍니다.

  • - USART Disable :                    UE = 0 oversampling
  • - mode 설정 :                           OVER8 = 0
  • - Transmitter/Receiver enable :  TE = 1, RE  = 1
  • - word length 설정 :                   M  = 0
  • - parity bit 설정 :                        PCE = 0.
  • - RXNE interrupt 설정 :              RXNEIE = 1

스크린샷 2016-04-05 오후 1.22.50.png

 

CR2는 다음과 같이 설정합니다.

  • - stop bit :   STOP = 0

스크린샷 2016-04-05 오후 1.24.16.png

 

CR3는 다음과 같이 설정합니다.

  • - error interrupt enable 설정:  EIE    = 1
  • - hardware control 설정:        CTSE = 0, RTSE = 0

스크린샷 2016-04-05 오후 1.25.50.png

 

Baud rate은 다음의 공식을 통하여, register 설정값을 구합니다. 원하는 baudrate을 Tx/Rx baud에 두고 USARTDIV값을 구하여, USART_BRR register의 DIV_Mantisssa, DIV_Fraction field값에 입력합니다.

스크린샷 2016-04-05 오후 1.27.51.png

스크린샷 2016-04-05 오후 1.28.00.png

 

위의 모든 초기화과정을 완료하고, interrupt handler를 연결한 후 usart를 enable 합니다.

 

 

USART 를 interrupt mode로 사용할 경우, TXE/RXNE가 발생하였을 경우 그 의미를 알아야합니다.

TXE bit 발생은 다음을 의미합니다. :

  • - data 가 TDR에서 shift register로 이동하여 TX로 data transmission이 진행
  • - TDR register 가 비었음.
  • - 다음 전송할 data를 USART_DR register에 write하여도 됨.
  • - TXEIE bit (USART_CR1)이 설정되면 TXE가 설정되면 interrupt 발생.

스크린샷 2016-04-05 오후 1.33.55.png

  • - TX에서 data transmitting이 일어날 때, TC/TXE/DR의 관계는 다음의 그림으로 설명됩니다.

스크린샷 2016-04-05 오후 1.37.21.png

 

TXE는 TDR이 비었을 경우 발생하는 interrupt이므로, 항상 enable 시켜놓을 수는 없습니다. 따라서 평소에는 disable이 되어 있고, write할 data가 있을 경우, tty로부터 startup command가 write할 data와 함께 내려오는데, 이 때 TX interrupt 를 enable해주고 보내야할 data전송이 완료된 후 disable하여줍니다.

 

반면 RXNE의 발생의미는 다음과 같습니다.

  •  - RXNE bit 발생은 shift register의 data 가 RDR로 이동이 되어, 읽힐 준비가 되었음을 의미.

스크린샷 2016-04-05 오후 1.42.08.png

따라서 RXNE interrupt는 interrupt mode를 사용할 경우 항상 enable 시켜놓도록 합니다.

 

위로