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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Организация программ, дайте вектор куда копать
syoma
сообщение Mar 31 2017, 13:22
Сообщение #16


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

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Zelepuk, а не хотите попробовать Matlab/Simulink/Embedded Coder под это дело? Ваша задача выглядит типовой для этого.
Т.е. всю обработку данных и свои алгоритмы нарисовать в Simulink в виде модели, которую вы сможете моделировать на PC вместе с входными данными, а затем всю модель выгрузить за несколько кликов в Си код, который будет исполняться в реальном времени на вашем контроллере. И все это без морок с глобальными флагами и переменными и часто даже без ОСРВ. Это достаточно "красивый" подход с заделом на будущее. Называется Model-Based Design.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 31 2017, 13:33
Сообщение #17


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Zelepuk @ Mar 31 2017, 15:54) *
Проще тогда наверное Keil с его ОС использовать. Хоть только за Keil платить придется...

Да, Keil - это благо. И ОС там легкая.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Mar 31 2017, 13:47
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(syoma @ Mar 31 2017, 16:22) *
Zelepuk, а не хотите попробовать Matlab/Simulink/Embedded Coder под это дело? Ваша задача выглядит типовой для этого.
Т.е. всю обработку данных и свои алгоритмы нарисовать в Simulink в виде модели, которую вы сможете моделировать на PC вместе с входными данными, а затем всю модель выгрузить за несколько кликов в Си код, который будет исполняться в реальном времени на вашем контроллере. И все это без морок с глобальными флагами и переменными и часто даже без ОСРВ. Это достаточно "красивый" подход с заделом на будущее. Называется Model-Based Design.

Почем-то мне думается что там не все так просто и красиво как описывается. посмотреть бы пример реализации такого подхода. Генерируемый код весьма труден для понимания. Увидеть бы готовый вариант простой процедуры: принять байт от SPI, накопить буфер, посчитать среднее раз в 100мс.
Go to the top of the page
 
+Quote Post
syoma
сообщение Mar 31 2017, 14:19
Сообщение #19


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

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата
Генерируемый код весьма труден для понимания.

Его не надо читать и понимать. Достаточно знать, что он делает то же самое, что и в симуляции.
Цитата
принять байт от SPI, накопить буфер, посчитать среднее раз в 100мс.

Вопрос - сколько байт надо накопить за 100мс? или как часто приходят новые данные?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 31 2017, 14:26
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Zelepuk @ Mar 31 2017, 15:47) *
Почем-то мне думается что там не все так просто и красиво как описывается. посмотреть бы пример реализации такого подхода. Генерируемый код весьма труден для понимания. Увидеть бы готовый вариант простой процедуры: принять байт от SPI, накопить буфер, посчитать среднее раз в 100мс.

Что там трудного?:
CODE
void MboxPost(OS_EVENT *mbox)
{
int e = OSMboxPost(mbox, (void *)1);
if (e != OS_ERR_NONE && e != OS_ERR_MBOX_FULL) trap(TRAP_OS, e);
}
void MboxPend(OS_EVENT *mbox)
{
u8 e;
OSMboxPend(mbox, 0, &e);
if (e != OS_ERR_NONE) trap(TRAP_OS, e);
}
isr() {
if (PERIPH.EMPTY) return;
t1 = sysTimer;
do { //Вычитываем все байты из FIFO периферии в программный FIFO.
uint i = PERIPH.READ;
if (!FIFO.isFull()) FIFO.write(i);
} while (!PERIPH.EMPTY);
if (FIFO.cnt() < N) if ((uint)(sysTimer - t1) < (uint)T) return; //Смотрим если в программном FIFO накопилось менее чем N байт (FIFO.cnt) и прошло менее чем T мсек с момента t1, то return;
иначе:
IsrEnter();
MboxPost(mbox); //посылаем сообщение сервисному процессу обработать накопленный программный FIFO.
IsrExit();
}
__noreturn void Task(void *) { //сервисный процесс, обслуживающий программный FIFO
t1 = sysTimer;
while (1) {
while (!FIFO.isEmpty()) {
FIFO.read();
...
}
MboxPend(mbox);
}
}

Всё. Это для uCOS. Для других ОС примерно так же.
Go to the top of the page
 
+Quote Post
Zelepuk
сообщение Mar 31 2017, 14:33
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464



Цитата(syoma @ Mar 31 2017, 17:19) *
Его не надо читать и понимать. Достаточно знать, что он делает то же самое, что и в симуляции.

