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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Помогите переписать код для GCC под IAR
smk
сообщение Feb 1 2012, 16:39
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Суть такова: помещаем массив во flash и потом побайтно читаем.
В GCC:

Код
unsigned char brightness[256] PROGMEM = //табличка визуально равномерно наращивающая яркость
{0,0,0,1,1,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9,10,10,10,11,11,12,12,
12,12,13,13,13,13,13,14,14,14,14,15,15,15,16,16,16,16,17,17,17,18,18,
18,19,19,19,19,20,20,20,21,21,21,22,22,22,22,23,23,23,24,24,24,25,25,
25,25,26,26,26,27,27,27,28,28,28,28,29,29,30,30,31,31,32,32,33,34,34,
35,35,36,37,38,38,39,40,41,41,42,43,44,44,45,46,47,48,48,49,50,51,52,
52,53,54,55,56,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,
75,76,77,78,79,80,82,83,84,86,87,88,89,91,92,94,95,97,99,101,102,104,
106,107,109,111,113,114,116,118,120,122,123,125,127,129,131,134,136,
138,140,142,145,147,149,151,153,156,158,160,162,164,167,169,171,173,
175,177,179,182,184,186,188,190,192,193,195,197,198,200,202,203,205,
206,208,210,211,213,215,217,218,220,222,223,225,226,228,229,231,232,
233,235,236,237,239,240,241,242,243,244,245,246,247,249,250,251,252,
253,254,255};

if((pwm>pgm_read_byte(&brightness[count_pwm]))|(pwm==0)){sig_off;}


А как такое делается в IAR? Спасибо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
shmur
сообщение Feb 1 2012, 16:54
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553



Объявить как const и IAR сам поместит в ro секцию.

Или явно указать место, куда нужно поместить
Код
#pragma location="PROGMEM"
unsigned char brightness[256] =
//или так
unsigned char brightness[256] @ PROGMEM  =
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 17:09
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(smk @ Feb 1 2012, 18:39) *
Суть такова: помещаем массив во flash и потом побайтно читаем.
В GCC:

Код
unsigned char brightness[256] PROGMEM = //табличка визуально равномерно наращивающая яркость
{0,0,0,1,1,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9,10,10,10,11,11,12,12,
12,12,13,13,13,13,13,14,14,14,14,15,15,15,16,16,16,16,17,17,17,18,18,
18,19,19,19,19,20,20,20,21,21,21,22,22,22,22,23,23,23,24,24,24,25,25,
25,25,26,26,26,27,27,27,28,28,28,28,29,29,30,30,31,31,32,32,33,34,34,
35,35,36,37,38,38,39,40,41,41,42,43,44,44,45,46,47,48,48,49,50,51,52,
52,53,54,55,56,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,
75,76,77,78,79,80,82,83,84,86,87,88,89,91,92,94,95,97,99,101,102,104,
106,107,109,111,113,114,116,118,120,122,123,125,127,129,131,134,136,
138,140,142,145,147,149,151,153,156,158,160,162,164,167,169,171,173,
175,177,179,182,184,186,188,190,192,193,195,197,198,200,202,203,205,
206,208,210,211,213,215,217,218,220,222,223,225,226,228,229,231,232,
233,235,236,237,239,240,241,242,243,244,245,246,247,249,250,251,252,
253,254,255};

if((pwm>pgm_read_byte(&brightness[count_pwm]))|(pwm==0)){sig_off;}


А как такое делается в IAR? Спасибо.

Так например:
Код
__flash unsigned char brightness[256]={.....}
if (brightness[count_pwm]....) {...}
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 1 2012, 17:15
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Сделал #pragma location="PROGMEM". Теперь вот такую ошибку пишет.

Код
Error[Pe095]: array is too large D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16
Error[Be010]: segment/section name not allowed (object must have static storage duration and be const or __no_init) D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16


Цитата(_Артём_ @ Feb 1 2012, 19:09) *
Так например:
Код
__flash unsigned char brightness[256]={.....}
if (brightness[count_pwm]....) {...}

Пробовал. выдает ошибку.

В нелпе как-то через указатель делается. Кто-то так делал?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 17:18
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(shmur @ Feb 1 2012, 18:54) *
Объявить как const и IAR сам поместит в ro секцию.

