Цитата(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 вдруг гарантирует нам выполнение в реальном времени?
Посмотрите первый комментарий в первом из сгенерированных файлов.