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

 
 
> Портирование программы с IAR на WinAVR (GCC), тонкости с асемблером
PrSt
сообщение Nov 14 2007, 11:37
Сообщение #1


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



привет всем!

Портировать пришлось программу из среды IAR на среду WinAVR (GCC), и столкнулся с тем что я чегото не понимаю или не знаю...
помогите плиз разобраться

Вот привожу кусок кода как это было под IAR
Код
NAME loader
;     INCLUDE ""
     PUBLIC loader6000
     RSEG CODE  

.globl loader6000

SCLK  DEFINE 0
Data  DEFINE 1
Latch DEFINE 2

PORTA var 18h    

.text      
loader6000;
...
...



Но программу нужно портировать на WinAVR

А вот как я сделал под WinAVR

Код
;NAME loader
;;     INCLUDE ""
;     PUBLIC loader6000
;     RSEG CODE  

.globl loader6000


;SCLK  DEFINE 0
;Data  DEFINE 1
;Latch DEFINE 2
#define SCLK  0
#define Data  1
#define Latch 2

;PORTA var 18h    
PORTA = 0x18    

.text      
;loader6000;
loader6000:
....


Программа компиллируется но не работает

я так подозреваю что я некоррктно першел от записи PORTA var 18h или чтото не так понял как правильно интерпретировать иаровский DEFINE
Код
SCLK  DEFINE 0
Data  DEFINE 1
Latch DEFINE 2

PORTA var 18h


к записи

Код
#define SCLK  0
#define Data  1
#define Latch 2

PORTA = 0x18


я не могу понять как ему можно еще сказать.
как сделать правильно?
подскажите плиз!




.


--------------------
Go to the top of the page
 
+Quote Post
2 страниц V  < 1 2  
Start new topic
Ответов (15 - 25)
PrSt
сообщение Nov 16 2007, 15:27
Сообщение #16


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(alcosar @ Nov 16 2007, 16:31) *
У Вас
Код
Data:      65087 bytes (1627.2% Full)
(.data + .bss + .noinit)

озу заполненно на 1627.2%. Не здесь ли собака порылась.

Хм!
Оппачки, И как этого я не заметил?!
та-а-ак - пошел котать сюда...
Не скучайте - скоро вернусь.


.


--------------------
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 19 2007, 13:08
Сообщение #17


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



проблема с памятью решена

...наткнулся на следующую проблемму, присущую именно пути портирования с IAR на GCC

как я понял из инета проблема эта у многих, не не понял как ее обходят, да и не нашел по форумам.

дело в том что в той программе что я редактирую есть некоторое веселье, в ней используется 2 длинных массива по 32k тоесть всего 64К данных в массиве и чуточку кода на 20К

...в иаре они были объявленны как
farflash unsigned char ga_field [32385] = {
0x0FF,0x0FF,....
}

Но для GCC я их сделал как
//farflash unsigned char ga_field [32385] = {
//__attribute__((progmem))
__ATTR_PROGMEM__ const unsigned char ga_field [32385] = {
0x0FF,0x0FF,....
}

если верить что я все верно понял их мануала на GCC и из интернета - то это правильно
Но есть у AVR друга проблемма, он не умеет прагать через длину кода с раздывом в адресе в 64K....

и видать с этим сзязано подвисание, вот я его локализовал и вот это место


SPDR = ga_field[i];
// veter
//------------------------------------------
// YELOW_1; //LED1_off; LEDs |= LED1C
RED_1; //LED1_off; LEDs |= LED1A
// YELOW_2; //LED2_off; LEDs |= LED2C
RED_2; //LED2_off; LEDs |= LED2A
//------------------------------------------
while(!(SPSR&SPIF));
// veter
//------------------------------------------
YELOW_1; //LED1_off; LEDs |= LED1C
// RED_1; //LED1_off; LEDs |= LED1A
YELOW_2; //LED2_off; LEDs |= LED2C
// RED_2; //LED2_off; LEDs |= LED2A
//------------------------------------------

так вот я вижу только загоревшиеся красные сретодиоды RED_1; и RED_2; и потом срабатывает ватч дог на опереции чтения флага статуса о собитии прерывания - while(!(SPSR&SPIF));.
тоесть желтых не вижу - что и логично раз сработал ватчдог.