Нет не поместит (в общем случае)
Код
__root const unsigned char StartStr[]="1234";

StartStr помещена в SRAM по адресу 0x214E. Нужно явно указывать в настройках (почему-то нельзя выбрать

Прикрепленное изображение
)
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 1 2012, 17:21
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(_Артём_ @ Feb 1 2012, 19:18) *
Нет не поместит (в общем случае)
Код
__root const unsigned char StartStr[]="1234";

StartStr помещена в SRAM по адресу 0x214E. Нужно явно указывать в настройках (почему-то нельзя выбрать

Прикрепленное изображение
)

Галка там есть и была раньше.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 17:30
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(smk @ Feb 1 2012, 19:15) *
Сделал #pragma location="PROGMEM". Теперь вот такую ошибку пишет.

Код
Error[Pe095]: array is too large D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16
Error[Be010]: segment/section name not allowed (object must have static storage duration and be const or __no_init) D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16



Пробовал. выдает ошибку.

В нелпе как-то через указатель делается. Кто-то так делал?

У меня работает.
Код
__root __farflash unsigned char brightness[256]={....}
void SystemTimer() {
    PORTB.OUT=brightness[int_cnt++];
}

Может места нет?
Цитата
Галка там есть и была раньше.

Странно что её выбрать/отменить нельзя - неразрешена.
Go to the top of the page
 
+Quote Post
shmur
сообщение Feb 1 2012, 17:34
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 28-11-11
Пользователь №: 68 553



Цитата(smk @ Feb 1 2012, 20:15) *
Сделал #pragma location="PROGMEM". Теперь вот такую ошибку пишет.

Код
Error[Pe095]: array is too large D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16
Error[Be010]: segment/section name not allowed (object must have static storage duration and be const or __no_init) D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 16


Нужно с const
Код
#pragma location="PROGMEM"
[b]const[/b] unsigned char brightness[256] = {...}

PROGMEM должен быть определен в конфиг файле линкера, примерно так:
place in ROM_region { readonly section PROGMEM };

Если что курите иаровский DevelopmentGuide, там обо всем этом неплохо написано.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 18:06
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Кстати, а что за проц?
Я про АВР писал, у других архитектур может быть иначе.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Feb 1 2012, 18:07
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



способов куча, смотря что нужно.

1. через #pragma location=
только там писать не "PROGMEM", а имя сегмента памяти. Можно завести свой, можно посмотреть в документации как называются те, что компилятор сам использует.

2. через extended keywords, а конкретно __flash или __farflash
Удобно тем, что не нужно руками заводить сегментов как в (1) и потом объяснять линкеру что с этими сегментами делать.

3. Объявлять переменную с модификатором const, но по умолчанию он поместит такую переменную в RAM и проинициализирует, нужно это где-то в настройках указывать.

Функции типа pgm_read_byte() для доступа не нужны, компилятор сам знает как прочитать из флэши.

В папке /doc есть подробная дока, где описаны все особенности реализации, расширения языка и прочее.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 1 2012, 18:23
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(_Артём_ @ Feb 1 2012, 20:06) *
Кстати, а что за проц?
Я про АВР писал, у других архитектур может быть иначе.

Tiny13a

Сделал вот так
Код
__flash const unsigned char brightness[256] =


Пишет ошибку
Код
Error[e16]: Segment CODE (size: 0x30e align: 0x1) is too long for segment definition. At least 0x26 more bytes needed. The problem occurred while processing the segment placement command  
"-Z(CODE)CODE=_..X_FLASH_BASE-_..X_FLASH_END", where at the moment of placement the available memory ranges were "CODE:118-3ff"
   Reserved ranges relevant to this placement:
   CODE:14-113          NEAR_F
   CODE:114-117         INITTAB
   CODE:118-3ff         CODE


И еще это почему-то не нравится

Код
unsigned int read_adc (void)
{
unsigned int adc_res=0;
ADCSRA |= (1<<6);
while (!(ADCSRA & (1<<4)));
adc_res = ((ADCH<<8)+ADCL);
return adc_res;
}


Код
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 54





--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 18:31
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(smk @ Feb 1 2012, 20:23) *
Tiny13a

