Например TDA7294

Форум РадиоКот • Просмотр темы - Си. Передача массива констант в функцию, хранение и вызовы
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт апр 25, 2024 01:10:04

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 33 ]  1,  
Автор Сообщение
Не в сети
 Заголовок сообщения: Си. Передача массива констант в функцию, хранение и вызовы
СообщениеДобавлено: Вт май 30, 2017 20:37:15 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
Всем доброго вечера!
Запнулся на проблеме. Нид хэлп, как говорится )
Задача.
Есть ядро программы в виде отдельного модуля. Назвал его Kernel
К проекту подключаются другие сишные модули. Они автоматически регистрируются в ядре.
У каждого модуля есть такая запись:
Код:
#define  _NoPSR  0

static const uint16_t* PSR_Addresses[]
{
   //InitPSR
   _NoPSR,
   //TurnOnPSR
   _NoPSR,
   //TurnOffPSR
   _NoPSR,
   //ReportPRS
   (uint16_t*) &ExceptionsReport,
   //ProcessPRS
   (uint16_t*) &Exceptions,
   
   //Input 1 - Очистка таблицы исключений
   (uint16_t*) &RemoveExceptions
};

Вначале идут стандартные функции, потом неопределенное количество Input'ов, которые зависят от конкретного модуля. Если функция не описана - там стоит _NoPSR, т.е. 0. Обработчик в ядре вызов не выполнит.

Далее, при инициализации каждого модуля, последний заносит в общую таблицу ядра некую информацию о себе, в том числе он должен передать указатель на эту таблицу. Вроде такого:
Код:
#define Sub (uint16_t*) &

void Exceptions_KernelInit(void)
{
   Kernel_RegisterProcess(Sub InsExceptions, PSR_Addresses, _DT_Exception);
}

В ядре эта информация сохраняется в структуре:
Код:
struct
{
   enum _dtList EDType;
   uint16_t (*pFunc);
   uint16_t PSRtable;   //тут пока глюки
} knAddr[ProcessesCount];

void Kernel_RegisterProcess(uint16_t (*ProcessVector), const uint16_t *PSRtable, enum _dtList EDType)
{
   knAddr[++knProperties.CurrentID].EDType = EDType;
   knAddr[knProperties.CurrentID].pFunc = &(*ProcessVector);
   knAddr[knProperties.CurrentID].PSRtable = (uint16_t) &(*PSRtable);  //глюки-глюки. сюда пока особо не смотреть. игрался, ничего не выходит пока
}

//И дальше должен идти сам вызов удаленной функции:
char Kernel_CallPSR(char DeviceID, char _kp_position)
{
   if ((uint16_t) knAddr[DeviceID].PSRtable[_kp_position] == _NoPSR)
      return 0;
   else
      return ((char(*)(void))  ...что-то тут... (knAddr[DeviceID].PSRtable)[_kp_position]();
}

Т.е. механизм такой. Ядро знает где у какого модуля искать таблицу PSR_Addresses[], в которой лежат адреса ее функций. И по номеру нужной функции (_kp_position) произвести вызов.
По-русски хоть написал? ))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 20:42:41 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
ну а проблема-то в чем?

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 20:46:20 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
А вот не работает ) В генах, походу )) слабенький я еще в Си


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 20:49:52 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
что не работает-то? вы своего Гену там приструните, пусть толком говорит

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 20:51:25 
Модератор
Аватар пользователя

