S-Functions Arrays of Size Defined Externally

1 view (last 30 days)
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 */
}

Answers (1)

Sathvik
Sathvik on 30 May 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 Comment
Dana Schwanke
Dana Schwanke on 8 Jun 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.

Sign in to comment.

Categories

Find more on Simulink Coder in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!