diplom/научка/code/matlab_stm_emulate/.outdate/MCU_Wrapper/controller.c
2025-05-09 21:26:59 +03:00

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();
}
//-------------------------------------------------------------//