Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Подскажите где в WinAVR задаётся размер стека ?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
west329_
Перевожу программу с WinAVR на IAR AVR.

Проект нормально собирается в WinAVR-2007122 в Programmers Notepad.

Первой что непонятно, в иаре чётко надо указывать стек для контроллера, перерыл все исходники WinAVR и make файл, ничего чтоб указывало на стек ненашол ? подскажите как быть ?
Сергей Борщ
Цитата(west329_ @ Dec 19 2008, 10:41) *
перерыл все исходники WinAVR и make файл, ничего чтоб указывало на стек ненашол ? подскажите как быть ?
Читать описание на avr-libc (index.html->User Manual->Memory Areas and Using malloc()). Указатель стека ставится на конец набортного ОЗУ. Под стек отводится вся оставшаяся свободной набортная память.
west329_
Подскажите как правильно уйти от типа "prog_char" онже "PROGMEM" онже "prog_void" обявленного в WinAVR ?

Аналогично PSTR() ?

Имеются такие процедуры
Код
.
#include <avr/pgmspace.h>
.
.
.
extern uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s);
extern uint16_t fill_tcp_data(uint8_t *buf,uint16_t pos, const char *s);
.
.

.
plen=fill_tcp_data(buf,plen,password);
plen=fill_tcp_data_p(buf,plen,PSTR("/\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
_Pasha
Цитата(Сергей Борщ @ Dec 19 2008, 12:51) *
Указатель стека ставится на конец набортного ОЗУ. Под стек отводится вся оставшаяся свободной набортная память.

Есть еще момент, хорошо подаваемый AVRStudio gcc plugin.
Кусок makefile. Опция линкера -minit-stack для задания начального адреса стека.
Код
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -minit-stack=0x100
Сергей Борщ
Цитата(_Pasha @ Dec 19 2008, 11:59) *
Опция линкера -minit-stack для задания начального адреса стека.
Не знал. Надо будет посмотреть, как она реализована. Если также, как в mspgcc - в прологе main() прописывает указатель - то это не лучшее решение. Лишний расход кода - указатель и так прописывается в стартап-коде в секции .init2. Если выкинуть .init2, программа рушится на возврате из первого же конструктора в .init6 или на возврате из первой же пользовательской функции в .init3-.init8.

Проверил. На 20070525 не работает вообще.

Но есть решение: можно передать начальный адрес как значение символа __stack:
Код
LDFLAGS += -Wl,--defsym,__stack=0x100
Тогда этот адрес будет подставлен в .init2 без всяких накладных расходов.
west329_
Работо по переделки prog_char немного приостановил, за ненадобность в данный момент этих процедур.

Появился вопрос по функциям _delay_ms() _delay_us;

Подскажите простенький дефайн на С, который бы молотил пустые цыклы NOP() исходя из заданных параметров F_CPU ?

Пару раз встречал , но както недогодался сохранить.
mdmitry
Цитата(west329_ @ Dec 19 2008, 14:06) *
Подскажите простенький дефайн на С, который бы молотил пустые цыклы NOP() исходя из заданных параметров F_CPU ?

Пару раз встречал , но както недогодался сохранить.

Посмотрите файлы delay_basic.h и delay.h. Должно помочь. Изучение заголовочных файлов и описания avr-libc мне сильно помогло.
west329_
Цитата(mdmitry @ Dec 19 2008, 16:05) *
Посмотрите файлы delay_basic.h и delay.h. Должно помочь. Изучение заголовочных файлов и описания avr-libc мне сильно помогло.


это перенесётся на IAR согласен
Код
void
_delay_ms(double __ms)
{                            
    uint16_t __ticks;
    double __tmp = ((F_CPU) / 4e3) * __ms;
    if (__tmp < 1.0)
        __ticks = 1;
    else if (__tmp > 65535)
    {
        //    __ticks = requested delay in 1/10 ms
        __ticks = (uint16_t) (__ms * 10.0);
        while(__ticks)
        {
            // wait 1/10 ms
            _delay_loop_2(((F_CPU) / 4e3) / 10);
            __ticks --;
        }
        return;
    }
    else
        __ticks = (uint16_t)__tmp;
    _delay_loop_2(__ticks);                
}


а как быть с этим

Код
void
_delay_loop_2(uint16_t __count)
{
    __asm__ volatile (
        "1: sbiw %0,1" "\n\t"
        "brne 1b"
        : "=w" (__count)
        : "0" (__count)
    );
}


я, в асме из под IAR несилён, подскажите как это можно под IAR переписать ?
_Pasha
Цитата(Сергей Борщ @ Dec 19 2008, 14:54) *
Проверил. На 20070525 не работает вообще.

В 20081205 тоже, оказывается, не работает sad.gif
Сергей Борщ
Цитата(west329_ @ Dec 19 2008, 14:12) *
я, в асме из под IAR несилён, подскажите как это можно под IAR переписать ?
Код
_delay_ms(double __ms) = __delay_cycles(__ms * F_CPU / 1000)
west329_
Цитата(Сергей Борщ @ Dec 19 2008, 18:06) *
Код
_delay_ms(double __ms) = __delay_cycles(__ms * F_CPU / 1000)


у меня ИАР отказывается собирать
Код
Fatal Error[Ta030]: Argument to __delay_cycles must be a constant expression.


посмотрел в описании __delay_cycles
Код
__intrinsic void __delay_cycles(unsigned long);


ругается на то что __ms переменная а не константа, подскажите что делать ?
SysRq
Цитата(west329_ @ Dec 19 2008, 19:28) *
ругается на то что __ms переменная а не константа, подскажите что делать ?

Дать константу, как просит.
Переменную можете оформить себе сами в виде цикла с вызовом внутри него __delay_cycles() с необходимой константой (учтите поправку на сам цикл).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.