195 lines
6.5 KiB
C
195 lines
6.5 KiB
C
/**************************************************************************
|
|
Äàííûé ôàéë ñîäåðæèò ôóíêöèè äëÿ ñèìóëÿöèè ÌÊ â Simulink (S-Function).
|
|
|
|
**************************************************************************/
|
|
#include "simstruc.h"
|
|
#include "mcu_wrapper_conf.h"
|
|
//#include <windows.h>
|
|
//#include <synchapi.h>
|
|
|
|
DEL_MCUHandleTypeDef hmcu; // äëÿ óïðàâëåíèÿ êîíòåêñòîì ïðîãðàììû ÌÊ
|
|
HANDLE hThread;
|
|
uint32_t idThreads;
|
|
unsigned flag_to_end;
|
|
|
|
double SystemClockDouble = 0; // äëÿ ñèìóëÿöèè ñèñòåìíûõ òèêîâ, ïðîêà ïðîñòî ïî ïðèêîëó
|
|
uint64_t SystemClock; // äëÿ ñèìóëÿöèè ñèñòåìíûõ òèêîâ, ïðîêà ïðîñòî ïî ïðèêîëó
|
|
|
|
/* Extern function of control MCU App from asmjmp.asm */
|
|
extern void GET_RSP_ORIGIN(DEL_MCUHandleTypeDef* hmcu);
|
|
extern void RESTORE_CONTEXT_AND_JUMP(DEL_MCUHandleTypeDef* hmcu);
|
|
extern void READ_REGS(_JUMP_BUFFER* hmcu);
|
|
|
|
//-------------------------------------------------------------//
|
|
//-----------------CONTROLLER SIMULATE FUNCTIONS---------------//
|
|
/** MCU STEP SIMULATION */
|
|
/**
|
|
* @brief Read from simulink S-Block Inputs and write to MCU I/O ports.
|
|
* @param in - inputs of S-Function.
|
|
* @param disc - discrete array of S-Function. Outputs would be written from disc.
|
|
* @param time - current time of simulation (in second).
|
|
* @note Âûçûâàåò ãëàâíóþ ôóíêöèþ main èç ïîëüçîâàòåëüñêîãî êîäà è óïðàâëÿåò å¸ õîäîì:
|
|
* Ïðåðûâàåò å¸, åñëè îíà ïîïàëà â áåñêîíå÷íûé while, ñèìóëèðóåò ïåðèôåðèþ
|
|
* è âîçâðàùàåò â òî÷êó îñòàíîâêè íà ñëåäóþùåì øàãå.
|
|
*/
|
|
/* simulate controller step */
|
|
extern int main(void); // extern while from main.c
|
|
unsigned __stdcall MCU_App_Thread(void) {
|
|
main(); // ñèìóëÿöèÿ êîäà ÌÊ
|
|
return 0;
|
|
}
|
|
void MCU_Step_Simulation(SimStruct* S, real_T* in, real_T* disc, time_T time)
|
|
{
|
|
//-----------INIT WRAPPER-----------
|
|
if (hmcu.Get_RSP_Origin) // åñëè íàäî ïîëó÷òü óêàçàòåëü íà "íà÷àëî" ñòåêà
|
|
{
|
|
hmcu.Get_RSP_Origin = 0; // ñáðîñ ôëàãà, ÷òîáû ñþäà áîëüøå íå ïîïàäàòü
|
|
// óêàçàòåëü íà "íà÷àëî" ñòåêà - áåðåòñÿ â íà÷àëå ãëàâíîé óïðàâëÿþùåé ôóíêöèè
|
|
//GET_RSP_ORIGIN(&hmcu);
|
|
|
|
// èíèöèàëèçàöèÿ ïîòîêà, êîòîðûé áóäåò âûïîëíÿòü êîä ÌÊ
|
|
hThread = (HANDLE)_beginthreadex(NULL, 0, MCU_App_Thread, 0, 0x00000004, &idThreads);
|
|
|
|
ResumeThread(hThread);
|
|
|
|
//Sleep(100);
|
|
for (int i = TIME_FOR_MCU_APP*10000; i > 0; i--)
|
|
{
|
|
}
|
|
|
|
SuspendThread(hThread);
|
|
return;
|
|
}
|
|
//----------------------------------
|
|
|
|
// Get uwTick (in ms)
|
|
//uwTick = time * 1000; // from simulation time
|
|
|
|
SystemClockDouble += SystemCoreClock * SIM_Sample_Time; // emulate core clock
|
|
SystemClock = SystemClockDouble;
|
|
uwTick = SystemClock / (SystemCoreClock / 1000);
|
|
|
|
MCU_readInputs(in); // ñ÷èòûâàíèå ïîðòîâ
|
|
|
|
MCU_Periph_Simulation(); // simulate peripheral
|
|
|
|
//// Return to MCU app at line, where it was stopped
|
|
//if (hmcu.Resume_MCU_App) // åñëè íåîáõîäèìî âåðíóòñÿ â êîä ÌÊ
|
|
//{
|
|
// // Ñáðîñ ôëàãîâ
|
|
// hmcu.Resume_MCU_App = 0;
|
|
// hmcu.Stop_MCU_App = 0;
|
|
// // Âîçâðàò â êîä ÌÊ
|
|
// RESTORE_CONTEXT_AND_JUMP(&hmcu);
|
|
//}
|
|
|
|
//// ñîõðàíåíèå êîíòåêñòà äî ïåðåõîäà â êîä ÌÊ
|
|
//if (!hmcu.Stop_MCU_App && (setjmp(hmcu.main_start) == 0))
|
|
//{ // åñëè êîíòåêñò ñîõðàíåí (setjmp == 0) è ÌÊ íå îñòàíîâëåí
|
|
// main(); // ñèìóëÿöèÿ êîäà ÌÊ
|
|
//}
|
|
// note: ïðè âûçîâå longjmp, setjmp != 0, ïîýòîìó ïðîãðàììà íå âîéäåò çàíîâî â main_loop
|
|
|
|
|
|
|
|
ResumeThread(hThread);
|
|
for (int i = TIME_FOR_MCU_APP; i > 0; i--)
|
|
{
|
|
}
|
|
SuspendThread(hThread);
|
|
|
|
|
|
MCU_writeOutputs(disc); // çàïèñü ïîðòîâ (ïî ôàêòó çàïèñü â áóôåð. çàïèñü â ïîðòû â mdlOutputs)
|
|
}
|
|
|
|
/** SIMULATE MCU PERIPHERAL */
|
|
/**
|
|
* @brief Simulate peripheral of MCU
|
|
* @note Ïîëüçîâàòåëüñêèé êîä, êîòîðûé ñèìóëèðóåò ðàáîòó ïåðèôåðèè ÌÊ.
|
|
*/
|
|
void MCU_Periph_Simulation(void)
|
|
{
|
|
Simulate_TIMs();
|
|
}
|
|
|
|
/** READ INPUTS S-FUNCTION */
|
|
/**
|
|
* @brief Read from simulink S-Block Inputs and write to MCU I/O ports.
|
|
* @param in - inputs of S-Function.
|
|
* @note Ïîëüçîâàòåëüñêèé êîä, êîòîðûé çàïèñûâàåò â ïîðòû ââîäà-âûâîäà èç disc.
|
|
*/
|
|
void MCU_readInputs(real_T *in)
|
|
{
|
|
SFUNC_to_GPIO(in);
|
|
}
|
|
|
|
/** WRITE OUTPUTS S-FUNCTION */
|
|
/**
|
|
* @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.
|
|
* @note Ïîëüçîâàòåëüñêèé êîä, êîòîðûé çàïèñûâàåò â disc ïîðòû ââîäà-âûâîäà.
|
|
*/
|
|
void MCU_writeOutputs(real_T *disc)
|
|
{
|
|
GPIO_to_SFUNC(disc);
|
|
}
|
|
//-----------------CONTROLLER SIMULATE FUNCTIONS---------------//
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//----------INITIALIZE/DEINITIALIZE SIMULATE FUNCTIONS---------//
|
|
/** MCU WRAPPER DEINITIALIZATION */
|
|
/**
|
|
* @brief Initialize structures and variables for simulating MCU.
|
|
* @note Ïîëüçîâàòåëüñêèé êîä, êîòîðûé áóäåò íàñòðàèâàòü âñå ñòðóêòóðû.
|
|
*/
|
|
void SIM_Initialize_Simulation(void)
|
|
{
|
|
/* user initialization */
|
|
Initialize_Periph_Sim();
|
|
|
|
/* wrapper initialization */
|
|
//SystemClock_step = SystemCoreClock * SIM_Sample_Time; // set system clock step
|
|
hmcu.Get_RSP_Origin = 1; // set flag to store pionter to "beginning" pf the stack
|
|
}
|
|
/** MCU WRAPPER DEINITIALIZATION */
|
|
/**
|
|
* @brief Deinitialize structures and variables for simulating MCU.
|
|
* @note Ïîëüçîâàòåëüñêèé êîä, êîòîðûé áóäåò î÷èùàòü âñå ñòðóêòóðû.
|
|
*/
|
|
void SIM_deInitialize_Simulation(void)
|
|
{
|
|
// simulate structures of peripheral deinitialization
|
|
deInitialize_Periph_Sim();
|
|
// mcu peripheral memory deinitialization
|
|
deInitialize_MCU();
|
|
}
|
|
//-------------------------------------------------------------//
|
|
|
|
|
|
//-------------------------------------------------------------//
|
|
//------------------- SAVE CONTEXT FUNCTIONS -----------------//
|
|
/** SAVE CONTEXT OF PROGRAMM */
|
|
/**
|
|
* @brief Save context (stack, registers) of running program.
|
|
* @note Äàííàÿ ôóíêöèÿ óñòàíàâëèâàåò ñ÷åò÷èê êîììàíä íà íà÷àëî ôóíêöèè.
|
|
* Òàê ÷òî âîçâðàò áóäåò ïðîèçâåäåí â íà÷àëî ýòîé ôóíêöèè.
|
|
*/
|
|
void saveProgramContext(void)
|
|
{
|
|
_SAVE_RIP_(hmcu);
|
|
hmcu.REGS.Rip -= 5; // Ñäâèã RIP ñ ýòîé êîìàíäû íà ïåðâóþ êîìàíäó â ôóíêöèè: sizeof(call getNextAddr) = 5
|
|
READ_REGS(&hmcu.REGS); // Ñ÷èòûâàíèå ðåãèñòðîâ
|
|
_SAVE_STACK_(hmcu); // Ñ÷èòûâàíèå ðåãèñòðîâ
|
|
}
|
|
|
|
/** GET NEXT INSTRUCTION ADDRESS */
|
|
/**
|
|
* @brief Gives the address where this function will return.
|
|
*/
|
|
void* getNextAddr(void) {
|
|
return _ReturnAddress();
|
|
}
|
|
//-------------------------------------------------------------//
|