Карма: 90
Рейтинг сообщений: 1289
Зарегистрирован: Чт мар 18, 2010 23:09:57
Сообщений: 4510
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Когда "не работает", самое эффективное - подключать инструменты отладки. Только Вы, как автор кода, сможете найти проблему в нём.


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 20:55:39 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
Для начала я не могу передать в функцию указатель на массив констант неопределенной длины.
Где-то косяк. Или несколько.
Когда в последней строке
return ((char(*)(void)) ...что-то тут... (knAddr[DeviceID].PSRtable)[_kp_position]();
формируется адрес вызываемой функции, там всегда бред в итоге. Бросок в гущу кода.

Добавлено after 58 seconds:
Когда "не работает", самое эффективное - подключать инструменты отладки. Только Вы, как автор кода, сможете найти проблему в нём.


так-то оно так. только знаний пока маловато. и опыта. а спросить не у кого


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 21:01:56 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
рекомендую избавиться от явного приведения типов указателей - сразу делайте указатели нужного типа, иначе можно напортачить.
массивы "неопределенной длины" - это очень хороший способ выстрелить себе в ногу... источник всех проблем в ОС, напиманных на Си - зачем это вам?

и, если честно, я не очень понял, что вы затеяли... я подорбную систему "модулей" делал так:
1. определил структуру, описывающую интерфейс модуля
2. в каждом модуле структура эта помещена во flash и заполнена адресами соответствующих функций. если функция модулем не поддерживается, там пишу NULL
3. при "регистрации" модуля адрес этой структуры передаю "менеджеру" модулей, а он заносит этот адрес в массив.
4. когда надо обратиться к модулю, то по массиву беру нужную структуру, а из нее - адрес функции...
вот и все. у вас так или не так?

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 21:27:37 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
Так, только не определено количество этих функций. У каждого подключаемого модуля оно может быть разным. Ваша реализация это может поддержать?
Глобально идея выглядит так. Попробую вкратце.
Берется новая плата. На ней, к примеру, есть пять светодиодов, три кнопки и какой-то интерфейс связи (пусть будет уарт).
Текст программы main выглядит:
void main(void)
{
Kernel_AddDevice(_DT_Led);
Kernel_AddDevice(_DT_Led);
Kernel_AddDevice(_DT_Led);
Kernel_AddDevice(_DT_Led);
Kernel_AddDevice(_DT_Led);
Kernel_AddDevice(_DT_Button);
Kernel_AddDevice(_DT_Button);
Kernel_AddDevice(_DT_Button);
Kernel_AddDevice(_DT_UART);

while(1) Kernel;
}
Все само дальше крутится и отвечает на запросы по UART.
Когда приходит пакет по UART, модуль UART передает его ядру, которое ищет у себя нужный адресат и по коду команды вызывает нужную функцию у нужного модуля. Передавая остаток данных пакета тому самому обработчику.
Соответственно, у кнопок и светодиода разные задачи и разное количество команд управления (Input'ов у меня). В массив я не могу это засунуть, потому что структура неизвестна. Или я просто не знаю как это организовать правильно?

Добавлено after 12 minutes 35 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Можете дать пример кода, где описывается ваша структура во флэш?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 21:33:10 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 1
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Код для AVR-GCC не хуже версии 4

Это от незавершенного проекта "цифровой цветомузыки" :)


Вложения:
Комментарий к файлу: Здесь определены все необходимые для работы с модулем структуры и т.п.
main_effect.h [3.73 KiB]
Скачиваний: 305
Комментарий к файлу: Это "шаблон" модуля - все функции в виде пустышек.
template_effect.c [2.1 KiB]
Скачиваний: 609

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 21:41:24 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
спасибо! завтра поковыряюсь


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Вт май 30, 2017 21:50:23 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 1
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Что касается неизвестного количества функций у модуля, то могу предложить такой вариант
Код:
typedef int (*interface_func)(char *ptr); // определили тип для интерфейсной функции

// определяем тип для описания интерфейса модуля
typedef struct{
   uint8_t func_cnt; // количество функций в интерфейсе
   interface_func interface[]; // массив неопределенной длины
} module_interface_t;

// в менеджере модулей определяем массив, хранящий все модули
module_interface_t modules[MAX_MODULE_CNT];

// когда надо обратиться к конкретному модулю, надо делать так:
int run_module_func(uint8_t id, uint8_t func_id, char *data){
   if(id >= MAX_MODULE_CNT) return -1; // ошибка - модулей меньше, чем указано
   if(modules[id] == NULL) return -2; // ошибка - модуль с таким номером не зарегистрирован
   if(func_id >= modules[id].func_cnt) return -3; // ошибка - такая функция не может быть!
   if(modules[id].interface[func_id] == NULL) return -4; // ошибка - функция не реализована
   return modules[id].interface[func_id](data); // вызываем функцию и возвращаем ее результат работы
}


Добавлено after 6 minutes 57 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
да, чуть не забыл: инициализировать структуру интерфейса модуля можно так:
Код:
static module_interface_t module = {
   .func_cnt = 3,
   .interface[0] = func1,
   .interface[1] = func2,
   .interface[2] = func3
};

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Ср май 31, 2017 11:43:49 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
День добрый!
Получается так.
Код:
typedef int (*interface_func);   //(char *ptr); // определили тип для интерфейсной функции

// определяем тип для описания интерфейса модуля
typedef struct{
   uint8_t func_cnt; // количество функций в интерфейсе
   interface_func tfunc;
   interface_func interface[]; // массив неопределенной длины
} module_interface_t;


в модуле
Код:
static module_interface_t Addresses = {
   .func_cnt = 3,
   .interface[0] = ExceptionsReport,     //<< Error: expected primary-expression before '.' token
        .interface[1] = Exceptions,     //<< Error: expected primary-expression before '.' token
   .interface[2] = RemoveExceptions,     //<< Error: expected primary-expression before '.' token
   .tfunc = RemoveExceptions
};


т.е. там где идет присвоение массиву - не хочет компилировать


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Ср май 31, 2017 13:11:11 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 1
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
А почему у вас тип указателя на функцию без круглых скобок?

кроме того, обращаю ваше внимание, что приведенная мною форма инициализации поддерживается AVR-GCC c включенной поддержкой C99 и расширений GNU, другие компиляторы могу так сразу не прожевать...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 09:19:47 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
вот этот и не жует. я в AtmelStudio7 пишу. проект под C++. Облом, значиццо. Буду думать


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 09:53:25 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 1
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Должен жевать, добавьте опцию -std=gnu99

И всё-таки, почему указатель на функцию у вас без круглых скобок? вместо typedef int (*interface_func); должно быть typedef int (*interface_func)(void); или с нужными типами параметров...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 12:46:11 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
А. этот недочет я исправил сразу. спасибо.
а параметр -std=gnu99 не хочет спасать ситуацию

Добавлено after 2 hours 16 minutes 37 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Перенес процесс присвоения адресов в отдельную функцию и все заработало!
Спасибо за помощь!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 12:50:27 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
RealHann писал(а):
Перенес процесс присвоения адресов в отдельную функцию и все заработало!
это как?

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 18:16:43 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
Код:
#define Sub (uint16_t*) &

static module_interface_t DeviceInfo;

void Exceptions_KernelInit(void)
{
   DeviceInfo.interface[_kp_ProcessPSR] = Sub Exceptions;
   DeviceInfo.interface[_kp_ReportPSR] = Sub ExceptionsReport;
   DeviceInfo.interface[_kp_InputPSR + 0] = Sub RemoveExceptions;

   Kernel_RegisterProcess(Sub InsExceptions, &DeviceInfo, _DT_Exceptions);
}

ну, и сам вызов потом:
Код:
char Kernel_CallPSR(char DeviceID, char _kp_position)
{
   module_interface_t *DevInfo = knAddr[DeviceID].DeviceInfo;
   uint16_t* funcAddr = (uint16_t*) DevInfo->interface[_kp_position];

   if ((uint16_t) funcAddr == _NoPSR)
      return 0;
   else
      return ((char(*)(void)) funcAddr)();
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 18:35:17 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 97
Рейтинг сообщений: 2058
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18030
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
меня интересовало, как у вас структура объявлена и как вы под нее память выделяете, не зная количества функций в массиве...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Си. Передача массива констант в функцию, хранение и вызо
СообщениеДобавлено: Чт июн 01, 2017 18:49:22 
Открыл глаза

Зарегистрирован: Ср май 14, 2014 15:46:02
Сообщений: 55
Откуда: Харьков
Рейтинг сообщения: 0
в .hpp
Код:
typedef uint16_t (*interface_func);   // определили тип для интерфейсной функции

// определяем тип для описания интерфейса модуля
struct module_interface_t
{
   char func_cnt; // количество функций в интерфейсе
   interface_func interface[]; // массив неопределенной длины
};


Добавлено after 1 minute 13 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Ваши комментарии так и пойдут в мир )


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 33 ]  1,  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 68


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y