글에 틀린 부분이 있을 수도 있습니다. 피드백은 언제나 환영입니다. 감사합니다.
1. Intro
이번 포스트에서는 mmio를 통해 FPGA 영역의 Slide Switch와 Hex Display를 이용하여 학번을 출력하는 banner scroll 프로그램을 어떻게 만들었는지 적어보려고 한다.
2. 동작원리
de1-soc에는 총 10개의 slide switch가 있고 6개의 hex display가 존재한다. Banner Scroll을 구현하기 위해 slide switch 한 개와 hex display 6개를 사용하였다. slide switch를 켜면 banner scroll이 왼쪽으로 이동하고, slide switch를 끄면 banner scroll이 오른쪽으로 이동한다.
2.1 선언된 변수들
Memory-Mapped IO in Linux-Based Systems(1) 포스트에 있는 사진을 다시 한번 가져왔다. DE1-SoC 보드에는 7-segment display가 6개 존재한다. 그리고 이를 위해 2개의 Data register가 있고 둘은 서로 연결되어 있다. 0xFF200020 에 있는 레지스터는 HEX3에서부터 HEX0까지
구동시키고, 0xFF200030에 있는 레지스터는 HEX5와 HEX4
를 구동시킨다.
또한 DE1-SoC 보드에는 10개의 slide switch가 존재한다. 1-bit 가 slidw switch(SW) 1개의 상태를 나타낸다.
6개의 7-segment와 1개의 slide switch를 이용하여 banner scroll 프로그램을 구현했고, 이를 위해 필요한 변수들을 다음과 같이 선언하였다.
- HEX5_HEX4_ptr : HEX5_HEX4의 주소를 저장
- HEX3_HEX0_ptr : HEX3_HEX0의 주소를 저장
- SW0 : SW의 주소를 저장
- new_num : 학번의 각 숫자를 나타내는 7-segment 값
HEX5_HEX4_ptr, HEX3_HEX0_ptr, SW0에 저장된 주소값은 컴파일 될 때 최적화되면 안되므로 volatile
키워드를 이용하여 다음과 같이 선언해주었다.
HEX3_HEX0_ptr= (volatile int *) (lw_virtual + HEX3_HEX0_BASE);
HEX5_HEX4_ptr= (volatile int *) (lw_virtual + HEX5_HEX4_BASE);
SW0 = (volatile int *) (lw_virtual + SW_BASE);
2.2 Banner Scroll Algorithm
먼저 *SW==0인 상황(오른쪽으로 진행)
부터 생각해보자.
ㄴ에 있는 4자리의 10진수를 오른쪽으로 한 자리씩 이동하고 이를 ㄱ에 있는 하위 한 개의 10진수와 합치면 새로운 ㄴ의 상태가 되겠고, ㄱ의 두번째 칸에 있던 10진수를 첫번째 칸으로 이동시키고, 두번째 칸에는 새로운 10진수가 오도록 하면 그 상태가 새로운 ㄱ의 상태가 될 것이다. 이를 레지스터를 이용하여 설명하면 다음과 같다.
이제 *SW==1인 상황(왼쪽으로 진행)
을 생각해보자.
ㄴ의 4번째 칸에 있는 10진수를 ㄱ의 첫번째 칸에, ㄱ의 첫번째 칸에 있던 10진수를 ㄱ의 두번째 칸에 출력되도록 하면 그것이 ㄱ의 새로운 상태일 것이고, ㄴ의 첫번째~세번째 칸에 있던 10진수를 왼쪽으로 한 칸 이동시키고, ㄴ의 첫번째 칸에는 새로운 숫자가 오면, 그것이 ㄴ의 새로운 상태가 될 것이다. 이를 레지스터를 이용하여 설명하면 다음과 같다.
3. 구현 방법 설명
각각의 7-segment의 상태를 나타내기 위해 0부터 9까지 각 숫자를 표현하기 위한 함수를 만들어주었다. 예를 들어 7-segment에 3이 출력되기 위해선 0,1,2,3,6 위치의 불빛들이 켜져야 하므로 2진수로 01001111에 해당한다. 이런 식으로 0부터 9까지 각 함수를 만들어주었다.
segment라는 함수는 main 함수 내부에서 7-segment에 출력하고 싶은 10진수 숫자를 인수로 받아서 이에 대응되는 code 값을 반환하는 함수이다. 이를 위해 함수 포인터 배열을 사용하였다. 0~9외의 10진수를 인수로 받으면 code = 0b00000000을 반환하여 7-segment에는 공백이 출력된다.
SW0 스위치가 올라가고 내려감에 따라 배너 스크롤의 진행방향이 달라지게 하기 위해서 한 개의 큰 무한 while 루프 안에 SW0가 0일 때 무한으로 실행되는 while 루프와 SW0가 1일 때 무한으로 실행되는 while 루프를 만들어주었다. 또 각각의 작은 while 무한루프 문 안에는 학번의 각 자릿수가 다 진행될 수 있도록 반복문을 만들어주었다.
글로 설명한 것을 코드로 나타낸 것이다. SW0값에 따라 진행방향이 바뀌도록 작은 while 무한루프 안에 있는 for문 안에서 조건에 따른 break문을 만들어주었다. usleep(500000) 로 인해 banner scroll은 0.5초마다 업데이트가 된다.
4. 결과
SW0 스위치가 켜지면(*SW0 ==1)는 Banner scroll이 오른쪽에서 왼쪽으로 이동하고, SW0가 꺼지면 (*SW0 == 0) Banner scroll이 왼쪽에서 오른쪽으로 이동함을 확인할 수 있다. 프로그램의 전체코드는 source code 에서 확인할 수 있다.
다음 포스트에서는 Polled IO를 이용한 Calculator 프로그램에 대해 적어보려고 한다.
'과제 및 프로젝트 > 임베디드 시스템 설계' 카테고리의 다른 글
Polled I/O를 이용한 Calculator (0) | 2024.12.23 |
---|---|
Memory-Mapped IO in Linux-Based Systems(2) (0) | 2024.12.22 |
Memory-Mapped IO in Linux-Based Systems(1) (0) | 2024.12.22 |