Сделал вот так
Код
__flash const unsigned char brightness[256] =


Пишет ошибку
Код
Error[e16]: Segment CODE (size: 0x30e align: 0x1) is too long for segment definition. At least 0x26 more bytes needed. The problem occurred while processing the segment placement command  
"-Z(CODE)CODE=_..X_FLASH_BASE-_..X_FLASH_END", where at the moment of placement the available memory ranges were "CODE:118-3ff"
   Reserved ranges relevant to this placement:
   CODE:14-113          NEAR_F
   CODE:114-117         INITTAB
   CODE:118-3ff         CODE


Цитата
At least 0x26 more bytes needed.

Что-то памяти ему мало. Попробуйте уменьшить массив на 0x26 байт или упростите программу (только чтобы посмотреть откомпилируется ли и куда положит)

Цитата(smk @ Feb 1 2012, 20:23) *
Код
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\DATA\IAR_AVR\DatMSL\DatMSL_main.c 54

Ему не нравится такое выражение:
Цитата
adc_res = ((ADCH<<8)+ADCL);

Можно так:
Код
adc_res = ADC;





Go to the top of the page
 
+Quote Post
smk
сообщение Feb 1 2012, 18:45
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(_Артём_ @ Feb 1 2012, 20:31) *
Что-то памяти ему мало. Попробуйте уменьшить массив на 0x26 байт или упростите программу (только чтобы посмотреть откомпилируется ли и куда положит)


Ему не нравится такое выражение:

Можно так:
Код
adc_res = ADC;

Попробовал, получилось. Спасибо.

По части памяти я очень удивлен. GCC откомпилировал в 936 байт, а на ИАР как раз перетягиваю т.к. нужно кое-чего добавить, а у ИАР говорят код компактней. Может привести код целиком?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 1 2012, 18:53
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(smk @ Feb 1 2012, 20:45) *
Попробовал, получилось. Спасибо.

По части памяти я очень удивлен. GCC откомпилировал в 936 байт, а на ИАР как раз перетягиваю т.к. нужно кое-чего добавить, а у ИАР говорят код компактней. Может привести код целиком?


Может и привести...

Цитата(smk @ Feb 1 2012, 20:45) *
По части памяти я очень удивлен. GCC откомпилировал в 936 байт, а на ИАР как раз перетягиваю т.к. нужно кое-чего добавить, а у ИАР говорят код компактней. Может привести код целиком?


Какая оптимизация установлена?
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 1 2012, 19:22
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Оптимизация максимальная по размеру.

Код
#include <ioavr.h>
#include <intrinsics.h>


#include <stdio.h>

#define sig_off PORTB &= ~(1<<2)//âêë êîíòðîëüíûé ñâåòîäèîä
#define sig_on PORTB |= (1<<2)  //âûêë êîíòðîëüíûé ñâåòîäèîä
#define sensibility  120//50            //÷óâñòâèòåëüíîñòü
//#define div_on_off 200//200 ñêîðîñòü ïëàâíîãî çàæèãàíèÿ/ãàøåíèÿ
//#define set_time 2 //ïàóçà ïåðåä ãàøåíèåì â ñåêóíäàõ

__flash const unsigned char brightness[256] = //òàáëè÷êà âèçóàëüíî ðàâíîìåðíî íàðàùèâàþùàÿ ÿðêîñòü
{0,0,0,1,1,2,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,8,9,9,10,10,10,11,11,12,12,
12,12,13,13,13,13,13,14,14,14,14,15,15,15,16,16,16,16,17,17,17,18,18,
18,19,19,19,19,20,20,20,21,21,21,22,22,22,22,23,23,23,24,24,24,25,25,
25,25,26,26,26,27,27,27,28,28,28,28,29,29,30,30,31,31,32,32,33,34,34,
35,35,36,37,38,38,39,40,41,41,42,43,44,44,45,46,47,48,48,49,50,51,52,
52,53,54,55,56,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,
75,76,77,78,79,80,82,83,84,86,87,88,89,91,92,94,95,97,99,101,102,104,
106,107,109,111,113,114,116,118,120,122,123,125,127,129,131,134,136,
138,140,142,145,147,149,151,153,156,158,160,162,164,167,169,171,173,
175,177,179,182,184,186,188,190,192,193,195,197,198,200,202,203,205,
206,208,210,211,213,215,217,218,220,222,223,225,226,228,229,231,232,
233,235,236,237,239,240,241,242,243,244,245,246,247,249,250,251,252,
253,254,255};

