|
Организация программ, дайте вектор куда копать |
|
|
|
Mar 31 2017, 07:52
|
Знающий
   
Группа: Участник
Сообщений: 634
Регистрация: 27-10-10
Пользователь №: 60 464

|
Планируется разработка измерительного прибора, принимающего данные от АЦП в прерывании, складывающего данные в буфер и обрабатывающего данные пос ложному алгоритму. Дело в том что нужно часто давать сигналы готовности данных на разных ступенях алгоритма. Использовать флаги - глобальные переменные неудобно (их будет слишком много). Сообщить, какие "более красивые подходы" для этого используются. например на микрокотнтроллере можно использовать ОСРВ и ее средства взаимодействия между задачами, а как быть когда нужно сделать демо-проект на PC (для последующего переноса на МК)?
Например есть такая задача: 1)АЦП складывает данные непрерывно в кольцевой буфер 2) Раз в миллисекунду данные из буфера обрабатываются результат сохраняется в переменную. 3) после 10й итерации по пункту 2 (т.е. раз в 10 миллисекунд) нужно делать усреднение данных
У меня сейчас в функции, которая реализует п.2 просто есть счетчик итераций в виде переменной. Я опрашиваю эту переменную, и, как только она равна 10 - запускаю функию, реализующую п.3 Все это выглядит ужасно в бесконечном цикле.
Подскажите, как сделать грамотно.
Сообщение отредактировал Zelepuk - Mar 31 2017, 08:00
|
|
|
|
|
 |
Ответов
|
Mar 31 2017, 14:19
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Цитата Генерируемый код весьма труден для понимания. Его не надо читать и понимать. Достаточно знать, что он делает то же самое, что и в симуляции. Цитата принять байт от SPI, накопить буфер, посчитать среднее раз в 100мс. Вопрос - сколько байт надо накопить за 100мс? или как часто приходят новые данные?
|
|
|
|
|
Mar 31 2017, 19:31
|
Профессионал
    
Группа: Свой
Сообщений: 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 вдруг гарантирует нам выполнение в реальном времени? Посмотрите первый комментарий в первом из сгенерированных файлов.
|
|
|
|
|
Mar 31 2017, 20:19
|

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" оставили статическим внутри функции. Феерично! Так что не надо нам этих фэйков. Цитата(Lagman @ Mar 31 2017, 19:16)  Я ее как раз и не стал использовать, только потому, что она очень дорого выходит для штучных коммерческих изделий. Не знаю, я делаю штучные и коммерческие, я мэйкер. Мне бесплатно.
|
|
|
|
|
Mar 31 2017, 20:26
|
Профессионал
    
Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368

|
Цитата(AlexandrY @ Mar 31 2017, 22:17)  Они оставляют за собой право сделать "Overrun" и посылают вас самих это расхлебывать. А как вы предлагаете расхлебывать ситуацию в реальном времени, если разработанная вами функция не выполнится за заданное время? Цитата Причем флаг "Overrun" оставили статическим внутри функции. Феерично! А в чем проблема? rt_OneStep в примере предлагается вызывать в прерывании от таймера. Во время исполнения модельного кода флаг Overrun ставится в true, а после завершения сбрасывается. Если следующее прерывание от таймера произойдет до окончания исполнения модельного кода, факт overrun ловится и делай, сам, что считаешь нужным. Вообще-то ert_main.c - это всего лишь пример, как можно запустить функцию на исполнение в реальном времени без ОСРВ. Его можно без проблем изменять по своему усмотрению.
|
|
|
|
|
Mar 31 2017, 20:37
|

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