значит проблемма может быть или при операции (SPDR = ga_field[i] wink.gif или же в вызове чтения флага прерывания...

теперь,
помогите пожалуйста дальше разобраться - а то тут я не могу уже понять куда копать

Ребята - крыша улетает, нид хелп.

.


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 19 2007, 13:33
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



По объявлению - можно и так: prog_uint8_t ga_field [32385] = {...};
По коду: Во-первых SPDR = pgm_read_byte(&ga_field[i]); А почему собака - трудно сказать. Передача по SPI идет? Попробуйте просто передавать что-нибудь типа SPDR = 0xAA, может у вас SPI не проинициализирован и передачи нет, поэтому и флаг не выставляется.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 19 2007, 13:57
Сообщение #19


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Сергей Борщ @ Nov 19 2007, 15:33) *
По объявлению - можно и так: prog_uint8_t ga_field [32385] = {...};
По коду: Во-первых SPDR = pgm_read_byte(&ga_field[i]); А почему собака - трудно сказать. Передача по SPI идет? Попробуйте просто передавать что-нибудь типа SPDR = 0xAA, может у вас SPI не проинициализирован и передачи нет, поэтому и флаг не выставляется.


через SPDR = pgm_read_byte(&ga_field[i]); - щас попробую, покапаю в эту сторону

SPI - еще не тестится осциллограффом по прицине что прибор закрыт пока, хотя возможно прийдется его разбирать.

до SPI еще дело не дошло как мне кажется
и следующий тест это подтвердил
вот я сделал ловушку
SPDR = ga_field[i];
if (ga_field[0]==0x00){
// veter
//------------------------------------------
// YELOW_1; //LED1_off; LEDs |= LED1C
RED_1; //LED1_off; LEDs |= LED1A
YELOW_2; //LED2_off; LEDs |= LED2C
// RED_2; //LED2_off; LEDs |= LED2A
//------------------------------------------
while (1);
}

и программа на эту ловушку словилась
потому что споймала 0х00 вместо значения из массива 0xFF

таким образом становится очевидно что продлемма кроется скорее не в прерывании на данном этапе а на полученном значении из массива

.


--------------------
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 20 2007, 08:11
Сообщение #20


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Сергей Борщ @ Nov 19 2007, 15:33) *
По объявлению - можно и так: prog_uint8_t ga_field [32385] = {...};
По коду: Во-первых SPDR = pgm_read_byte(&ga_field[i]); А почему собака - трудно сказать.

1111493779.gif
так я тоже исппробовал, как Вы посоветовали - не помогло
все одно срабатывает ловушка
пробовал так
SPDR = pgm_read_byte(&ga_field[i])
и так
SPDR = pgm_read_byte(&ga_field+i)
и так
SPDR = pgm_read_byte(&ga_field[0]+i)

не помогло sad.gif

help.gif
.


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 20 2007, 08:40
Сообщение #21


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(PrSt @ Nov 20 2007, 10:11) *
не помогло sad.gif
Все три варианта эквивалентны. Передача происходит? SPI инициализируется? Покажите инициализацию, поставьте в нее ловушку, убедитесь что программа попадает в инициализацию.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 20 2007, 08:55
Сообщение #22


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Сергей Борщ @ Nov 20 2007, 10:40) *
Все три варианта эквивалентны.

разобрался
правильно не так
SPDR = pgm_read_byte(&ga_field[i])
а так
SPDR = pgm_read_byte(ga_field+i)
тоесть не нужно разадрессовывать массив при передаче в функцию, 0й элемент и есть же адрес массива.
теперь значение получил из массива 0xFF.

но делу это не помогло похоже

Код
    for(i = 0; i < ga_count; i++)
    {        
      //SPDR = ga_field[i];
        SPDR = pgm_read_byte(ga_field[i]);

// veter
//------------------------------------------
//  YELOW_1;  //LED1_off; LEDs |= LED1C
  RED_1;    //LED1_off; LEDs |= LED1A
//  YELOW_2;  //LED2_off; LEDs |= LED2C
  RED_2;    //LED2_off; LEDs |= LED2A
//------------------------------------------
      while(!(SPSR&SPIF));
// veter
//------------------------------------------
  YELOW_1;  //LED1_off; LEDs |= LED1C
//  RED_1;    //LED1_off; LEDs |= LED1A
  YELOW_2;  //LED2_off; LEDs |= LED2C
//  RED_2;    //LED2_off; LEDs |= LED2A
//------------------------------------------

горят красные светодиоды, значит продлемма осталась с прерыванием.

crying.gif help.gif


Цитата(Сергей Борщ @ Nov 20 2007, 10:40) *
Пере дача происходит? SPI инициализируется? Покажите инициализацию, поставьте в нее ловушку, убедитесь что программа попадает в инициализацию.


вот инициализация
в IARовском варианте она работало
Код
void set_spi(void)
{
  DDRB=0x17;
  PORTB=0xF0;  //11110000   open drain input          

  SPCR = SPE|DORD|MSTR;
}

вроде все впорядке...



.


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 20 2007, 09:33
Сообщение #23


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(PrSt @ Nov 20 2007, 10:55) *
разобрался
правильно не так
SPDR = pgm_read_byte(&ga_field[i])
а так
SPDR = pgm_read_byte(ga_field+i)
Давайте смотреть листинг. С точки зрения синтаксиса оба варианта тождественны. В первом случае вы берете адрес i-го элемента масива, во втором - берете адрес массива и прибавляете к нему размер i элементов, т.е. получаете тот же адрес i-го элемента. Первая запись более наглядна.
Цитата(PrSt @ Nov 20 2007, 10:55) *
вот инициализация
в IARовском варианте она работало
Программа точно в это место попадает? Раз не выставляется SPIF, значит не идет передача, значит SPI не проинициализирован в режим мастер. Прерывание у вас не разрешено, значит прерывание сбросить SPIF не может. Других мыслей у меня нет... Или может в этот момент срабатывает какое-то другое прерывание и программа циклится в обработчике? Попробуйте перед зажиганием красных светлодиодов запретить прерывания. Если поможет - ищите, в какой вектор улетает программа.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 20 2007, 10:25
Сообщение #24


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Сергей Борщ @ Nov 20 2007, 11:33) *
Давайте смотреть листинг. С точки зрения синтаксиса оба варианта тождественны. В первом случае вы берете адрес i-го элемента масива, во втором - берете адрес массива и прибавляете к нему размер i элементов, т.е. получаете тот же адрес i-го элемента. Первая запись более наглядна.