Вопрос - сколько байт надо накопить за 100мс? или как часто приходят новые данные?

примерно 50кБ.

Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 31 2017, 15:13
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(AlexandrY @ Mar 31 2017, 13:28) *
Бесплатная то она бесплатная, но мне только через 2 месяца пришел ответ типа извините мы были перегружены запросами, хотим продолжить общение.
И на очередной запрос опять зависли.

Посмотрите сами, она бесплатна только для некоммерческого применения за все остальное надо платить. https://www.micrium.com/buy/licensing/
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Mar 31 2017, 15:26
Сообщение #23


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Mar 31 2017, 16:22) *
Т.е. всю обработку данных и свои алгоритмы нарисовать в Simulink в виде модели, которую вы сможете моделировать на PC вместе с входными данными, а затем всю модель выгрузить за несколько кликов в Си код, который будет исполняться в реальном времени на вашем контроллере.

Оч интересно, а каким таким образом Simulink вдруг гарантирует нам выполнение в реальном времени?
Или вы реальным временем обзываете все что только способно выполняться в микроконтроллере? biggrin.gif

Цитата(Lagman @ Mar 31 2017, 18:13) *
Посмотрите сами, она бесплатна только для некоммерческого применения за все остальное надо платить. https://www.micrium.com/buy/licensing/

Ну если вам так хочется делать бизнес и никому не платить, что поделаешь? Проходите мимо. laughing.gif
Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 31 2017, 16:16
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(AlexandrY @ Mar 31 2017, 18:26) *
Ну если вам так хочется делать бизнес и никому не платить, что поделаешь? Проходите мимо. laughing.gif

Вы сами то поняли на что ответили? Я ее как раз и не стал использовать, только потому, что она очень дорого выходит для штучных коммерческих изделий.
Go to the top of the page
 
+Quote Post
syoma
сообщение Mar 31 2017, 19:31
Сообщение #25


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

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата(Zelepuk @ Mar 31 2017, 16:33) *
примерно 50кБ.

Если считать, что принять байт от SPI, накопить буфер, - это делает Ваш драйвер SPI, а сама процедура посчитать среднее вызывается раз в 100мс, и ей передается массив из 50000 значений, то в Симулинке она будет выглядеть так:
Прикрепленное изображение

Рассчитано для исходного типа int8, результата суммы int32.
Тогда сгенерированный код будет выглядеть вот так:
ert_main.c - функция main
CODE
/*
/*
* File: ert_main.c
*
* Code generated for Simulink model 'Average'.
*
* Model version : 1.39
* Simulink Coder version : 8.11 (R2016b) 25-Aug-2016
* C/C++ source code generated on : Fri Mar 31 21:32:35 2017
*
* Target selection: ert.tlc
* Embedded hardware selection: 32-bit Generic
* Code generation objectives: Unspecified
* Validation result: Not run
*/

#include <stddef.h>
#include <stdio.h> /* This ert_main.c example uses printf/fflush */
#include "Average.h" /* Model's header file */
#include "rtwtypes.h"

static RT_MODEL_Average_T Average_M_;
static RT_MODEL_Average_T *const Average_M = &Average_M_;/* Real-time model */

/* '<Root>/In1' */
static int8_T Average_U_In1[50000];

/* '<Root>/Out1' */
static int8_T Average_Y_Out1;

/*
* Associating rt_OneStep with a real-time clock or interrupt service routine
* is what makes the generated code "real-time". The function rt_OneStep is
* always associated with the base rate of the model. Subrates are managed
* by the base rate from inside the generated code. Enabling/disabling
* interrupts and floating point context switches are target specific. This
* example code indicates where these should take place relative to executing
* the generated code step function. Overrun behavior should be tailored to
* your application needs. This example simply sets an error status in the
* real-time model and returns from rt_OneStep.
*/
void rt_OneStep(RT_MODEL_Average_T *const Average_M);
void rt_OneStep(RT_MODEL_Average_T *const Average_M)
{
static boolean_T OverrunFlag = false;

/* Disable interrupts here */

/* Check for overrun */
if (OverrunFlag) {
return;
}

OverrunFlag = true;

/* Save FPU context here (if necessary) */
/* Re-enable timer or interrupt here */
/* Set model inputs here */

/* Step the model */
Average_step(Average_M, Average_U_In1, &Average_Y_Out1);

/* Get model outputs here */

/* Indicate task complete */
OverrunFlag = false;

/* Disable interrupts here */
/* Restore FPU context here (if necessary) */
/* Enable interrupts here */
}

