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

 
 
> 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
O.L.
сообщение Mar 22 2011, 07:05
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890



Цитата(1kvi1 @ Mar 22 2011, 08:07) *
Ну вот собственно вопрос - почему среда сама не ставит адрес вершины стека и как оптимизировать этот процесс. Я не так хорошо знаком с keil'ом как например с iar'ом (последний явно совершенней). Просьба напишите как сделать правильно - очень не хочется переносить проект под другую среду.


Теперь понятно
Покрутил в симуляторе свои reentrant функции, в последнее время я крайне редко их применяю. Действительно, нет у Keil-a возможности автоматического определения вершину стека.
Вот что пашет Keil по этому поводу.
Цитата
PBPSTACKTOP:
Specifies the top of the small model reentrant stack. The default is 0xFF in idata memory.
The Cx51 Compiler does not check to see if the stack area available satisfies the requirements of the application. It is your responsibility to perform such a test.


Получается, что Вы можете либо использовать другой компайлер, либо переработать проект и избавиться от reentrant функций, либо после каждой компиляции править руками STARTUP.
Хотел помочь, но увы sad.gif

Сообщение отредактировал O.L. - Mar 22 2011, 08:23
Go to the top of the page
 
+Quote Post



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

 


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


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