ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
22 ноября
96230
Petr_ (02.08.2007 23:25, просмотров: 804)
Вопрос по С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 ?