Azzera filtri
Azzera filtri

S-Functions Arrays of Size Defined Externally

1 visualizzazione (ultimi 30 giorni)
Dana Schwanke
Dana Schwanke il 18 Mag 2023
Commentato: Dana Schwanke il 8 Giu 2023
I am using S-Functions to access C code which includes access to several arrays of fixed size. This size is defined in a C header file using a #define. I would like to use this value when creating my S-functions so that the S-Functions take arrays of the exact same length. Then, if I ever change the size of the arrays, I don't have to do anything but rebuild the files. For example, here is the header file I am working with, with the definition DMA_BUFFER_SIZE which should always be available to both the Simulink project and the C code.
stm32_usart.h:
/* We may be able to use the definition in S-Functions if we make it so
* that it is defined even if MATLAB_MEX_FILE is, too. */
#ifndef DMA_BUFFER_SIZE
#define DMA_BUFFER_SIZE 32U
#endif
#ifndef MATLAB_MEX_FILE
#ifndef __STM32_USART_H_
#define __STM32_USART_H_
#include "main.h" /* Contains all of the STM32 handles */
#include "stm32_targets_cfg.h" /* contains the target setup definitions like USING_USARTX */
#if defined (USING_USART1)
extern uint8_t rx_UART1_DMA_Buffer[DMA_BUFFER_SIZE];
#endif
#if defined (USING_USART2)
extern uint8_t rx_UART2_DMA_Buffer[DMA_BUFFER_SIZE];
#endif
#if defined (USING_USART3)
extern uint8_t rx_UART3_DMA_Buffer[DMA_BUFFER_SIZE];
#endif
#if defined (USING_USART4)
extern uint8_t rx_UART4_DMA_Buffer[DMA_BUFFER_SIZE];
#endif
#if defined (USING_USART5)
extern uint8_t rx_UART5_DMA_Buffer[DMA_BUFFER_SIZE];
#endif
#endif
#endif
The matching C file which defines the variables and the wrapper code I actually want to implement are both included below, but the part I need to figure out how to modify is what gets put in the S-Function file itself. That DMA_BUFFER_SIZE needs to be available for the S-Function to define the fixed size of the array:
/*
* File: USART_DMA_Receive_Poll.c
.......
#define NUM_OUTPUTS 2
/* Output Port 0 */
#define OUT_PORT_0_NAME rx_Data
#define OUTPUT_0_WIDTH [THIS SHOULD BE DMA_BUFFER_SIZE]
#define OUTPUT_DIMS_0_COL 1
.......
Is there a way to accomplish this?
stm32_usart.c:
#include "stm32_usart.h"
#if defined (USING_USART1)
uint8_t rx_UART1_DMA_Buffer[DMA_BUFFER_SIZE] = { 0U };
#endif
#if defined (USING_USART2)
uint8_t rx_UART2_DMA_Buffer[DMA_BUFFER_SIZE] = { 0U };
#endif
#if defined (USING_USART3)
uint8_t rx_UART3_DMA_Buffer[DMA_BUFFER_SIZE] = { 0U };
#endif
#if defined (USING_USART4)
uint8_t rx_UART4_DMA_Buffer[DMA_BUFFER_SIZE] = { 0U };
#endif
#if defined (USING_USART5)
uint8_t rx_UART5_DMA_Buffer[DMA_BUFFER_SIZE] = { 0U };
#endif
USART_DMA_Receive_Poll_wrapper.c:
/*
* Include Files
*
*/
#if defined(MATLAB_MEX_FILE)
#include "tmwtypes.h"
#include "simstruc_types.h"
#else
#include "rtwtypes.h"
#endif
/* %%%-SFUNWIZ_wrapper_includes_Changes_BEGIN --- EDIT HERE TO _END */
#ifndef MATLAB_MEX_FILE
#include "stm32_usart.h"
#endif
/* %%%-SFUNWIZ_wrapper_includes_Changes_END --- EDIT HERE TO _BEGIN */
#define y_width 1
/*
* Create external references here.
*
*/
/* %%%-SFUNWIZ_wrapper_externs_Changes_BEGIN --- EDIT HERE TO _END */
/* %%%-SFUNWIZ_wrapper_externs_Changes_END --- EDIT HERE TO _BEGIN */
/*
* Start function
*
*/
void USART_DMA_Receive_Poll_Start_wrapper(const uint8_T *UartPort, const int_T p_width0)
{
/* %%%-SFUNWIZ_wrapper_Start_Changes_BEGIN --- EDIT HERE TO _END */
#ifndef MATLAB_MEX_FILE
#if defined (USING_USART1)
HAL_UART_Receive_DMA(&huart1, rx_UART1_DMA_Buffer, DMA_BUFFER_SIZE);
#endif
#if defined (USING_USART2)
HAL_UART_Receive_DMA(&huart2, rx_UART2_DMA_Buffer, DMA_BUFFER_SIZE);
#endif
#if defined (USING_USART3)
HAL_UART_Receive_DMA(&huart3, rx_UART3_DMA_Buffer, DMA_BUFFER_SIZE);
#endif
#if defined (USING_USART4)
HAL_UART_Receive_DMA(&huart4, rx_UART4_DMA_Buffer, DMA_BUFFER_SIZE);
#endif
#if defined (USING_USART5)
HAL_UART_Receive_DMA(&huart5, rx_UART5_DMA_Buffer, DMA_BUFFER_SIZE);
#endif
#endif
/* %%%-SFUNWIZ_wrapper_Start_Changes_END --- EDIT HERE TO _BEGIN */
}
/*
* Output function
*
*/
void USART_DMA_Receive_Poll_Outputs_wrapper(uint8_T *rx_Data,
uint8_T *rx_length,
const uint8_T *UartPort, const int_T p_width0)
{
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_BEGIN --- EDIT HERE TO _END */
/* Default rx_length to 0 */
*rx_length = 0U;
#ifndef MATLAB_MEX_FILE
#define START_CODE 0xAAU
#define MAX_RETRIES 2U
UART_HandleTypeDef *huart = NULL;
DMA_HandleTypeDef *hdma_usart_rx = NULL;
uint8_t *rx_DMA_Buffer = NULL;
switch(*UartPort)
{
#if defined (USING_USART1)
case 1:
huart = &huart1;
hdma_usart_rx = &hdma_usart1_rx;
rx_DMA_Buffer = rx_UART1_DMA_Buffer;
break;
#endif
#if defined (USING_USART2)
case 2:
huart = &huart2;
hdma_usart_rx = &hdma_usart2_rx;
rx_DMA_Buffer = rx_UART2_DMA_Buffer;
break;
#endif
#if defined (USING_USART3)
case 3:
huart = &huart3;
hdma_usart_rx = &hdma_uart3_rx;
rx_DMA_Buffer = rx_UART3_DMA_Buffer;
break;
#endif
#if defined (USING_USART4)
case 4:
huart = &huart4;
hdma_usart_rx = &hdma_uart4_rx;
rx_DMA_Buffer = rx_UART4_DMA_Buffer;
break;
#endif
#if defined (USING_USART5)
case 5:
huart = &huart5;
hdma_usart_rx = &hdma_uart5_rx;
rx_DMA_Buffer = rx_UART5_DMA_Buffer;
break;
#endif
default:
return;
}
/* Check for valid UART channel and then see if any data has come in */
if( (huart != NULL ) &&
(hdma_usart_rx != NULL ) &&
(rx_DMA_Buffer != NULL ) &&
(*(hdma_usart_rx->Instance->CNDTR) != DMA_BUFFER_SIZE ) )
{
*rx_length = DMA_BUFFER_SIZE - *(hdma_usart_rx->Instance->CNDTR);
/* Copy data to the output */
for(uint8_t j = 0; j < *rx_length; j++)
{
rx_Data[j] = rx_DMA_Buffer[j];
}
}
#endif
/* %%%-SFUNWIZ_wrapper_Outputs_Changes_END --- EDIT HERE TO _BEGIN */
}

