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

 
 
> 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, 08:24
Сообщение #2


Участник
*

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



Очень жалко, что ответа найти не удается.
Проблема в том что я не знаю какую именно цифру ставить как вершину стека.
Вот если посмотреть листинг линкера - какой алгоритм выбора вершины?
Go to the top of the page
 
+Quote Post
AndreyS
сообщение Mar 22 2011, 18:50
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Добрый день.

Странный код у вас при вызове перевызываемой функции. Вот пример моей функции и ее листинг

Вот сама процедура на Си (первые цифры - это номера строк в коде, что бы легче было произвести сравнение с листингом)
На отсутствие return не смотрите.

Код
330 bit set_CS(byte set) reentrant
331 {
332     if (SPI_mas.ptrs[SPI_mas.rd].type==SPI_SD_card)
333     {// CS для карты памяти
334         CS_SD_card=(bit)set;
335         return(CS_SD_card);
336    }
337 }


Вот листинг. Тут видно что программный стек идет вниз (аппаратный идет вверх, SP. Вверх - к старшим адресам) из этого прямой вывод, что ставить начальный адрес надо как можно выше, лучше просто на максимум, т.е. вершину ставим не в конце всех переменных, а самый старший адрес памяти.

Код
            ; FUNCTION _?set_CS (BEGIN)
                                          ; SOURCE LINE # 330
0000 1500        E     DEC     ?C_IBP
0002 A800        E     MOV     R0,?C_IBP
0004 A607              MOV     @R0,AR7
                                          ; SOURCE LINE # 332
0006 900000      R     MOV     DPTR,#SPI_mas+025EH
0009 E0                MOVX    A,@DPTR
000A 75F00A            MOV     B,#0AH
000D A4                MUL     AB
000E 2400        R     ADD     A,#LOW SPI_mas+0267H
0010 F582              MOV     DPL,A
0012 E5F0              MOV     A,B
0014 3400        R     ADDC    A,#HIGH SPI_mas+0267H
0016 F583              MOV     DPH,A
0018 E0                MOVX    A,@DPTR
0019 B40209            CJNE    A,#02H,?C0043
                                          ; SOURCE LINE # 333
                                          ; SOURCE LINE # 334
001C A800        E     MOV     R0,?C_IBP
001E E6                MOV     A,@R0
001F 24FF              ADD     A,#0FFH
0021 92A0              MOV     CS_SD_card,C
                                          ; SOURCE LINE # 335
0023 A2A0              MOV     C,CS_SD_card
                                          ; SOURCE LINE # 336
                                          ; SOURCE LINE # 337
0025         ?C0043:
0025 C0D0              PUSH    PSW
0027 0500        E     INC     ?C_IBP
0029 D0D0              POP     PSW
002B 22                RET    
            ; FUNCTION _?set_CS (END)


В вашем примере я не обнаружил вообще вызов в стек. Есть какое то сложение данных по адресу 0x60 и все. То что в инициализации у вас в адрес 0x60 укладывается значение 0x7C (вы говорили о записи туда 0xFF) мне пока не говорит что это именно ?C_IBP (посмотрите ее значение в map файле, найдите в файл .map адрес этой переменной. В моем примере она лежит по адресу 0x13 в области DATA (т.е. директ мемори, не в XDATA).
В общем странно это все. У меня не происходит пересечения областей памяти при вызове первызываемых функций. Мало того IBPSTACK для small модели и складывает оно все в индерект память, а не в xdata как вы указали. У вас весь код в какой модели памяти? Нет ли прагма для отдельных файлов со сменой модели памяти для этих файлов (так тоже можно и оно отлично работает, нужно только в определении функции прописать ее тип модели и тогда при вызове процедуры с другой моделью никаких проблем не будет).

удачи.

Просмотрел еще раз сообщения. Ощущение что код у вас в compact, а стек вы упорно пытаетесь проинитить для small.


--------------------
Удачи.
Go to the top of the page
 
+Quote Post



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

 


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


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