|
Цитата(syoma @ Mar 31 2017, 23:26)  А как вы предлагаете расхлебывать ситуацию в реальном времени, если разработанная вами функция не выполнится за заданное время? Никак, в Simulink вы её не расхлебаете и даже не узнаете о ней. Симулинк будет тупо раз за разом перезаписывать свои заглушки поверх ваших правок. Его код предназначен для устойчивой среды исполнения на базе RTOS уже сделанной в микроконтроллере. Вы же так и делаете. Используете vxWorks, а тут подсовываете надуманную лабуду.
|
|
|
|
Сообщений в этой теме
Zelepuk Организация программ Mar 31 2017, 07:52 ViKo Я понял так, программа делает то, что от нее требу... Mar 31 2017, 08:19 Zelepuk Цитата(ViKo @ Mar 31 2017, 11:19) Я понял... Mar 31 2017, 08:24  AlexandrY Цитата(Zelepuk @ Mar 31 2017, 11:24) Эт п... Mar 31 2017, 09:09   jcxz Цитата(AlexandrY @ Mar 31 2017, 11:09) Fr... Mar 31 2017, 09:23    Lagman Цитата(AlexandrY @ Mar 31 2017, 12:09) Я ... Mar 31 2017, 09:42     AlexandrY Цитата(Lagman @ Mar 31 2017, 12:42) Эх, б... Mar 31 2017, 10:28      Lagman Цитата(AlexandrY @ Mar 31 2017, 13:28) Бе... Mar 31 2017, 15:13    AlexandrY Цитата(jcxz @ Mar 31 2017, 12:23) Перенес... Mar 31 2017, 10:20     jcxz Цитата(AlexandrY @ Mar 31 2017, 12:20) Вс... Mar 31 2017, 10:24     Zelepuk Цитата(jcxz @ Mar 31 2017, 11:52) В ISR, ... Mar 31 2017, 12:12      AlexandrY Цитата(Zelepuk @ Mar 31 2017, 15:12) как ... Mar 31 2017, 12:18      jcxz Цитата(Zelepuk @ Mar 31 2017, 14:12) Вот ... Mar 31 2017, 13:20 jcxz Цитата(Zelepuk @ Mar 31 2017, 09:52) У ме... Mar 31 2017, 08:52 XVR 2 ТС - какой у вас целевой процессор и ресурсы? Ес... Mar 31 2017, 09:55 Zelepuk Micrium платный. да еще за IAR платить надо.
Прощ... Mar 31 2017, 12:54 ViKo Цитата(Zelepuk @ Mar 31 2017, 15:54) Прощ... Mar 31 2017, 13:33 syoma Zelepuk, а не хотите попробовать Matlab/Simulink/E... Mar 31 2017, 13:22 Zelepuk Цитата(syoma @ Mar 31 2017, 16:22) Zelepu... Mar 31 2017, 13:47  jcxz Цитата(Zelepuk @ Mar 31 2017, 15:47) Поче... Mar 31 2017, 14:26 AlexandrY Цитата(syoma @ Mar 31 2017, 16:22) Т.е. в... Mar 31 2017, 15:26  Lagman Цитата(AlexandrY @ Mar 31 2017, 18:26) Ну... Mar 31 2017, 16:16      syoma Цитата(AlexandrY @ Mar 31 2017, 22:37) Си... Mar 31 2017, 20:53    Lagman Цитата(AlexandrY @ Mar 31 2017, 23:19) Не... Mar 31 2017, 22:48 TigerSHARC Интересно сравнить, где "красивше" будет... Apr 3 2017, 18:11 Lagman Цитата(TigerSHARC @ Apr 3 2017, 21:11) Ин... Apr 3 2017, 19:49  Zelepuk Цитата(Lagman @ Apr 3 2017, 22:49) Как вы... Apr 4 2017, 06:20   Baser Цитата(Zelepuk @ Apr 4 2017, 09:20) Зачем... Apr 4 2017, 09:26   Lagman Добавлю к словам Baser'a
Цитата(Zelepuk ... Apr 4 2017, 11:00    TigerSHARC Цитата(Lagman @ Apr 4 2017, 14:00) Добавл... Apr 4 2017, 19:00     AlexandrY Цитата(TigerSHARC @ Apr 4 2017, 22:00) Мг... Apr 4 2017, 19:28     Lagman Цитата(TigerSHARC @ Apr 4 2017, 22:00) Мг... Apr 4 2017, 19:41      Make_Pic Решил не создавать новую тему, а здесь спросить:
... Apr 5 2017, 10:58       jcxz Цитата(Make_Pic @ Apr 5 2017, 12:58) Нико... Apr 5 2017, 20:02        Make_Pic Цитата(jcxz @ Apr 6 2017, 00:02) Сохранен... Apr 6 2017, 04:44   HardEgor Цитата(Zelepuk @ Apr 4 2017, 13:20) Зачем... Apr 4 2017, 11:16 bve Из Вашего обработчика вызовите свободное прерывани... Apr 6 2017, 18:22 Make_Pic Цитата(bve @ Apr 6 2017, 21:22) Из Вашего... Apr 7 2017, 07:41 k155la3 Цитата(Zelepuk @ Mar 31 2017, 10:52) План... Apr 7 2017, 06:58 MrYuran Цитата(Zelepuk @ Mar 31 2017, 10:52) Все ... Apr 8 2017, 05:06 TigerSHARC Цитата(MrYuran @ Apr 8 2017, 08:06) Не зн... Apr 8 2017, 08:16  MrYuran Цитата(TigerSHARC @ Apr 8 2017, 11:16) На... Apr 8 2017, 09:18   TigerSHARC Цитата(MrYuran @ Apr 8 2017, 12:18) Скоре... Apr 8 2017, 15:17   jcxz Цитата(MrYuran @ Apr 8 2017, 11:18) Скоре... Apr 8 2017, 19:02 syoma ЦитатаОчевидно, что вы пишете только простые прогр... Apr 8 2017, 19:51 k155la3 Цитата(syoma @ Apr 8 2017, 22:51) . . . .... Apr 9 2017, 08:30 jcxz Цитата(syoma @ Apr 8 2017, 21:51) Все про... Apr 9 2017, 08:59  k155la3 Цитата(jcxz @ Apr 9 2017, 11:59) . . .
Э... Apr 9 2017, 09:52   jcxz Цитата(k155la3 @ Apr 9 2017, 11:52) В мое... Apr 9 2017, 15:26    k155la3 Цитата(jcxz @ Apr 9 2017, 18:26) Не обяза... Apr 11 2017, 07:34 aiwa Цитата(TigerSHARC @ Apr 8 2017, 18:17) Зд... Apr 9 2017, 10:40 pokk Добрый день, для своих программ использовал Switch... May 22 2017, 01:14 k155la3 Цитата(pokk @ May 22 2017, 04:14) . . .
... May 22 2017, 06:24
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|