matlab_stm_emulate/MCU_Wrapper/mcu_wrapper.c

160 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**************************************************************************
Данный файл содержит функции для симуляции МК в Simulink (S-Function).
**************************************************************************/
#include "mcu_wrapper_conf.h"
SIM__MCUHandleTypeDef hmcu; // для управления контекстом программы МК
double SystemClockDouble = 0; // для симуляции системных тиков, прока просто по приколу
double SystemClock_step = 0; // для симуляции системных тиков, прока просто по приколу
uint64_t SystemClock; // для симуляции системных тиков, прока просто по приколу
//-------------------------------------------------------------//
//-----------------CONTROLLER SIMULATE FUNCTIONS---------------//
/**
* @brief Main function of MCU app.
* @details Функция с которой начинается выполнение кода МК. Выход из данной функции происходит только в конце симуляции @ref mdlTerminate
*/
extern int main(void); // extern while from main.c
/** THREAD FOR MCU APP */
/**
* @brief Thread that run MCU code.
* @details Поток, который запускает и выполняет код МК (@ref main).
*/
unsigned __stdcall MCU_App_Thread(void) {
main(); // run MCU code
return 0; // end thread
// note: this return will reached only at the end of simulation, when all whiles will be skipped due to @ref sim_while
}
/** SIMULATE MCU FOR ONE SIMULATION STEP */
/**
* @brief Read from simulink S-Block Inputs and write to MCU I/O ports.
* @param time - current time of simulation (in second).
* @details Запускает поток, который выполняет код МК и управляет ходом потока:
* Если прошел таймаут, поток прерывается, симулируется периферия
* и на следующем шаге поток возобнавляется.
*/
void MCU_Step_Simulation(SimStruct* S, time_T time)
{
MCU_readInputs(S); // считывание портов
MCU_Periph_Simulation(); // simulate peripheral
ResumeThread(hmcu.hMCUThread);
for (int i = DEKSTOP_CYCLES_FOR_MCU_APP; i > 0; i--)
{
}
SuspendThread(hmcu.hMCUThread);
MCU_writeOutputs(S); // запись портов (по факту запись в буфер. запись в порты в mdlOutputs)
}
/** SIMULATE MCU PERIPHERAL */
/**
* @brief Simulate peripheral of MCU
* @details Пользовательский код, который симулирует работу периферии МК.
*/
void MCU_Periph_Simulation(void)
{
SystemClockDouble += SystemClock_step; // emulate core clock
SystemClock = SystemClockDouble;
uwTick = SystemClock / (SystemCoreClock / 1000);
Simulate_TIMs();
}
/** READ INPUTS S-FUNCTION TO MCU REGS */
/**
* @brief Read from simulink S-Block Inputs and write to MCU I/O ports.
* @param in - inputs of S-Function.
* @details Пользовательский код, который записывает в порты ввода-вывода из disc.
*/
void MCU_readInputs(SimStruct* S)
{
/* Get S-Function inputs */
real_T* IN = ssGetInputPortRealSignal(S, 0);
SFUNC_to_GPIO(IN);
}
/** WRITE OUTPUTS BUFFER S-FUNCTION FROM MCU REGS*/
/**
* @brief Read from MCU I/O ports and write to simulink S-Block Outputs.
* @param disc - discrete array of S-Function. Outputs would be written from disc.
* @details Пользовательский код, который записывает в disc порты ввода-вывода.
*/
void MCU_writeOutputs(SimStruct* S)
{
/* Get S-Function descrete array */
real_T* DISC = ssGetDiscStates(S);
GPIO_to_SFUNC(DISC);
}
//-----------------CONTROLLER SIMULATE FUNCTIONS---------------//
//-------------------------------------------------------------//
//-------------------------------------------------------------//
//----------------------SIMULINK FUNCTIONS---------------------//
/** WRITE OUTPUTS OF S-BLOCK */
/**
* @brief Write S-Function Output ports to inputs.
* @param disc - discrete array of S-Function. Outputs would be written from disc.
* @details Пользовательский код, который записывает выходы S-Function.
*/
void SIM_writeOutputs(SimStruct* S)
{
real_T* GPIO;
real_T* DISC = ssGetDiscStates(S);
//-------------WRITTING GPIOS---------------
for (int j = 0; j < PORT_NUMB; j++)
{
GPIO = ssGetOutputPortRealSignal(S, j);
for (int i = 0; i < PORT_WIDTH; i++)
{
GPIO[i] = DISC[j * PORT_WIDTH + i];
DISC[j * PORT_WIDTH + i] = 0;
}
}
//------------------------------------------
}
/** MCU WRAPPER DEINITIALIZATION */
/**
* @brief Initialize structures and variables for simulating MCU.
* @details Пользовательский код, который будет настраивать все структуры для симуляции.
*/
void SIM_Initialize_Simulation(void)
{
/* user initialization */
Initialize_Periph_Sim();
/* wrapper initialization */
SystemClock_step = SystemCoreClock * hmcu.SIM_Sample_Time; // set system clock step
// инициализация потока, который будет выполнять код МК
hmcu.hMCUThread = (HANDLE)CreateThread(NULL, 0, MCU_App_Thread, 0, CREATE_SUSPENDED, &hmcu.idMCUThread);
}
/** MCU WRAPPER DEINITIALIZATION */
/**
* @brief Deinitialize structures and variables for simulating MCU.
* @details Пользовательский код, который будет очищать все структуры после окончания симуляции.
*/
void SIM_deInitialize_Simulation(void)
{
// simulate structures of peripheral deinitialization
deInitialize_Periph_Sim();
// mcu peripheral memory deinitialization
deInitialize_MCU();
}
//-------------------------------------------------------------//
////-----------INIT WRAPPER-----------
//if (hmcu.MCU_Start) // если надо получть указатель на "начало" стека
//{ // сброс флаша, чтобы сюда больше не попадать
// hmcu.MCU_Start = 0;
// // инициализация потока, который будет выполнять код МК
// hmcu.hMCUThread = (HANDLE)_beginthreadex(NULL, 0, MCU_App_Thread, 0, 0x00000004, &hmcu.idMCUThread); /* 0x00000004 - CREATE_SUSPENDED */
//}
////----------------------------------