Вопрос по С30, или танцы вокруг PSVPAG Мне нужно разместить в программе большие массивы данных
(знакогенератор). Но в С30 есть ограничение в 32кБ на
суммарный размер const.
Ясное дело, так как используется отображение
программной памяти на оперативку. А там размер этого окна 32кБ.
Но есть чудный файл: MPLAB_C30_Managed_PSV_Ptrs.pdf
Где приведен такой примерчик:
• Variables stored in a user managed PSV section char *foo __attribute__((space(psv))) = "a constant string"; int fibonacci[4] __attribute__((space(psv))) = { 1, 1, 2, 3 }; void bar() { int a,b; CORCONbits.PSV = 1; PSVPAG = __builtin_psvpage(fibonacci); a = fibonacci[1]; b = fibonacci[3]; PSVPAG = __builtin_psvpage(foo); 3 fprintf(stderr,"%s: %d %d\n", foo, a, b); } When compiled without specifying the constants-in-data memory model this program will fail at run-time. That is because the literal string in the call to fprintf will occupy the auto psv space and the PSVPAG setting has been changed. The other things to note are: – the user must ensure that the PSV window is enabled – only one PSVPAG is available at a time, so the user must cache some of the values before the call to fprintf – it really isn’t hard, just annoying Note, that this example can apply to data stored in EEDATA too as the hardware allows the EEDATA memory to be accessed via the PSV window.И тут возникают вопросы. Пишут, что если скомпилить с constants-in-data то все будет ОК с их fprintf(stderr,"%s: %d %d\n", foo, a, b); Можно подумать, что при обращении к const, расположенных в auto_psv компилер всегда будет юзать EEDATA (уж не знаю как) и понимает, что PSVPAG испорчен. Но это не так. Более того при включении/выключении опции компиляции constants-in-data КОД НЕ МЕНЯЕТСЯ. Что странно. И приходится далать примерно так: <c> unsigned short Rd_Line_Simvol(unsigned char Simv,unsigned char Colonka,unsigned char Font) //чтение знакогенератора { unsigned short Rez; //результат unsigned short Adres; //адрес нужного слова в памяти unsigned short Mem_PSVPAG; //для хранения PSVPAG unsigned char IPL; //уровень прерываний Rez=0x0000; //для несуществующих шрифтов IPL=SRbits.IPL; //уровень прерываний SRbits.IPL=0b111; //уровень прерываний 7 if(Font <= 2) //шрифты 0-2 { Adres=KShrift_Adr[Font]+Simv*33+Colonka*2; //вычислим адрес Mem_PSVPAG=PSVPAG; //сохранили PSVPAG PSVPAG=__builtin_psvpage(Font_Arr_02); //переключение PSVPAG Rez=(Font_Arr_02[Adres] << 8) | Font_Arr_02[Adres+1]; //читаем PSVPAG=Mem_PSVPAG; //восстановили PSVPAG } else if(Font <= 5) //шрифты 3-5 { Adres=KShrift_Adr[Font-3]+Simv*33+Colonka*2; //вычислим адрес Mem_PSVPAG=PSVPAG; //сохранили PSVPAG PSVPAG=__builtin_psvpage(Font_Arr_35); //переключение PSVPAG Rez=(Font_Arr_35[Adres] << 8) | Font_Arr_35[Adres+1]; //читаем PSVPAG=Mem_PSVPAG; //восстановили PSVPAG } SRbits.IPL=IPL; //восстановим уровень прерываний return Rez; //результат } </c> Так этот код становится ещё и критическим и приходится запрещать прерывания(в обработчиках могут юзаться const из auto_psv). Проще уж делать табличное чтение :( Почему не срабатывает constants-in-data ? Может лучше возится с Managed PSV pointers - 24-bit pointers ?