Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Держит паяльник хвостом
Аватара пользователя
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

Сообщение Apparatchik »

Это как?

Если непонятно описание то скажу "попроще":
первый параметр - массив куда читать, ноходящийся в ОЗУ.
второй параметр - массив откуда читать, находящийся в еепром.
третий параметр - сколько байт читать.
Последний раз редактировалось Apparatchik Пт июл 04, 2014 13:13:54, всего редактировалось 1 раз.
«И всё-таки она вертится!»
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

пример использования можно?
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

Сообщение Apparatchik »

Код: Выделить всё

char mas[13];
EEMEM char mas_eeprom[13] = {...};

eeprom_read_block(mas, mas_eeprom, 13);
«И всё-таки она вертится!»
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

не работает у меня :cry:
Реклама
Эиком - электронные компоненты и радиодетали
Держит паяльник хвостом
Аватара пользователя
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

Сообщение Apparatchik »

У меня работает. Покажите полный код.
«И всё-таки она вертится!»
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

Код: Выделить всё

for (int8_t i=otr_spis;i<otr_spis_1;i++)
						{							
							unsigned char buffer1[40];	
							uint32_t t[13];
							eeprom_read_block(t,t_og_r,sizeof(t));
							utoa(t[i], buffer1, 10);
							LcdStr(FONT_1X,buffer1);
						}
а eeprom_read_word(&t_og_r) работает, хотя в тоже время eeprom_read_dword(&t_og_r) не работает(((
Реклама
Опытный кот
Сообщения: 884
Зарегистрирован: Пн июл 08, 2013 22:59:45

Сообщение kelod »

сделал с dword, но всё равно хочется понять как работает блок
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

насколько мне ведомо то в Си такого типа как bool нет
но в некоторых прогах я его видал
в чем фокус то ?
Tell Me The Truth
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

в С++ есть, в версии стандарта С99 добавили булевый тип, называется _Bool
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Тип в C по сути ненужный. Тем же char-ом можно заменить.

А что в прогах видел - возможно, там было что-то вроде #define bool char
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

WiseLord писал(а):А что в прогах видел - возможно, там было что-то вроде #define bool char
твердо утверждать не стану, на там вроде такого нет
под прогами я имел ввиду скрипты написанные на Си для WinCC
Tell Me The Truth
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Имеется массив указателей на функции:

Код: Выделить всё

const void(*mnu_func_ptr[11])() ={ // menu functions pointer
&menu_main, &menu_time, &menu_date, ... };
С помощью него организован автомат состояний программы т.к. на switch-case получается длинная и медленная обработка.
Вызов нужной функции происходит через косвенный переход:

Код: Выделить всё

(mnu_func_ptr[device_sm-DEV_STA_MNU_MAIN])(); // indirect call
Проблема: Т.к. указатель - это по сути переменная, то массив хранится в RAM. С другой стороны функции лежат во flash, их адреса постоянны и определяются линкером на этапе компиляции.
Таким образом было бы логичнее их адреса записать в константный массив примерно так:

Код: Выделить всё

__flash uint16_t func_adress[]={ &menu_main, &menu_date, ... } 
Но так компилятор ругается.

Как корректно объявлять и инициализировать массив адресов функций во flash чтобы не тратить драгоценную RAM ?
Компилятор CVAVR 2.05 и CVAVR 1.25.
Спасибо.
Опытный кот
Аватара пользователя
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США

Сообщение Pink-Pank »

ругается потому, что Вы объявляете массив целых чисел, а запихиваете туда указатели.
А в Code Vision, если не ошибаюсь, const = flash
Fucking static initialization order fiasco
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Это я понимаю, что имеется несоответствие типов данных, оттого и ругается.
Просто я не могу понять, как привести тип функции void к константному значению, понятному для flash uint16_t.

Как я рассуждаю:
(1)Функция func1() находится во флеш по физическому 16-битному адресу N.
(2)Этот адрес мы заносим(точнее заносит компилятор) в ячейку flash массива func_adress[].
(3)Далее в самой программе в переменную uint16_t adr читается адрес из массива adr = func_adress[x];
(4)Приводитя к типу указателя на функцию:
void (*p_func)(void);
p_func = (void(*)(void))adr;
(5)Переход:
p_func();

Как раз на этапе (2) у меня проблема.

ЗЫ. В codevision const=flash если включить соответсвующую опцию компилятора. А так кладет в RAM.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

для сложных типов данных я всегда применяю описание собственных типов, тогда получается гораздо проще описать именно то, что желаешь, и не запутаться

Код: Выделить всё

typedef void (*menu_finc_ptr)(void); // определили тип днных "указатель на функцию"

flash menu_func_ptr func_array[] = {func1, func2, func3, ...}; // определили массив во flash этих самых указателей
потом, кстати, и приведение типов легче делать - не многоэтажная запись, а одноэтажная :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Просто я не могу понять, как привести тип функции void к константному значению, понятному для flash uint16_t
А для чего все эти извращения-приведения ? Почему сразу не сделать массив указателей ?
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Указатель - есть по сути переменная. А переменная кладётся в RAM.
Когда 2-3 функции, то разницы по сути нет где хранить. Когда десятки функций и есть некоторый дефицит RAM, то начинаешь задумываться об оптимизации.
Модератор
Аватара пользователя
Сообщения: 4618
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

uk8amk писал(а):Указатель - есть по сути переменная.
Я имел ввиду тип массива - указатель на функцию (void (*ptr)(void)), а не целое (uint16_t). Для чего все эти лишние приведения типов :dont_know:
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Ха!
То, что описал ARV разместилось в Flash, как раз что надо, спасибо.

Только не могу понять, почему объявление
flash void(*mnu_func_ptr[11])(void) ={ // menu functions pointer
menu_main,
menu_time,
menu_date,
у меня вызывало ошибку Storage modifier not allowed in this context.
Вроде аналогичное объявление.
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

С предыдущим вопросом кое-как разобрался. Теперь возник следующий и тоже про указатели.
Значит есть в моей менюшке строки:

Код: Выделить всё

flash uint8_t str_time[]  ="ВРЕМЯ";
flash uint8_t str_date[]  ="ДАТА";
и т.д.
Если я создам массив указателей

Код: Выделить всё

flash uint8_t *mnu_main_str_ptr[]={ str_time, str_date, ...
То они(указатели) опять попадают в SRAM, строк много, памяти жалко.
Тогда я делаю такой массив:

Код: Выделить всё

flash uint16_t mnu_ptr[] = { // массив адресов строк меню во флеш
(uint16_t) &str_time, // вычисление адреса строки и приведение к 16-бит 
(uint16_t) &str_date,
... };
Использование:

Код: Выделить всё

copymem_load_fstr( (flash uint8_t*)mnu_ptr[mnu_item_index], str_buf_RAM ); //загрузить flash строку в RAM
Прототип функции копирования:

Код: Выделить всё

copymem_load_fstr( flash uint8_t *str, uint8_t *dest ); // *источник flash, *буфер RAM 
В принципе всё нормально работает, но выглядит как-то монстрообразно.
Можно ли привести это в нормальный, человеческий вид?
Ответить

Вернуться в «Разные вопросы по МК»