/*
* The example "main" function illustrates what is required by your
* application code to initialize, execute, and terminate the generated code.
* Attaching rt_OneStep to a real-time clock is target specific. This example
* illustrates how you do this relative to initializing the model.
*/
int_T main(int_T argc, const char *argv[])
{
/* Unused arguments */
(void)(argc);
(void)(argv);

/* Pack model data into RTM */

/* Initialize model */
Average_initialize(Average_M, Average_U_In1, &Average_Y_Out1);

/* Attach rt_OneStep to a timer or interrupt service routine with
* period 0.1 seconds (the model's base sample time) here. The
* call syntax for rt_OneStep is
*
* rt_OneStep(Average_M);
*/
printf("Warning: The simulation will run forever. "
"Generated ERT main won't simulate model step behavior. "
"To change this behavior select the 'MAT-file logging' option.\n");
fflush((NULL));
while (((void*) 0) == (NULL)) {
/* Perform other application tasks here */
}

/* The option 'Remove error status field in real-time model data structure'
* is selected, therefore the following code does not need to execute.
*/
#if 0

/* Disable rt_OneStep() here */

/* Terminate model */
Average_terminate(Average_M);

#endif

return 0;
}

/*
* File trailer for generated code.
*
* [EOF]
*/



Функция average - собственно сам расчет среднего
CODE
/*
* File: Average.c
*
* Code generated for Simulink model 'Average'.
*
* Model version : 1.39
* Simulink Coder version : 8.11 (R2016b) 25-Aug-2016
* C/C++ source code generated on : Fri Mar 31 21:22:13 2017
*
* Target selection: ert.tlc
* Embedded hardware selection: 32-bit Generic
* Code generation objectives: Unspecified
* Validation result: Not run
*/

#include "Average.h"
#include "Average_private.h"

void mul_wide_s32(int32_T in0, int32_T in1, uint32_T *ptrOutBitsHi, uint32_T
*ptrOutBitsLo)
{
uint32_T absIn0;
uint32_T absIn1;
uint32_T in0Lo;
uint32_T in0Hi;
uint32_T in1Hi;
uint32_T productHiLo;
uint32_T productLoHi;
absIn0 = in0 < 0 ? ~(uint32_T)in0 + 1U : (uint32_T)in0;
absIn1 = in1 < 0 ? ~(uint32_T)in1 + 1U : (uint32_T)in1;
in0Hi = absIn0 >> 16U;
in0Lo = absIn0 & 65535U;
in1Hi = absIn1 >> 16U;
absIn0 = absIn1 & 65535U;
productHiLo = in0Hi * absIn0;
productLoHi = in0Lo * in1Hi;
absIn0 *= in0Lo;
absIn1 = 0U;
in0Lo = (productLoHi << /*MW:OvBitwiseOk*/ 16U) + /*MW:OvCarryOk*/ absIn0;
if (in0Lo < absIn0) {
absIn1 = 1U;
}

absIn0 = in0Lo;
in0Lo += /*MW:OvCarryOk*/ productHiLo << /*MW:OvBitwiseOk*/ 16U;
if (in0Lo < absIn0) {
absIn1++;
}

absIn0 = (((productLoHi >> 16U) + (productHiLo >> 16U)) + in0Hi * in1Hi) +
absIn1;
if (!((in0 == 0) || ((in1 == 0) || ((in0 > 0) == (in1 > 0))))) {
absIn0 = ~absIn0;
in0Lo = ~in0Lo;
in0Lo++;
if (in0Lo == 0U) {
absIn0++;
}
}

*ptrOutBitsHi = absIn0;
*ptrOutBitsLo = in0Lo;
}

int32_T mul_s32_hiSR(int32_T a, int32_T b, uint32_T aShift)
{
uint32_T u32_chi;
uint32_T u32_clo;
mul_wide_s32(a, b, &u32_chi, &u32_clo);
return (int32_T)u32_chi >> aShift;
}

/* Model step function */
void Average_step(RT_MODEL_Average_T *const Average_M, int8_T Average_U_In1
[50000], int8_T *Average_Y_Out1)
{
int32_T i;
int32_T rtb_SumofElements;

/* Sum: '<S1>/Sum of Elements' incorporates:
* Inport: '<Root>/In1'
*/
rtb_SumofElements = Average_U_In1[0];
for (i = 0; i < 49999; i++) {
rtb_SumofElements += Average_U_In1[i + 1];
}

/* End of Sum: '<S1>/Sum of Elements' */

/* Outport: '<Root>/Out1' incorporates:
* Gain: '<S1>/Gain'
*/
*Average_Y_Out1 = (int8_T)mul_s32_hiSR(351843721, rtb_SumofElements, 12U);
UNUSED_PARAMETER(Average_M);
}