volatile unsigned int adc_data;//íàïðÿæåíèå íà âûõîäå ÈÊ äàò÷èêà òåêóùåå
volatile unsigned int _adc_data;//íàïðÿæåíèå íà âûõîäå ÈÊ äàò÷èêà ïðåäèäóùåå
volatile unsigned int tick_count,dev_pwm;//äåëèòåëü ÷àñòîòû ØÈÌ
volatile unsigned char status_flag,delta,pwm,my_time,count_pwm,detect;//ñêîðîñòü èçìåíåíèÿ (îòñ÷åòîâ ÀÖÌ / 50 ìñ)
volatile unsigned char div_on_on, div_on_off, set_time;

unsigned int read_adc (void)
{
ADCSRA |= (1<<6);
while (!(ADCSRA & (1<<4)));
return ADC;
}


#pragma vector=TIM0_OVF_vect
__interrupt static void timer0_ovf_isr( void )//26087 hz
    {
    TCNT0 = 0xD2; //set count
    if(dev_pwm==700)//700
        {
            dev_pwm=0;
            TCCR0B = 0x00; //stop timer
            adc_data=read_adc();
            if(adc_data>=_adc_data) delta=adc_data - _adc_data;//âû÷èñëÿåì èçìåíåíèå çà âðåìÿ îò ïðåäèäóùåãî ïðåðûâàíèÿ îò òàéìåðà
            else delta=_adc_data - adc_data;
            _adc_data = adc_data;//çàïîìèíàåì òåêóùåå çíà÷åíèå ñèãíàëà îò ÈÊ äàò÷èêà
            if(delta>sensibility)
                {
                    detect=255;
                    status_flag=1;
                }
            else {detect=0;}
            TCCR0B = 0x02; //start timer
        }
    if((pwm>(brightness[count_pwm]))|(pwm==0)){sig_off;}
    else {sig_on;}
    ++dev_pwm;
    ++pwm;
    ++tick_count;
    }


void main(void)
{
ADMUX=0x43; //0b01000011;
ADCSRA=0x86; //0b10000110;
PORTB=0x10; //0b00010000;
DDRB=0x04; //0b00000100;
TCNT0 = 0xD2; //set count
TCCR0A = 0x00;
TCCR0B = 0x02; //start timer
TIMSK0 = 0x02; //timer interrupt sources
if(PINB & (1<<4)) //PB4==1?
    {//ðåçèñòîð îòïàÿí
    div_on_on=10;
    div_on_off=10;
    set_time=1;
    }
else
    {//ðåçèñòîð ïðèïàÿí
    div_on_on=200;
    div_on_off=200;
    set_time=60;    
    }
__enable_interrupt();

while(1)
    {
    if(status_flag==0)
    {
        tick_count=0;
    }
    if(status_flag==1)
        {
            for(;;)    
            {
            if(tick_count==div_on_on)
                {
                if(count_pwm==255)
                    {
                        count_pwm=255;
                        status_flag=2;
                        tick_count=0;
                        break;
                    }
                    tick_count=0;
                    ++count_pwm;
                }    
            }    
        }
    if(status_flag==2)
        {
            for(;;)
            {
            if(tick_count==26087)
                {
                if(my_time==set_time)
                    {
                        tick_count=0;
                        my_time=0;
                        status_flag=3;
                        break;
                    }
                    tick_count=0;
                    ++my_time;
                }
            if(detect==255)
                {
                    my_time=0;
                }    
            }
        }
    if(status_flag==3)    
        {
            for(;;)
            {
            if(tick_count==div_on_off)
                {
                if(count_pwm==0)
                    {
                        tick_count=0;
                        count_pwm=0;
                        status_flag=0;
                        break;
                    }
                tick_count=0;
                --count_pwm;
                }
            if(detect==255)
                {
                    status_flag=1;
                    break;
                }
            }
        }

    }
//return 0;
}


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 1st August 2025 - 19:49
Рейтинг@Mail.ru


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