Risposte (1)

Sathvik
Sathvik il 30 Mag 2023
To use the value of ‘DMA_BUFFFER_SIZE’ defined in the header file in your S- Function, it can be defined in a separate header file and in every implementation that the constant is needed, you can just include the header file and use the constant in your code. For example:
1. Create a separate header file, say “dma_buffer_size.h”, and define the DMA_BUFFER_SIZE constant in it.
#ifndef DMA_BUFFER_SIZE_H
#define DMA_BUFFER_SIZE_H
#define DMA_BUFFER_SIZE 32U
#endif
2. In your S-function implementation file, include the `dma_buffer_size.h` header file
3. Use the `DMA_BUFFER_SIZE` constant in your S-function code. For example, in your `USART_DMA_Receive_Poll.c` file, you can define
#define OUT_PORT_0_NAME rx_Data
#define OUTPUT_0_WIDTH DMA_BUFFER_SIZE
Hope this helps
  1 Commento
Dana Schwanke
Dana Schwanke il 8 Giu 2023
This helps on the C-code side of things, but there a way for the the Simulink code which will implement the S-Function block to also know the size of DMA_BUFFER_SIZE? When we are passing vectors to S-Functions that need to be of a specific size, the Simulink value's "Port Dimensions" should be the same "DMA_BUFFER_SIZE", otherwise we are still hard-coding the size somewhere.

Accedi per commentare.

Categorie

Scopri di più su Simulink Coder in Help Center e File Exchange

Prodotti


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by