реклама на сайте
подробности

 
 
> Keil 9+Silabs C51+pdata, Как зарезервировать память под стек?
1kvi1
сообщение Mar 17 2011, 06:59
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 5-12-10
Пользователь №: 61 414



Всем, привет!
Делаю первый проект на С для С51.
Возникла следующая проблема.
При использовании модели памяти compact не удается определить местоположение стека.
То есть при вызове reentrant функции портятся переменные расположенные в памяти xdata по адресу меньше 0x100.
Проверил все опции, прочитал хелп, пользовался поиском - не могу найти решения проблемы.
Подскажите кто знает как исправить проблему.
Заранее спасибо!

Линкер генерит такую таблицу памяти

ACTIVE MEMORY CLASSES OF MODULE: msd-silabs (F34X_MSD_USB_MAIN)

BASE START END USED MEMORY CLASS
==========================================================
X:000000H X:000000H X:000FFFH 000CECH XDATA
X:000000H X:000000H X:000FFFH HDATA
C:000000H C:000000H C:00FFFFH ECODE
B00:0000H C:000000H C:00FFFFH HCONST
C:000000H C:000000H C:00FFFFH 008E13H CODE
X:000000H X:000000H X:0000FFH 0000B7H PDATA
I:000000H I:000000H I:00007FH 000046H DATA
C:000000H C:000000H C:00FFFFH 000131H CONST
I:000000H I:000000H I:0000FFH 000080H IDATA


Сообщение отредактировал 1kvi1 - Mar 17 2011, 06:21
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
1kvi1
сообщение Mar 22 2011, 02:07
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 36
Регистрация: 5-12-10
Пользователь №: 61 414



Цитата
Цитата(1kvi1 @ Mar 19 2011, 06:57) *
Старт-ап код я исправил и указал вершину на 0x100. Я так понимаю линкер должен это учесть и не располагать переменые и структуры ниже адреса 0x100?

Нет смысла править STARTUP.A51 для этого. Линкер его не анализирует. А располагает все переменные и структуры согласно выбранной модели памяти. Попробуйте установить модель памяти LARGE и увидите совсем другую картину, если конечно в программе нет ошибок.


Поставить модель LARGE я не могу по ряду причин. В программе нет ошибок (связанных с этой ситуацией).

Цитата
Несколько раз перечитал всю ветку, но так и не понял, что Вы называете проблемой, какое поведение хотите получить, а главное зачем?


Проблема в следующем - в проекте есть старт-ап код
Код
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF


Привожу его кусок куда нужно заострить внимание. Согласно документации выставляем PBPSTACK =1 и PBPSTACKTOP=0xFF. Это требуется при использовании модели PDATA.

Теперь внимание привожу пример листинга reentrant функции - то есть та которая использует программный (эмулируемый) стек, который как раз согласно модели и должен располагаться в xdata-памяти, в первой странице.

Код
   183: IF PBPSTACK <> 0
   184: EXTRN DATA (?C_PBP)
C:0x0DC8    755E00   MOV      0x5E,#0x00
   185:                 MOV     ?C_PBP,#LOW PBPSTACKTOP
   186: ENDIF
   187:  
C:0x0DCB    75607C   MOV      0x60,#Data_Ptr(0x7C)
   188:                 MOV     SP,#?STACK-1
   189:  
   190:; This code is required if you use L51_BANK.A51 with Banking Mode 4
   191:;<h> Code Banking
   192:; <q> Select Bank 0 for L51_BANK.A51 Mode 4
   193: #if 0    
   194:;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.


Фрагмент листинга - страт-ап кода - видим что переменная C_PBP куда мы записали вершину стека находится по адресу 0x60.

Код
C:0x8C2B    FD       MOV      R5,A
C:0x8C2C    08       INC      R0
C:0x8C2D    E2       MOVX     A,@R0
C:0x8C2E    FE       MOV      R6,A
C:0x8C2F    08       INC      R0
C:0x8C30    E2       MOVX     A,@R0
C:0x8C31    FF       MOV      R7,A
  1814: void SectorRemapUpdateLogPhy (unsigned long log,unsigned long phy) reentrant {
  1815:         unsigned char c;
C:0x8C32    E560     MOV      A,0x60
C:0x8C34    24FC     ADD      A,#PCA0CPH0(0xFC)
C:0x8C36    F560     MOV      0x60,A
C:0x8C38    F8       MOV      R0,A
C:0x8C39    1205C6   LCALL    C?LSTPDATA(C:05C6)
C:0x8C3C    E560     MOV      A,0x60
C:0x8C3E    24F4     ADD      A,#P3MDIN(0xF4)
C:0x8C40    F560     MOV      0x60,A
  1816:         unsigned char n=~0;
C:0x8C42    F8       MOV      R0,A
C:0x8C43    08       INC      R0
C:0x8C44    74FF     MOV      A,#VDM0CN(0xFF)
C:0x8C46    F2       MOVX     @R0,A


Собственно reentrunt функция. Использует переменную C_PBP как вершину стека и сохраняет в памяти локальный переменные. Выше указывал что C_PBP указывает на адрес 0xFF, куда линкер (простая душа) положил нужные переменные.

Код
* * * * * * * * * * *  X D A T A   M E M O R Y  * * * * * * * * * * * * *
000000H   00007BH   00007CH   BYTE   INPAGE   PDATA          _PDATA_GROUP_
00007CH   000089H   00000EH   BYTE   INPAGE   PDATA          ?PD?F34X_MSD_USB_ISR
00008AH   000095H   00000CH   BYTE   INPAGE   PDATA          ?PD?F34X_MSD_USB_DESCRIPTOR
000096H   0000A0H   00000BH   BYTE   INPAGE   PDATA          ?PD?_FREAD?F34X_MSD_FILE_SYSTEM
0000A1H   0000A6H   000006H   BYTE   INPAGE   PDATA          ?PD?_GET_FILE_NAME?F34X_MSD_FILE_SYSTEM
0000A7H   0000ACH   000006H   BYTE   INPAGE   PDATA          ?PD?_FINDNAME?F34X_MSD_FILE_SYSTEM
0000ADH   0000AFH   000003H   BYTE   INPAGE   PDATA          ?PD?_WAVPLAY_INIT?F34X_MSD_USB_MAIN
0000B0H   0003C8H   000319H   BYTE   UNIT     XDATA          ?XD?F34X_MSD_NF_BASIC_FUNCTIONS
0003C9H   0005D9H   000211H   BYTE   UNIT     XDATA          ?XD?F34X_MSD_SECT_SERV


Вот такая неприятная ситуация - сейчас занимаюсь тем что смотрю в листинге адрес _PDATA_GROUP_ и подставляю в старт-ап код соответствующее значение - тогда работает. Число 0x7b - адрес вершины стека согласно листингу.
Код
; <h> Stack Space for reentrant functions in the COMPACT model.    
;  <q> PBPSTACK: Enable COMPACT model reentrant stack
;     <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK        EQU     1      ; set to 1 if compact reentrant is used.
;
;   <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
;     <i> Set the top of the stack to the highest location.
PBPSTACKTOP     EQU     0x7B+1    ; default 0FFH+1  
; </h>
;</h>


Ну вот собственно вопрос - почему среда сама не ставит адрес вершины стека и как оптимизировать этот процесс. Я не так хорошо знаком с keil'ом как например с iar'ом (последний явно совершенней). Просьба напишите как сделать правильно - очень не хочется переносить проект под другую среду.

Заранее спасибо!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th July 2025 - 03:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.02437 секунд с 7
ELECTRONIX ©2004-2016