dsPIC33보드를 이용하여 EXP-ARM TFT LCD에 이미지를 출력하려고 const 데이터를 할당받았는데 에러가 발생한다.
하드웨어 구조상 32k 이상 할당이 안된다고 한다.
해결책이 없을까?
dsPIC에서 const 데이터는 코어 구조상 32byte까지 할당 가능하다. 대용량의 코드 데이터(constant)를 할당 받으려면 PSV를 이용하면 된다고 한다. 물론 psv를 할당해도 32kbye단위로 설정 가능하다.(그냥 const로 설정하면 32k 이상 할당 할 수가 없다.)
32KB 영역(0x8000 ~ 0xFFFF)을 페이지 별로 할당하여 사용할 수 있다고 한다.
C30컴파일러 에서는 __attribute__((space(psv))) 로 설정할 수 있다.
사용할 때는 PSVPAG = __builtin_psvpage(&arry) 으로 설정해서 사용하면 된다.
186T TFT LCD 이미지는 32K가 넘어 가므로 이미지를 두부분으로 나누고 각각 PSV영역에 할당해서 이미지 출력할때 각각 출력하는 형식을 취했다.
먼저, PSV 기능을 사용하신다면 먼저 MPLAB C30 V3.0 이상의 사용을 권장합니다.
이미 아시겠지만 PSV 는 프로그램 메모리 영역중 32KB(16K Word) 영역을 데이터 메모리 영역의 하위 32KB 영역(0x8000 ~ 0xFFFF)으로 매핑함으로써 프로그램 메모리 영역의 액세스 속도를 극대화할 수 있는 방법입니다. 따라서, PSV는 대용량의 프로그램 메모리 영역중 32KB 범위 이내에서만 액세스가 가능하게 됩니다. 16비트 MCU의 경우 대부분 프로그램 메모리가 32KB를 넘게 되기때문에 PSV Page 개념을 도입할 필요가 있게되었으며, 여기서 말하는 PSV 페이지는 프로그램 메모리를 32KB 단위의 페이지 단위 즉, 각각의 블럭 단위로 나누고 이 페이지 번호(블럭 번호)를 기억하기 위한 레지스터로써 PSVPAG 를 사용하게 됩니다.
이미 눈치를 채셨겠지만, PSVPAG 레지스터는 아래와 같이 프로그램 메모리 영역의 주소중 32K 단위의 페이지를 가르키게 됩니다.
PSVPAG = 0 --> 0x0000 - 0x7FFF
PSVPAG = 1 --> 0x8000 - 0xFFFF
PSVPAG = 3 --> 0x10000 - 0x17FFF
설명이 너무 길어지니, PSV에 대한 설명은 이 정도에서 마치고 질문에 대한 답변을 드리겠습니다. (좀더 자세한 내용은 Reference Manual의 Ch-4. Program Memory 참조 바랍니다.)
문의하신 질문에 대한 답변 올리겠습니다. [Q1] const unsigned __attribute__ ((space(psv), address(0x17F00))) table[10]={0,1,2,3,4,5,6,7,8,9}
위와 같이 설정하면 PSV address에서 table 배열 값을 확인 할 수 없습니다.
Data space memory 영역이 0x8000부터 0xFFFF이기 때문인것 같은데 이럴 경우 PSV 기능이 적용이 않되는 것인가요 ? --->[답변] PSVPAG 설정을 하지 않으셔서 그렇습니다.
할당된 데이터(주소:0x17F00 )는 PSVPAG = 3 영역에 할당되어 있기 때문이지요.
(해결방법) PSVPAG = __builtin_psvpage(table); //<<---- 변수 사용전 페이지 설정 명령 1줄만 써주시면 됩니다.
[Q2] 그리고, 사용자가 사용할 수 있는 Program memory는 0x100번지 부터 address를 0x2000번지 미만으로 설정하면 Error가 발생하는데 이유가 무엇입니까 ? ---> [답변] 0~0xFF 까지는 리셋 벡터, 0x100 - 0x???? 까지는 사용자 코드 즉, 소스코드가 자리를 잡고 있기 때문입니다. 0x2000 번지 이후로만 PSV 메모리 할당이 가능하다는 얘기는 윤경훈 님의 소스코드가 이미 0x2000 번지까지 차지하고 있기때문입니다. 즉, 프로그램 할당 우선순위에서 PSV가 밀린다는 얘기이지요.
(해결방법1) 특정 함수등의 소스코드 영역을 특정메모리에 할당하시기를 원하신다면 Linker Script 에 사용자 Section 선언하시고 함수 선언시 해당 Section으로 선언하시면 됩니다. 이 부분은 메뉴얼 첨부로 대체하겠습니다.
(해결방법2) 가급적 PSV 메모리 할당을 프로그램 메모리의 뒷부분에 할당하시면 소스코드의 영역과의 충돌을 피할 수 있습니다.
(해결방법3) PSV 메모리 할당시 자동으로 하십시오. 컴파일러가 알아서 할당해줄 것이며,
PSVPAG = __builtin_psvpage(변수명); // <<---- 페이지 선언
이 한줄로 깔끔하게 해결될 것입니다.
끝으로, 제가 테스트한 아래 소스코드를 참조하시면 위에 설명한 내용들에 대한 이해가 되리라 봅니다.
MPLAB SIM 모드에서 Watch Window를 사용하시면 아주 쉽게 그 차이점을 이해하실 수 있습니다.
참고로, 프로젝트 파일을 압축해서 첨부드리겠습니다.
감사합니다.
//================ PSV Test Code ======================