да тождественны не спорю. кстати пробовал даже так
SPDR = pgm_read_byte_far((unsigned short)(ga_field+i));
вместо
SPDR = pgm_read_byte((unsigned short)(ga_field+i));

почему pgm_read_byte_far? так советуют.

Код
/* I read in file pgmspace.h :
    \note If possible, put your constant tables in the lower 64 KB and use
    pgm_read_byte_near() or pgm_read_word_near() instead of
    pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
    way, and you can still use the upper 64K for executable code.
    All functions that are suffixed with a \c _P \e require their
    arguments to be in the lower 64 KB of the flash ROM, as they do
    not use ELPM instructions.  This is normally not a big concern as
    the linker setup arranges any program space constants declared
    using the macros from this header file so they are placed right after
    the interrupt vectors, and in front of any executable code.  However,
    it can become a problem if there are too many of these constants, or
    for bootloaders on devices with more than 64 KB of ROM.
    <em>All these functions will not work in that situation.
*/



Цитата(Сергей Борщ @ Nov 20 2007, 11:33) *
Программа точно в это место попадает? Раз не выставляется SPIF, значит не идет передача, значит SPI не проинициализирован в режим мастер. Прерывание у вас не разрешено, значит прерывание сбросить SPIF не может. Других мыслей у меня нет...


И проходит инициализацию SPI тоже, вот
Да, точно попадает в нее.

Код
  set_spi();    
  set_UART();

if (eeprom.Speed==0xff)
    {
        //load_FLEX6000_old();
    }
else
    {
        load_FLEX6000();  
    }


load_FLEX6000(); - это и есть текущая процедура с приведениями и фантомами которые тут обсуждаются.

и вот она

Код
void load_FLEX6000(void)
{                
  unsigned char OKLoad;
  unsigned int i;
  
  OKLoad = 1;

  while(OKLoad)
  {
.....
// veter
//------------------------------------------
  YELOW_1;  //LED1_off; LEDs |= LED1C
//  RED_1;    //LED1_off; LEDs |= LED1A
//  YELOW_2;  //LED2_off; LEDs |= LED2C
  RED_2;    //LED2_off; LEDs |= LED2A
//------------------------------------------
    for(i = 0; i < ga_count; i++)
    {        
      //SPDR = ga_field[i];
        SPDR = pgm_read_byte_far((unsigned short)(ga_field+i));

// veter
//------------------------------------------
//  YELOW_1;  //LED1_off; LEDs |= LED1C
  RED_1;    //LED1_off; LEDs |= LED1A
//  YELOW_2;  //LED2_off; LEDs |= LED2C
  RED_2;    //LED2_off; LEDs |= LED2A
//------------------------------------------
      while(!(SPSR&SPIF));
// veter
//------------------------------------------
  YELOW_1;  //LED1_off; LEDs |= LED1C
//  RED_1;    //LED1_off; LEDs |= LED1A
  YELOW_2;  //LED2_off; LEDs |= LED2C
//  RED_2;    //LED2_off; LEDs |= LED2A
//------------------------------------------
      if(!(InLoad & nStatus)) break;
    }
    if(i >= ga_count - 1) OKLoad = 0;
  }              
.....    
}


и я постоянно наблюдаю красные светодиоды...


Цитата(Сергей Борщ @ Nov 20 2007, 11:33) *
Или может в этот момент срабатывает какое-то другое прерывание и программа циклится в обработчике? Попробуйте перед зажиганием красных светлодиодов запретить прерывания. Если поможет - ищите, в какой вектор улетает программа.