/* Model initialize function */
void Average_initialize(RT_MODEL_Average_T *const Average_M, int8_T
Average_U_In1[50000], int8_T *Average_Y_Out1)
{
/* Registration code */

/* external inputs */
(void)memset(&Average_U_In1[0], 0, 50000U * sizeof(int8_T));

/* external outputs */
(*Average_Y_Out1) = 0;
UNUSED_PARAMETER(Average_M);
}

/* Model terminate function */
void Average_terminate(RT_MODEL_Average_T *const Average_M)
{
/* (no terminate code required) */
UNUSED_PARAMETER(Average_M);
}

/*
* File trailer for generated code.
*
* [EOF]
*/


По коду можно сказать, что матлаб сгенерировал хитрый умножитель на 1/50000. Почему - это зависит от того, что поддерживает, а что нет конкретная платформа

Цитата
Оч интересно, а каким таким образом Simulink вдруг гарантирует нам выполнение в реальном времени?

Посмотрите первый комментарий в первом из сгенерированных файлов.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Mar 31 2017, 20:19
Сообщение #26


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Mar 31 2017, 22:31) *
Посмотрите первый комментарий в первом из сгенерированных файлов.

Цитата
Associating rt_OneStep with a real-time clock or interrupt service routine is what makes the generated code "real-time".

Они над вами смеются. Заметили скобочки?
Прочитайте весь комментарий.
Они оставляют за собой право сделать "Overrun" и посылают вас самих это расхлебывать.
Причем флаг "Overrun" оставили статическим внутри функции. Феерично!
Так что не надо нам этих фэйков. biggrin.gif
Цитата(Lagman @ Mar 31 2017, 19:16) *
Я ее как раз и не стал использовать, только потому, что она очень дорого выходит для штучных коммерческих изделий.

Не знаю, я делаю штучные и коммерческие, я мэйкер. Мне бесплатно.
Go to the top of the page
 
+Quote Post
syoma
сообщение Mar 31 2017, 20:26
Сообщение #27


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

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата(AlexandrY @ Mar 31 2017, 22:17) *
Они оставляют за собой право сделать "Overrun" и посылают вас самих это расхлебывать.

А как вы предлагаете расхлебывать ситуацию в реальном времени, если разработанная вами функция не выполнится за заданное время?

Цитата
Причем флаг "Overrun" оставили статическим внутри функции. Феерично!

А в чем проблема?
rt_OneStep в примере предлагается вызывать в прерывании от таймера.
Во время исполнения модельного кода флаг Overrun ставится в true, а после завершения сбрасывается. Если следующее прерывание от таймера произойдет до окончания исполнения модельного кода, факт overrun ловится и делай, сам, что считаешь нужным.
Вообще-то ert_main.c - это всего лишь пример, как можно запустить функцию на исполнение в реальном времени без ОСРВ. Его можно без проблем изменять по своему усмотрению.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Mar 31 2017, 20:37
Сообщение #28


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(syoma @ Mar 31 2017, 23:26) *
А как вы предлагаете расхлебывать ситуацию в реальном времени, если разработанная вами функция не выполнится за заданное время?

Никак, в Simulink вы её не расхлебаете и даже не узнаете о ней.
Симулинк будет тупо раз за разом перезаписывать свои заглушки поверх ваших правок.
Его код предназначен для устойчивой среды исполнения на базе RTOS уже сделанной в микроконтроллере.

Вы же так и делаете. Используете vxWorks, а тут подсовываете надуманную лабуду.
Go to the top of the page
 
+Quote Post
syoma
сообщение Mar 31 2017, 20:53
Сообщение #29


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

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата(AlexandrY @ Mar 31 2017, 22:37) *
Симулинк будет тупо раз за разом перезаписывать свои заглушки поверх ваших правок.

Не понимаю я вас. Где и что Симулинк будет перезаписывать?
Go to the top of the page
 
+Quote Post
Lagman
сообщение Mar 31 2017, 22:48
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(AlexandrY @ Mar 31 2017, 23:19) *
Не знаю, я делаю штучные и коммерческие, я мэйкер. Мне бесплатно.

Это ваше оправдание, можете жить спокойно, только не заглядывайте на страничку о покупке microc os и не читайте про лицензии.
Go to the top of the page
 
+Quote Post

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

 


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


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