угу, щас покопаю в этом направлении тоже, тем более что вид HEX файла в PonyProg.е на это намикает, в начале HEX файла какието значения присутствуют может то и есть прерывания лишние.

:100000000C94B13F0C94D13F0C94D13F0C94D13F50
:100010000C94D13F0C94D13F0C94D13F0C94D13F20
:100020000C94D13F0C94D13F0C94D13F0C94D13F10
:100030000C94D13F0C94D13F0C94D13F0C94D13F00
:100040000C94D13F0C94D13F0C9461600C94D13F3F
:100050000C94D13F0C94D13F0C94D13F0C94D13FE0
это наверно программа, точнее ее кусок.
:100060004120000042C80000461C40004CBEBC209D
:100070005A0E1BCA749DC5AE3DCCCCCD3C23D70ACD
:1000800038D1B717322BCC7724E695950A4FB11F9C
:100090000639652C033AA23B593C1EBAE03D633B4E
:1000A000F43E75FF4E3F3172113F80000000054065
:1000B000B504F441A0000141E2463241A0000040F5
:1000C000E246303F8000000541778C4F40C32CE270
:1000D0004117BF24C1A48DD9C0E1D8A1C05B6782FC
это уже массив, который я и читаю как pgm_read_byte_far((unsigned short)(ga_field+i));
:1000E000FFFF627516FFFFFFFFFFFFFFFFFFFFFF30
:1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10
:10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FE
....
....

который объявлен как
//const unsigned char ga_field [32385] __ATTR_PROGMEM__ = {
prog_uint8_t ga_field [32385] = {...}

так вот к чему я веду
вот начало HEX от программы собранной IAR

:100000000C9433000000000000000000000000001D
:1000100000000000000000000000000000000000E0
:10002000000000000C9455110000000000000000CA
:1000300000000000000000000000000000000000C0
:100040000C94E110000000000C94D213000000009A
:10005000000000000C94A010FFFFFFFFFFFFFFFF58
:10006000FFFF00EC05BFCDEFD4E000EE03500DBF65
:1000700000E000400EBF0E94C016002309F424D007
:10008000E0E6F0E000E010E00E942619E0EDF0E08C
:1000900000E610E040E050E00E941819E3E0F1E0D3
:1000A0000DEB10E00E942619E0EDF0E000EE10E00C

как видно от сюда - в начале похоже что это явно ссылка на обработчики прерывания остальное забито нулями, в отличие от моего HEX собранного под GCC
вот я не могу понять - это нужно какойто ключик дополнительный компилятору указать или же нужно в коде прорнаммы явно отключать все прерывания?


...помогите плз, а то уже хочется повеситься на полку. help.gif help.gif

.


--------------------
Go to the top of the page
 
+Quote Post
PrSt
сообщение Nov 20 2007, 14:51
Сообщение #25


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Сергей Борщ @ Nov 20 2007, 11:33) *
Прерывание у вас не разрешено, значит прерывание сбросить SPIF не может. Других мыслей у меня нет... Или может в этот момент срабатывает какое-то другое прерывание и программа циклится в обработчике? Попробуйте перед зажиганием красных светлодиодов запретить прерывания. Если поможет - ищите, в какой вектор улетает программа.

полез я осцилограффом и пощюпал шину SPI судя по всему она не работает с этим моим полученным HEX, нет даже клоков на шине.
похоже чтото такое там происходит что я не могу предположить.
я уже и проверки делал - вроде все ок
Код
void set_spi(void)
{
  DDRB=0x17;
  PORTB=0xF0;  //11110000   open drain input          

  SPCR = SPE|DORD|MSTR;

if (&SPCR == 0x2d){
// veter
//------------------------------------------
//  YELOW_1;  //LED1_off; LEDs |= LED1C
  RED_1;    //LED1_off; LEDs |= LED1A
  YELOW_2;  //LED2_off; LEDs |= LED2C
//  RED_2;    //LED2_off; LEDs |= LED2A
//-----------------------------------------
while (1);

}

}

что это может быть за проблемма?


на этой же прошивке от IAR - все работает.

.


--------------------
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 20 2007, 14:58
Сообщение #26


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(PrSt @ Nov 20 2007, 16:51) *
Код
  SPCR = SPE|DORD|MSTR;

на этой же прошивке от IAR - все работает.
ЧуднО smile.gif Странный у вас ИАР - и указатели присваивает, и биты у него описаны иначе smile.gif SPCR = ( 1 << SPE) | ( 1 << DORD) | (1 << MSTR);

Исправлено: Извините, про указатели это я с другой веткой попутал.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

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

 


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


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