diff --git a/MCU_STM32F1xx_Matlab/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h b/MCU_STM32F1xx_Matlab/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h index 1950978..263b866 100644 --- a/MCU_STM32F1xx_Matlab/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h +++ b/MCU_STM32F1xx_Matlab/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h @@ -30,7 +30,7 @@ extern "C" { #include "stm32f1xx.h" #include "Legacy/stm32_hal_legacy.h" #include -#include "mcu_wrapper_conf.h" +//#include "mcu_wrapper_conf.h" /* Exported types ------------------------------------------------------------*/ diff --git a/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.c b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.c index c330d14..ea1927b 100644 --- a/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.c +++ b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.c @@ -3,6 +3,7 @@ δετΰινΰμθ β stm32f4xx_matlab_conf.h. **************************************************************************/ +#include "stm32f1xx_matlab_conf.h" #include "mcu_wrapper_conf.h" MCU_MemoryTypeDef MCU_MEM; diff --git a/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.h b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.h index 6ad9d73..43717cb 100644 --- a/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.h +++ b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.h @@ -7,7 +7,7 @@ #define _MATLAB_SETUP_H_ #include "stm32_defs.h" #include "stm32f1xx_hal.h" -//#include "mcu_wrapper_conf.h" +#include "mcu_wrapper_conf.h" // DEFINES (UNCOMMENT WHAT YOU WILL SIMULATE) // TIMS diff --git a/MCU_STM32F1xx_Matlab/periph_config.json b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.json similarity index 78% rename from MCU_STM32F1xx_Matlab/periph_config.json rename to MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.json index 8d354ed..263f7ba 100644 --- a/MCU_STM32F1xx_Matlab/periph_config.json +++ b/MCU_STM32F1xx_Matlab/stm32f1xx_matlab_conf.json @@ -1,4 +1,57 @@ { + "Code": { + "Sources": { + "Type": "files", + "Options": [ + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c", + "Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c", + "stm32f1xx_matlab_conf.c", + "Drivers/STM32F1xx_SIMULINK/stm32f1xx_matlab_gpio.c", + "Drivers/STM32F1xx_SIMULINK/stm32f1xx_matlab_tim.c", + "Drivers/STM32F1xx_SIMULINK/stm32f1xx_periph_registers.c" + ] + }, + "Includes": { + "Type": "paths", + "Options": [ + "", + "Drivers/STM32F1xx_SIMULINK", + "Drivers/CMSIS", + "Drivers/CMSIS/Device/STM32F1xx", + "Drivers/STM32F1xx_HAL_Driver/Inc", + "Drivers/STM32F1xx_HAL_Driver/Inc/Legacy" + ] + } + }, + "UserCode": { + "Functions": { + "PeriphInit": { + "Options": [ + "Initialize_Periph_Sim()" + ] + }, + "PeriphSimulation": { + "Options": [ + "Simulate_TIMs()", + "Simulate_GPIO_BSRR()" + ] + }, + "PeriphDeinit": { + "Options": [ + "deInitialize_Periph_Sim()" + ] + } + } + }, "RCC": { "Defines": { "HCLK_Clock": { diff --git a/MCU_Wrapper/MCU.c b/MCU_Wrapper/MCU.c index 05ad921..f0bbed8 100644 --- a/MCU_Wrapper/MCU.c +++ b/MCU_Wrapper/MCU.c @@ -19,7 +19,7 @@ * @{ */ -#define S_FUNCTION_NAME MCU +#define S_FUNCTION_NAME MCU #define S_FUNCTION_LEVEL 2 #include "mcu_wrapper_conf.h" @@ -111,16 +111,18 @@ static void mdlInitializeSizes(SimStruct* S) ssSetNumDiscStates(S, DISC_STATES_WIDTH); // number of discrete states // set up input port - if (!ssSetNumInputPorts(S, 1)) return; + if (!ssSetNumInputPorts(S, IN_PORT_NUMB)) return; for (int i = 0; i < IN_PORT_NUMB; i++) - ssSetInputPortWidth(S, i, IN_PORT_WIDTH); - ssSetInputPortDirectFeedThrough(S, 0, 0); - ssSetInputPortRequiredContiguous(S, 0, 1); // direct input signal access + { + ssSetInputPortWidth(S, i, inLengths[i]); + ssSetInputPortDirectFeedThrough(S, i, 0); + ssSetInputPortRequiredContiguous(S, i, 1); + } // set up output port if (!ssSetNumOutputPorts(S, OUT_PORT_NUMB)) return; for (int i = 0; i < OUT_PORT_NUMB; i++) - ssSetOutputPortWidth(S, i, OUT_PORT_WIDTH); + ssSetOutputPortWidth(S, i, outLengths[i]); ssSetNumSampleTimes(S, 1); @@ -152,7 +154,7 @@ static void mdlInitializeSizes(SimStruct* S) */ static void mdlStart(SimStruct* S) { - SIM_Initialize_Simulation(); + SIM_Initialize_Simulation(S); } #endif // MDL_START @@ -167,10 +169,10 @@ static void mdlStart(SimStruct* S) static void mdlInitializeSampleTimes(SimStruct* S) { // Π¨Π°Π³ дискрСтизации - hmcu.SIM_Sample_Time = mxGetPr(ssGetSFcnParam(S, NPARAMS - 1))[0]; + hmcu.sSimSampleTime = mxGetPr(ssGetSFcnParam(S, NPARAMS - 1))[0]; // Register one pair for each sample time - ssSetSampleTime(S, 0, hmcu.SIM_Sample_Time); + ssSetSampleTime(S, 0, hmcu.sSimSampleTime); ssSetOffsetTime(S, 0, 0.0); } @@ -189,7 +191,7 @@ static void mdlTerminate(SimStruct* S) ResumeThread(hmcu.hMCUThread); WaitForSingleObject(hmcu.hMCUThread, 10000); #endif - SIM_deInitialize_Simulation(); + SIM_deInitialize_Simulation(S); mexUnlock(); } diff --git a/MCU_Wrapper/app_wrapper.c b/MCU_Wrapper/app_wrapper.c deleted file mode 100644 index 17be3d1..0000000 --- a/MCU_Wrapper/app_wrapper.c +++ /dev/null @@ -1,138 +0,0 @@ -/** -************************************************************************** -* @file app_wrapper.c -* @brief Код для ΠΈΠ· прилоТСния МК для симуляции. -************************************************************************** -**************************************************************************/ - -#include "mcu_wrapper_conf.h" -// Includes START -#include "upp.h" -#include "main.h" -// Inlcudes END - -// Dummy functions START -uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {} -void SystemClock_Config(void) {} -void Error_Handler(void) {} -// Dummy functions END - -void app_init(void) -{ -/* USER CODE BEGIN 1 */ - - /* USER CODE END 1 */ - - /* MCU Configuration--------------------------------------------------------*/ - - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ - HAL_Init(); - - /* USER CODE BEGIN Init */ - - /* USER CODE END Init */ - - /* Configure the system clock */ - SystemClock_Config(); - - /* USER CODE BEGIN SysInit */ - - /* USER CODE END SysInit */ - - /* Initialize all configured peripherals */ - MX_GPIO_Init(); - MX_TIM2_Init(); - /* USER CODE BEGIN 2 */ - upp_init(); - - /* USER CODE END 2 */ - - /* Infinite loop */ - /* USER CODE BEGIN WHILE */ - //while (1) - //{ - // upp_main(); - // /* USER CODE END WHILE */ - - // /* USER CODE BEGIN 3 */ - //} - /* USER CODE END 3 */ -} - - -void app_step(void) -{ - upp_main(); -} - -void app_writeOutputBuffer(real_T* disc) -{ - - for (int i = 0; i < PORT_WIDTH; i++) - { - if (GPIOA->ODR & (1 << i)) - { - disc[i] = 1; - } - - if (GPIOB->ODR & (1 << i)) - { - disc[PORT_WIDTH + i] = 1; - } - } - disc[2 * PORT_WIDTH + 0] = phase_A.ctrl.angle.delay_us; - disc[2 * PORT_WIDTH + 1] = (uint16_t)((uint16_t)TIMER->CNT - phase_A.ctrl.angle.start_delay_tick); - disc[2 * PORT_WIDTH + 2] = phase_A.ctrl.angle.start_delay_tick; - disc[2 * PORT_WIDTH + 3] = TIMER->CNT; -} - - - -void app_readInputs(real_T* in) -{ - -#define detect_front(_in_numb_, _var_, _val_) { \ -if ((in[_in_numb_] > 0.5) && (prev_in[_in_numb_] <= 0.5)) \ -{ \ - _var_ = _val_; \ -} } - -#define detect_rise(_in_numb_, _var_, _val_) { \ -if ((in[_in_numb_] < 0.5) && (prev_in[_in_numb_] >= 0.5)) \ -{ \ - _var_ = _val_; \ -} } - - static real_T prev_in[IN_PORT_WIDTH]; - - detect_front(0, phase_A.zc_detector.f.EXTIZeroCrossDetected, 1); - detect_rise(0, phase_A.zc_detector.f.EXTIZeroCrossDetected, 1); - - detect_front(1, phase_B.zc_detector.f.EXTIZeroCrossDetected, 1); - detect_rise(1, phase_B.zc_detector.f.EXTIZeroCrossDetected, 1); - - detect_front(2, phase_C.zc_detector.f.EXTIZeroCrossDetected, 1); - detect_rise(2, phase_C.zc_detector.f.EXTIZeroCrossDetected, 1); - - detect_front(3, Upp.GoSafe, 1); - detect_rise(3, Upp.GoSafe, 0); - - detect_front(4, Upp.Prepare, 1); - detect_rise(4, Upp.Prepare, 0); - - detect_front(5, Upp.ForceStop, 1); - detect_rise(5, Upp.ForceStop, 0); - - detect_front(6, Upp.ForceDisconnect, 1); - detect_rise(6, Upp.ForceDisconnect, 0); - - - Upp.sine_freq = in[7]; - Upp.Duration = in[8]; - - - for (int i = 0; i < IN_PORT_WIDTH; i++) - { - prev_in[i] = in[i]; - } -} diff --git a/MCU_Wrapper/findjobj.mltbx b/MCU_Wrapper/findjobj.mltbx deleted file mode 100644 index fda256a..0000000 Binary files a/MCU_Wrapper/findjobj.mltbx and /dev/null differ diff --git a/MCU_Wrapper/mcu_wrapper.c b/MCU_Wrapper/mcu_wrapper.c index 5c13741..032c353 100644 --- a/MCU_Wrapper/mcu_wrapper.c +++ b/MCU_Wrapper/mcu_wrapper.c @@ -7,6 +7,7 @@ Π”Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» содСрТит Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для симуляции МК Π² Simulink (S-Function). **************************************************************************/ #include "mcu_wrapper_conf.h" +#include "app_wrapper.h" /** * @addtogroup WRAPPER_CONF @@ -15,6 +16,41 @@ SIM__MCUHandleTypeDef hmcu; ///< Π₯Π΅Π½Π΄Π» для управлСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК +// INPUT/OUTPUTS AUTO-PARAMS START +/** + * @brief Π’Π°Π±Π»ΠΈΡ†Π° Π΄Π»ΠΈΠ½ массивов IN + */ +const int inLengths[IN_PORT_NUMB] = { + IN_PORT_1_WIDTH, + IN_PORT_2_WIDTH +}; +/** + * @brief Π’Π°Π±Π»ΠΈΡ†Π° смСщСний Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ массивС IN + */ +const int inOffsets[IN_PORT_NUMB] = { + OFFSET_IN_ARRAY_1, + OFFSET_IN_ARRAY_2 +}; + +/** + * @brief Π’Π°Π±Π»ΠΈΡ†Π° Π΄Π»ΠΈΠ½ массивов OUT + */ +const int outLengths[OUT_PORT_NUMB] = { + OUT_PORT_1_WIDTH, + OUT_PORT_2_WIDTH, + OUT_PORT_3_WIDTH +}; +/** + * @brief Π’Π°Π±Π»ΠΈΡ†Π° смСщСний Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ массивС OUT + */ +const int outOffsets[OUT_PORT_NUMB] = { + OFFSET_OUT_ARRAY_1, + OFFSET_OUT_ARRAY_2, + OFFSET_OUT_ARRAY_3 +}; + +// INPUT/OUTPUTS AUTO-PARAMS END + /** MCU_WRAPPER * @} */ @@ -50,13 +86,13 @@ unsigned __stdcall MCU_App_Thread(void) { */ void MCU_Step_Simulation(SimStruct* S, time_T time) { - hmcu.SystemClockDouble += hmcu.SystemClock_step; // emulate core clock + hmcu.SystemClockDouble += hmcu.sSystemClock_step; // emulate core clock hmcu.SystemClock = hmcu.SystemClockDouble; hmcu.SimTime = time; MCU_readInputs(S); // считываниС ΠΏΠΎΡ€Ρ‚ΠΎΠ² - MCU_Periph_Simulation(); // simulate peripheral + MCU_Periph_Simulation(S); // simulate peripheral #ifdef RUN_APP_MAIN_FUNC_THREAD ResumeThread(hmcu.hMCUThread); @@ -76,25 +112,26 @@ void MCU_Step_Simulation(SimStruct* S, time_T time) * @brief Бимуляция ΠΏΠ΅Ρ€ΠΈΡ„Π΅Ρ€ΠΈΠΈ МК * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ симулируСт Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠ΅Ρ€ΠΈΡ„Π΅Ρ€ΠΈΠΈ МК. */ -void MCU_Periph_Simulation(void) +void MCU_Periph_Simulation(SimStruct* S) { - uwTick = hmcu.SystemClock / (MCU_CORE_CLOCK / 1000); - - Simulate_TIMs(); +// PERIPH SIM START + Simulate_TIMs(); + Simulate_GPIO_BSRR(); +// PERIPH SIM END } /* READ INPUTS S-FUNCTION TO MCU REGS */ /** * @brief Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅ Π²Ρ…ΠΎΠ΄ΠΎΠ² S-Function Π² ΠΏΠΎΡ€Ρ‚Ρ‹ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°. * @param S - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру S-Function ΠΈΠ· "simstruc.h" - * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ записываСт ΠΏΠΎΡ€Ρ‚Ρ‹ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΈΠ· Π²Ρ…ΠΎΠ΄ΠΎΠ² S-Function. + * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ записываСт Π²Ρ…ΠΎΠ΄Ρ‹ МК ΠΈΠ· Π²Ρ…ΠΎΠ΄ΠΎΠ² S-Function. */ void MCU_readInputs(SimStruct* S) { - /* Get S-Function inputs */ - real_T* IN = ssGetInputPortRealSignal(S, 0); - - app_readInputs(IN); + SIM_readInputs(S); + /* Get S-Function descrete array (IO buffer) */ + real_T* In_Buff = ssGetDiscStates(S); + app_readInputs(In_Buff); } /* WRITE OUTPUTS BUFFER S-FUNCTION FROM MCU REGS*/ @@ -105,10 +142,9 @@ void MCU_readInputs(SimStruct* S) */ void MCU_writeOutputs(SimStruct* S) { - /* Get S-Function descrete array */ + /* Get S-Function descrete array (IO buffer) */ real_T* Out_Buff = ssGetDiscStates(S); - Simulate_GPIO_BSRR(); app_writeOutputBuffer(Out_Buff); } //-----------------CONTROLLER SIMULATE FUNCTIONS---------------// @@ -118,65 +154,129 @@ void MCU_writeOutputs(SimStruct* S) //-------------------------------------------------------------// //----------------------SIMULINK FUNCTIONS---------------------// -/* WRITE OUTPUTS OF S-BLOCK */ -/** - * @brief Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² S-Function. - * @param S - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру S-Function ΠΈΠ· "simstruc.h" - * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ записываСт Π²Ρ‹Ρ…ΠΎΠ΄Ρ‹ S-Function ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π°. - */ -void SIM_writeOutputs(SimStruct* S) -{ - real_T* GPIO; - real_T* Out_Buff = 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] = Out_Buff[j * PORT_WIDTH + i]; - Out_Buff[j * PORT_WIDTH + i] = 0; - } - } - //------------------------------------------ -} /* MCU WRAPPER DEINITIALIZATION */ /** * @brief Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ симуляции МК. - * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСт ΠΏΠΎΡ‚ΠΎΠΊ для прилоТСния МК + * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСт ΠΏΠΎΡ‚ΠΎΠΊ для прилоТСния МК ΠΈ настраиваСт симулятор МК для симуляции. */ -void SIM_Initialize_Simulation(void) +void SIM_Initialize_Simulation(SimStruct* S) { #ifdef RUN_APP_MAIN_FUNC_THREAD // инициализация ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠΎΠ΄ МК hmcu.hMCUThread = (HANDLE)CreateThread(NULL, 0, MCU_App_Thread, 0, CREATE_SUSPENDED, &hmcu.idMCUThread); -#else - extern int app_init(void); - app_init(); #endif //RUN_APP_MAIN_FUNC_THREAD /* user initialization */ - Initialize_Periph_Sim(); - - /* wrapper initialization */ - hmcu.SystemClock_step = MCU_CORE_CLOCK * hmcu.SIM_Sample_Time; // set system clock step + app_init(); +// PERIPH INIT START + Initialize_Periph_Sim(); +// PERIPH INIT END + + /* clock step initialization */ + hmcu.sSystemClock_step = MCU_CORE_CLOCK * hmcu.sSimSampleTime; // set system clock step + hmcu.fInitDone = 1; } /* MCU WRAPPER DEINITIALIZATION */ /** * @brief ДСинициализация симуляции МК. * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ всС структуры послС окончания симуляции. */ -void SIM_deInitialize_Simulation(void) +void SIM_deInitialize_Simulation(SimStruct* S) { -//#ifdef DEINITIALIZE_AFTER_SIM -#include "upp.h" - memset(&Upp, 0, sizeof(Upp)); - // simulate structures of peripheral deinitialization - deInitialize_Periph_Sim(); - // mcu peripheral memory deinitialization - deInitialize_MCU(); -//#endif +#ifdef DEINITIALIZE_AFTER_SIM + // deinitialize app + app_deinit(); +// PERIPH DEINIT START + deInitialize_Periph_Sim(); +// PERIPH DEINIT END +#endif// DEINITIALIZE_AFTER_SIM +} +/* WORK WITH IN/OUT BUFFER OF S-BLOCK */ + +/** + * @brief Ѐункция для записи ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² Π±ΡƒΡ„Π΅Ρ€ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ массив + * @param xD - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π±ΡƒΡ„Π΅Ρ€ состояний + * @param value - Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для записи + * @param array_index - индСкс Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ массива + * @param value_index - индСкс Π²Π½ΡƒΡ‚Ρ€ΠΈ массива + */ +void __WriteOutputArray(real_T* xD, float value, int array_index, int value_index) +{ + if (array_index >= OUT_PORT_NUMB) + return; + + if (value_index >= outLengths[array_index]) + return; + + int global_index = XD_OUTPUT_START + outOffsets[array_index] + value_index; + xD[global_index] = value; +} + +/** + * @brief Ѐункция для чтСния значСния ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° Π²Ρ…ΠΎΠ΄ΠΎΠ² ΠΈΠ· ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ массива + * @param xD - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π±ΡƒΡ„Π΅Ρ€ состояний + * @param array_index - индСкс Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ массива + * @param value_index - индСкс Π²Π½ΡƒΡ‚Ρ€ΠΈ массива + * @return - считанноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ 0.0 ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π·Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ + */ +float __ReadInputArray(const real_T* xD, int array_index, int value_index) +{ + if (array_index >= IN_PORT_NUMB) + return 0.0f; + + if (value_index >= inLengths[array_index]) + return 0.0f; + + int global_index = XD_INPUT_START + inOffsets[array_index] + value_index; + return xD[global_index]; +} + +/** + * @brief Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² S-Function. + * @param S - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру S-Function ΠΈΠ· "simstruc.h" + * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ записываСт Π²Ρ‹Ρ…ΠΎΠ΄Ρ‹ S-Function ΠΈΠ· Π±ΡƒΡ„Π΅Ρ€Π° дискрСтных состояний. + */ +void SIM_writeOutputs(SimStruct* S) +{ + real_T* Output = ssGetOutputPortRealSignal(S,0); + real_T* Out_Buff = ssGetDiscStates(S); + int global_index; + + //-------------WRITTING OUTPUT-------------- + for (int arr_ind = 0; arr_ind < OUT_PORT_NUMB; arr_ind++) + { + Output = ssGetOutputPortRealSignal(S, arr_ind); + for (int val_ind = 0; val_ind < outLengths[arr_ind]; val_ind++) + { + global_index = XD_OUTPUT_START + outOffsets[arr_ind] + val_ind; + Output[val_ind] = Out_Buff[global_index]; + Out_Buff[global_index] = 0; + } + } + //------------------------------------------ +} +/** + * @brief Π€ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ…ΠΎΠ΄ΠΎΠ² S-Function. + * @param S - ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру S-Function ΠΈΠ· "simstruc.h" + * @details ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ считываСт Π²Ρ…ΠΎΠ΄Ρ‹ S-Function Π² Π±ΡƒΡ„Π΅Ρ€ дискрСтных состояний. + */ +void SIM_readInputs(SimStruct* S) +{ + real_T* Input = ssGetInputPortRealSignal(S, 0); + real_T* In_Buff = ssGetDiscStates(S); + int global_index; + + //-------------READING INPUTS--------------- + for (int arr_ind = 0; arr_ind < IN_PORT_NUMB; arr_ind++) + { + Input = ssGetInputPortRealSignal(S, arr_ind); + for (int val_ind = 0; val_ind < inLengths[arr_ind]; val_ind++) + { + global_index = XD_INPUT_START + inOffsets[arr_ind] + val_ind; + In_Buff[global_index] = Input[val_ind]; + } + } + //------------------------------------------ } //-------------------------------------------------------------// diff --git a/MCU_Wrapper/mcu_wrapper_conf.h b/MCU_Wrapper/mcu_wrapper_conf.h index 545b824..6879f93 100644 --- a/MCU_Wrapper/mcu_wrapper_conf.h +++ b/MCU_Wrapper/mcu_wrapper_conf.h @@ -2,11 +2,11 @@ ************************************************************************** * @dir ../MCU_Wrapper * @brief Папка с исходным ΠΊΠΎΠ΄ΠΎΠΌ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК. -* @details -Π’ этой ΠΏΠ°ΠΏΠΊΠ΅ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒΡΡ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°(Π°Π½Π³Π». wrapper) для запуска ΠΈ контроля -эмуляции ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² Π² MATLAB (любого МК, Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ STM). -ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° прСдставляСт собой S-Function - Π±Π»ΠΎΠΊ Π² Simulink, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ -ΠΏΠΎ скомпилированому ΠΊΠΎΠ΄Ρƒ. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ происходит с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ MSVC-компилятора. +* @details +Π’ этой ΠΏΠ°ΠΏΠΊΠ΅ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒΡΡ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°(Π°Π½Π³Π». wrapper) для запуска ΠΈ контроля +эмуляции ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² Π² MATLAB (любого МК, Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ STM). +ΠžΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ° прСдставляСт собой S-Function - Π±Π»ΠΎΠΊ Π² Simulink, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ +ΠΏΠΎ скомпилированому ΠΊΠΎΠ΄Ρƒ. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ происходит с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ MSVC-компилятора. **************************************************************************/ /** @@ -25,56 +25,105 @@ #define _WRAPPER_CONF_H_ // Includes -#include "stm32f1xx_matlab_conf.h" // For stm simulate functions #include "simstruc.h" // For S-Function variables #include // For threads +#include "app_includes.h" + /** * @defgroup MCU_WRAPPER MCU Wrapper * @brief ВсякоС для ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК */ - /** - * @addtogroup WRAPPER_CONF Wrapper Configuration - * @ingroup MCU_WRAPPER - * @brief ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ для ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК - * @details Π—Π΄Π΅ΡΡŒ Π΄Π΅Ρ„Π°ΠΉΠ½Π°ΠΌΠΈ задаСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ ΠΊΠ°ΠΊ ΠΎΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ - * @{ - */ +/** + * @addtogroup WRAPPER_CONF Wrapper Configuration + * @ingroup MCU_WRAPPER + * @brief ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ для ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК + * @details Π—Π΄Π΅ΡΡŒ Π΄Π΅Ρ„Π°ΠΉΠ½Π°ΠΌΠΈ задаСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ ΠΊΠ°ΠΊ ΠΎΠ½Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ + * @{ + */ - // Parametrs of MCU simulator +// Parametrs of MCU simulator //#define RUN_APP_MAIN_FUNC_THREAD ///< Enable using thread for MCU main() func -//#define DEKSTOP_CYCLES_FOR_MCU_APP 0xFF ///< number of for() cycles after which MCU thread would be suspended -//#define MCU_CORE_CLOCK 72000000 +//#define DEKSTOP_CYCLES_FOR_MCU_APP 0xFFFF ///< number of for() cycles after which MCU thread would be suspended +//#define MCU_CORE_CLOCK 150000000 ///< MCU clock rate for simulation - -//#define DEINITIALIZE_AFTER_SIM ///< Enable deinitializing structures at simulation ends - - -#define PORT_WIDTH 16 ///< width of one port -#define PORT_NUMB 3 ///< amount of ports // Parameters of S_Function -#define NPARAMS 1 ///< number of input parametrs (only Ts) -#define IN_PORT_WIDTH (9) ///< width of input ports -#define IN_PORT_NUMB 1 ///< number of input ports -#define OUT_PORT_WIDTH PORT_WIDTH ///< width of output ports -#define OUT_PORT_NUMB PORT_NUMB ///< number of output ports -#define DISC_STATES_WIDTH PORT_WIDTH*PORT_NUMB ///< width of discrete states array +// INPUT/OUTPUTS PARAMS START +#define IN_PORT_NUMB 2 +#define IN_PORT_1_WIDTH 3 +#define IN_PORT_2_WIDTH 6 +#define OUT_PORT_NUMB 3 +#define OUT_PORT_1_WIDTH 16 +#define OUT_PORT_2_WIDTH 16 +#define OUT_PORT_3_WIDTH 16 + +// INPUT/OUTPUTS PARAMS END /** WRAPPER_CONF * @} */ - /** - * @addtogroup MCU_WRAPPER - * @{ - */ - // Fixed parameters(?) of S_Function +/** + * @addtogroup MCU_WRAPPER + * @{ + */ + +/** @brief ЗаписываСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ массив Π±Π»ΠΎΠΊΠ° S-Function + * @param _var_ Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ (Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΎ Π² float) + * @param _arr_ind_ ИндСкс Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Ρ‚Π° + * @param _val_ind_ ИндСкс элСмСнта Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌ массивС + */ +#define WriteOutputArray(_var_, _arr_ind_, _val_ind_) __WriteOutputArray(Buffer, (float)_var_, _arr_ind_, _val_ind_) + +/** @brief Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ массива Π±Π»ΠΎΠΊΠ° S-Function + * @param _var_ Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ (Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΎ Π² float) + * @param _arr_ind_ ИндСкс Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ€Ρ‚Π° + * @param _val_ind_ ИндСкс элСмСнта Π²ΠΎ Π²Ρ…ΠΎΠ΄Π½ΠΎΠΌ массивС + */ +#define ReadInputArray(_arr_ind_, _val_ind_) __ReadInputArray(Buffer, _arr_ind_, _val_ind_) + + + +// INPUT/OUTPUTS AUTO-PARAMS START +/// === ΠŸΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° === +#define TOTAL_IN_SIZE (IN_PORT_1_WIDTH + IN_PORT_2_WIDTH) + +/// === БмСщСния массивов (Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±Ρ‰Π΅Π³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π°) === +#define OFFSET_IN_ARRAY_1 0 +#define OFFSET_IN_ARRAY_2 (OFFSET_IN_ARRAY_1 + IN_PORT_1_WIDTH) + +/// === ΠŸΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±ΡƒΡ„Π΅Ρ€Π° === +#define TOTAL_OUT_SIZE (OUT_PORT_1_WIDTH + OUT_PORT_2_WIDTH + OUT_PORT_3_WIDTH) + +/// === БмСщСния массивов (Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±Ρ‰Π΅Π³ΠΎ Π±ΡƒΡ„Π΅Ρ€Π°) === +#define OFFSET_OUT_ARRAY_1 0 +#define OFFSET_OUT_ARRAY_2 (OFFSET_OUT_ARRAY_1 + OUT_PORT_1_WIDTH) +#define OFFSET_OUT_ARRAY_3 (OFFSET_OUT_ARRAY_2 + OUT_PORT_2_WIDTH) + +// INPUT/OUTPUTS AUTO-PARAMS END + +extern const int outLengths[OUT_PORT_NUMB]; +extern const int outOffsets[OUT_PORT_NUMB]; +extern const int inLengths[IN_PORT_NUMB]; +extern const int inOffsets[IN_PORT_NUMB]; +#define TOTAL_XD_SIZE (TOTAL_IN_SIZE + TOTAL_OUT_SIZE) +#define XD_INPUT_START 0 +#define XD_OUTPUT_START (XD_INPUT_START + TOTAL_IN_SIZE) + + + + + +// Fixed parameters(?) of S_Function #define NPARAMS 1 ///< number of input parametrs (only Ts) -#define DISC_STATES_WIDTH OUT_PORT_WIDTH*OUT_PORT_NUMB ///< width of discrete states array (outbup buffer) +#define DISC_STATES_WIDTH TOTAL_XD_SIZE ///< width of discrete states array (outbup buffer) + + + /** * @brief Define for creating thread in suspended state. * @details Define from WinBase.h. We dont wanna include "Windows.h" or smth like this, because of HAL there are a lot of redefine errors. @@ -83,21 +132,23 @@ typedef void* HANDLE; ///< MCU handle typedef /** - * @brief MCU handle Structure definition. + * @brief MCU handle Structure definition. * @note Prefixes: h - handle, s - settings, f - flag */ typedef struct { // MCU Thread HANDLE hMCUThread; ///< Π₯Π΅Π½Π΄Π» для ΠΏΠΎΡ‚ΠΎΠΊΠ° МК - uint32_t idMCUThread; ///< id ΠΏΠΎΡ‚ΠΎΠΊΠ° МК (unused) + int idMCUThread; ///< id ΠΏΠΎΡ‚ΠΎΠΊΠ° МК (unused) // Flags unsigned fMCU_Stop : 1; ///< Ρ„Π»Π°Π³ для Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК - double SIM_Sample_Time; ///< sample time of simulation + unsigned fInitDone : 1; ///< Ρ„Π»Π°Π³ для Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК + + double SimTime; ///< Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя симуляции + long SystemClock; ///< Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Ρ‚Π°ΠΊΡ‚ΠΎΠ² для симуляции систСмных Ρ‚ΠΈΠΊΠΎΠ² (Π² цСлочислСнном Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅) double SystemClockDouble; ///< Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ double для Ρ‚ΠΎΡ‡Π½ΠΎΠΉ симуляции систСмных Ρ‚ΠΈΠΊΠΎΠ² Π‘ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹ΠΌΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ - uint64_t SystemClock; ///< Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Ρ‚Π°ΠΊΡ‚ΠΎΠ² для симуляции систСмных Ρ‚ΠΈΠΊΠΎΠ² (Π² цСлочислСнном Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅) - double SystemClock_step; ///< Π¨Π°Π³ Ρ‚ΠΈΠΊΠΎΠ² для ΠΈΡ… симуляции, Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ double - double SimTime; + double sSystemClock_step; ///< Π¨Π°Π³ Ρ‚ΠΈΠΊΠΎΠ² для ΠΈΡ… симуляции, Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ double + double sSimSampleTime; ///< ΠŸΠ΅Ρ€ΠΈΠΎΠ΄ дискрСтизации симуляции }SIM__MCUHandleTypeDef; extern SIM__MCUHandleTypeDef hmcu; // extern для видимости ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π²ΠΎ всСх Ρ„Π°ΠΉΠ»Π°Ρ… @@ -112,54 +163,62 @@ extern SIM__MCUHandleTypeDef hmcu; // extern для видимос */ #define while(_expression_) sim_while(_expression_) #endif - /* SIMULINK WHILE */ - /** - * @brief While statement for emulate MCU code in Simulink. - * @param _expression_ - expression for while. - * @details Π”Π°Π½Π½Ρ‹ΠΉ while Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² ΠΊΠΎΠ½Ρ†Π΅ симуляции, Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ МК: - * ΠŸΡ€ΠΈ выставлСнии Ρ„Π»Π°Π³Π° окончания симуляции, всС while Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ - * ΠΈ ΠΏΠΎΡ‚ΠΎΠΊ смоТСт Π΄ΠΎΠΉΡ‚ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ сСбя. - */ + +/* SIMULINK WHILE */ +/** + * @brief While statement for emulate MCU code in Simulink. + * @param _expression_ - expression for while. + * @details Π”Π°Π½Π½Ρ‹ΠΉ while Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² ΠΊΠΎΠ½Ρ†Π΅ симуляции, Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ МК: + * ΠŸΡ€ΠΈ выставлСнии Ρ„Π»Π°Π³Π° окончания симуляции, всС while Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒΡΡ + * ΠΈ ΠΏΠΎΡ‚ΠΎΠΊ смоТСт Π΄ΠΎΠΉΡ‚ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ сСбя. + */ #define sim_while(_expression_) while((_expression_)&&(hmcu.fMCU_Stop == 0)) - /* DEFAULT WHILE */ - /** - * @brief Default/Native C while statement. - * @param _expression_ - expression for while. - * @details Π”Π°Π½Π½Ρ‹ΠΉ while - Π°Π½Π°Π»ΠΎΠ³ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ while, Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π°. - */ +/* DEFAULT WHILE */ +/** + * @brief Default/Native C while statement. + * @param _expression_ - expression for while. + * @details Π”Π°Π½Π½Ρ‹ΠΉ while - Π°Π½Π°Π»ΠΎΠ³ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ while, Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π°. + */ #define native_while(_expression_) for(; (_expression_); ) - /***************************************************************/ + /***************************************************************/ - //------------------ SIMULINK WHILE DEFINES -----------------// - //-------------------------------------------------------------// +//------------------ SIMULINK WHILE DEFINES -----------------// +//-------------------------------------------------------------// - //-------------------------------------------------------------// - //---------------- SIMULATE FUNCTIONS PROTOTYPES -------------// - /* Step simulation */ -void MCU_Step_Simulation(SimStruct* S, time_T time); +//-------------------------------------------------------------// +//---------------- SIMULATE FUNCTIONS PROTOTYPES -------------// +/* Step simulation */ +void MCU_Step_Simulation(SimStruct *S, time_T time); /* MCU peripheral simulation */ -void MCU_Periph_Simulation(void); +void MCU_Periph_Simulation(SimStruct* S); /* Initialize MCU simulation */ -void SIM_Initialize_Simulation(void); +void SIM_Initialize_Simulation(SimStruct* S); /* Deinitialize MCU simulation */ -void SIM_deInitialize_Simulation(void); +void SIM_deInitialize_Simulation(SimStruct* S); /* Read inputs S-function */ void MCU_readInputs(SimStruct* S); -void app_readInputs(real_T* in); /* Write pre-outputs S-function (out_buff states) */ void MCU_writeOutputs(SimStruct* S); -void app_writeOutputBuffer(real_T* disc); /* Write outputs of block of S-Function*/ -void SIM_writeOutput(SimStruct* S); +void SIM_writeOutputs(SimStruct* S); + +/* Write inputs of block of S-Function*/ +void SIM_readInputs(SimStruct* S); + +/* Set output of block of S-Function*/ +void __WriteOutputArray(real_T* xD, float value, int array_index, int value_index); + +/* Get input of block of S-Function*/ +float __ReadInputArray(const real_T* xD, int array_index, int value_index); //---------------- SIMULATE FUNCTIONS PROTOTYPES -------------// //-------------------------------------------------------------// @@ -169,14 +228,14 @@ void SIM_writeOutput(SimStruct* S); #endif // _WRAPPER_CONF_H_ - //-------------------------------------------------------------// - //---------------------BAT FILE DESCRIBTION--------------------// - /** - * @file run_mex.bat - * @brief Π‘Π°Ρ‚Π½ΠΈΠΊ для компиляции ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК. - * @details - * ВызываСтся Π² ΠΌΠ°Ρ‚Π»Π°Π±Π΅ ΠΈΠ· mexing.m. - * - * Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π±Π°Ρ‚Π½ΠΈΠΊΠ°: - * @include F:\Work\Projects\MATLAB\matlab_stm_emulate\MCU_Wrapper\run_mex.bat - */ \ No newline at end of file +//-------------------------------------------------------------// +//---------------------BAT FILE DESCRIBTION--------------------// +/** + * @file run_mex.bat + * @brief Π‘Π°Ρ‚Π½ΠΈΠΊ для компиляции ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ МК. + * @details + * ВызываСтся Π² ΠΌΠ°Ρ‚Π»Π°Π±Π΅ ΠΈΠ· allmex.m. + * + * Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π±Π°Ρ‚Π½ΠΈΠΊΠ°: + * @include run_mex.bat + */ \ No newline at end of file diff --git a/MCU_Wrapper/mexing.m b/MCU_Wrapper/mexing.m deleted file mode 100644 index a3c2709..0000000 --- a/MCU_Wrapper/mexing.m +++ /dev/null @@ -1,718 +0,0 @@ -% ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ S-function -function mexing(compile_mode) - global Ts - Ts = 0.00001; - - if compile_mode == 1 - delete("*.mexw64") - delete("*.mexw64.pdb") - delete(".\MCU_Wrapper\Outputs\*.*"); - set_param(gcb, 'consoleOutput', ''); - % Π”Π΅Ρ„Π°ΠΉΠ½Ρ‹ - definesWrapperArg = buildWrapperDefinesString(); - definesUserArg = parseDefinesMaskText(); - definesConfigArg = buildConfigDefinesString(); - definesAllArg = [definesUserArg + " " + definesWrapperArg + " " + definesConfigArg]; - - %Ρ€Π΅ΠΆΠΈΠΌΡ‹ компиляции - if read_checkbox('enableDebug') - modeArg = "debug"; - else - modeArg = "release"; - end - if read_checkbox('fullOutput') || read_checkbox('extConsol') - echoArg = 'echo_enable'; - else - echoArg = 'echo_disable'; - end - - [includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable'); - - % Π’Ρ‹Π·ΠΎΠ² Π±Π°Ρ‚Π½ΠΈΠΊΠ° с двумя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ: includes ΠΈ code - cmd = sprintf('.\\MCU_Wrapper\\run_mex.bat "%s" "%s" "%s" %s %s', includesArg, codeArg, definesAllArg, modeArg, echoArg); - - if read_checkbox('extConsol') - cmdout = runBatAndShowOutput(cmd); - else - [status, cmdout]= system(cmd); - end - - % Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ Π²Ρ‹Π²ΠΎΠ΄ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ маски с ΠΈΠΌΠ΅Π½Π΅ΠΌ 'consoleOutput' - set_param(gcb, 'consoleOutput', cmdout); - - beep - else - blockPath = bdroot; - config = read_periph_config(); - config = update_config_from_mask(blockPath, config); - write_periph_config(config); - update_mask_from_config(blockPath, config); - % set_param(gcb, 'consoleOutput', 'Peripheral configuration file loaded. Re-open Block Parameters'); - end -end - -%% COMPILE PARAMS - - -function [includesArg, codeArg] = make_mex_arguments(incTableName, srcTableame) -%MAKE_MEX_ARGUMENTS Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ строки Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для Π²Ρ‹Π·ΠΎΠ²Π° mex-компиляции Ρ‡Π΅Ρ€Π΅Π· Π±Π°Ρ‚Π½ΠΈΠΊ -% -% [includesArg, codeArg] = make_mex_arguments(includesCell, codeCell) -% -% Π’Ρ…ΠΎΠ΄: -% includesCell β€” ячСйковый массив ΠΏΡƒΡ‚Π΅ΠΉ ΠΊ дирСкториям include -% codeCell β€” ячСйковый массив исходных Ρ„Π°ΠΉΠ»ΠΎΠ² -% -% Π’Ρ‹Ρ…ΠΎΠ΄: -% includesArg β€” строка для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π² Π±Π°Ρ‚Π½ΠΈΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: "-I"inc1" -I"inc2"" -% codeArg β€” строка с исходниками, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: ""src1.c" "src2.cpp"" - - - % Π—Π΄Π΅ΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ получСния ΠΈΠ· маски Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ° (Π·Π°ΠΌΠ΅Π½ΠΈ ΠΏΠΎ своСму) - blockHandle = gcbh; % ΠΈΠ»ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈ Π½Π° Π½ΡƒΠΆΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ - - includesCell = parseCellString(get_param(blockHandle, incTableName)); - codeCell = parseCellString(get_param(blockHandle, srcTableame)); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΏΡƒΡ‚ΠΈ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΈ добавляСм -I - includesStr = strjoin(cellfun(@(f) ['-I"' f '"'], includesCell, 'UniformOutput', false), ' '); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠΌΠ΅Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ - codeStr = strjoin(cellfun(@(f) ['"' f '"'], codeCell, 'UniformOutput', false), ' '); - - % УдаляСм символ пСрСноса строки ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π» Π² ΠΊΠΎΠ½Ρ†Π΅, Ссли Π²Π΄Ρ€ΡƒΠ³ ΠΏΠΎΠΏΠ°Π» - codeStr = strtrim(codeStr); - includesStr = strtrim(includesStr); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ всю строку Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π°Ρ‚Π½ΠΈΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ понял - % includesArg = ['"' includesStr '"']; - % codeArg = ['"' codeStr '"']; - includesArg = includesStr; - codeArg = codeStr; - -end - - -function definesWrapperArg = buildWrapperDefinesString() - - definesWrapperArg = ''; - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableThreading', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableDeinit', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'threadCycles', 1); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'mcuClk', 1); -end - - -function definesUserArg = parseDefinesMaskText() - blockHandle = gcbh; - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues ΠΈ MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - - % ИндСкс ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° userDefs - idxUserDefs = find(strcmp(paramNames, 'userDefs')); - definesText = maskValues{idxUserDefs}; % ВСкст с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌΠΈ опрСдСлСниями - - % Π£Π±ΠΈΡ€Π°Π΅ΠΌ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½Ρ‹Π΅ символы \n ΠΈ \r - definesText = strrep(definesText, '\n', ' '); - definesText = strrep(definesText, '\r', ' '); - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ пСрСносам строк - lines = split(definesText, {'\n', '\r\n', '\r'}); - - parts = strings(1,0); % пустой массив строк - - for k = 1:numel(lines) - line = strtrim(lines{k}); - if isempty(line) - continue; - end - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ опрСдСлСния Π² строкС - tokens = split(line); - - for t = 1:numel(tokens) - token = strtrim(tokens{t}); - if isempty(token) - continue; - end - - eqIdx = strfind(token, '='); - if isempty(eqIdx) - % ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Π±Π΅Π· значСния - parts(end+1) = sprintf('-D"%s"', token); - else - key = strtrim(token(1:eqIdx(1)-1)); - val = strtrim(token(eqIdx(1)+1:end)); - parts(end+1) = sprintf('-D"%s__EQ__%s"', key, val); - end - end - end - - definesUserArg = strjoin(parts, ' '); -end - - - -function definesWrapperArg = buildConfigDefinesString() - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - tabName = 'configTab'; % Имя Π²ΠΊΠ»Π°Π΄ΠΊΠΈ (Prompt) - - allControls = mask.getDialogControls(); - tabCtrl = find_tab_by_name(allControls, tabName); - - if isempty(tabCtrl) - error('Π’ΠΊΠ»Π°Π΄ΠΊΠ° с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° Π² маскС', tabName); - end - definesWrapperArg = ''; - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ всС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - children = tabCtrl.DialogControls; - for i = 1:numel(children) - ctrl = children(i); - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΠ· ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π° - paramName = ctrl.Name; - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ - param = mask.getParameter(paramName); - - % ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ Ρ‚ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - switch lower(param.Type) - case 'checkbox' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 0); - case 'edit' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 1); - otherwise - % НСобрабатываСмыС Ρ‚ΠΈΠΏΡ‹ - end - catch ME - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ "%s": %s', paramName, ME.message); - end - end -end - - -%% PARSE FUNCTIONS - -function out = parseCellString(str) - str = strtrim(str); - if startsWith(str, '{') && endsWith(str, '}') - str = str(2:end-1); - end - - parts = split(str, ';'); - out = cell(numel(parts), 1); - for i = 1:numel(parts) - el = strtrim(parts{i}); - if startsWith(el, '''') && endsWith(el, '''') - el = el(2:end-1); - end - out{i} = el; - end - - if isempty(out) || (numel(out) == 1 && isempty(out{1})) - out = {}; - end -end - -function str = cellArrayToString(cellArray) - quoted = cellfun(@(s) ['''' s ''''], cellArray, 'UniformOutput', false); - str = ['{' strjoin(quoted, ';') '}']; -end - - -function definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, val_define) - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues, MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - param = mask.getParameter(paramName); % для alias - - % Найдём индСкс Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - idxParam = find(strcmp(paramNames, paramName), 1); - if isempty(idxParam) - error('Parameter "%s" not found in block mask parameters.', paramName); - end - - % Π‘Π΅Ρ€Ρ‘ΠΌ alias ΠΈΠ· маски - alias = param.Alias; - - if val_define ~= 0 - % Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - val = maskValues{idxParam}; - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ - newDefine = ['-D"' alias '__EQ__' val '"']; - else - if read_checkbox(paramName) - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ Π±Π΅Π· значСния - newDefine = ['-D"' alias '"']; - else - newDefine = ''; - end - end - - - - % ДобавляСм Π½ΠΎΠ²Ρ‹ΠΉ define ΠΊ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ (string) - if isempty(definesWrapperArg) || strlength(strtrim(definesWrapperArg)) == 0 - definesWrapperArg = newDefine; - else - definesWrapperArg = definesWrapperArg + " " + newDefine; - end -end - - - -function checkbox_state = read_checkbox(checkboxName) - maskValues = get_param(gcbh, 'MaskValues'); - paramNames = get_param(gcbh, 'MaskNames'); - - inxCheckBox = find(strcmp(paramNames, checkboxName)); - - checkbox_state_str = maskValues{inxCheckBox}; - if strcmpi(checkbox_state_str, 'on') - checkbox_state = 1; - else - checkbox_state = 0; - end -end - -%% CONSOLE FUNCTIONS - -function cmdret = runBatAndShowOutput(cmd) - import java.io.*; - import java.lang.*; - cmdEnglish = ['chcp 437 > nul && ' cmd]; - pb = java.lang.ProcessBuilder({'cmd.exe', '/c', cmdEnglish}); - pb.redirectErrorStream(true); - process = pb.start(); - - reader = BufferedReader(InputStreamReader(process.getInputStream())); - - cmdret = ""; % Π—Π΄Π΅ΡΡŒ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°Ρ‚ΡŒ вСсь Π²Ρ‹Π²ΠΎΠ΄ - - while true - if reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - % Π—Π΄Π΅ΡΡŒ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠ²ΡƒΡŽ строку - safeLine = strrep(line, '''', ''''''); % Π­ΠΊΡ€Π°Π½ΠΈΡ€ΡƒΠ΅ΠΌ апострофы - logWindow_append(safeLine); - drawnow; % обновляСм GUI - else - if ~process.isAlive() - % Π΄ΠΎΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ строки - while reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - safeLine = strrep(line, '''', ''''''); - logWindow_append(safeLine); - drawnow; - end - break; - end - pause(0.2); - end - end - process.waitFor(); -end - - -function logWindow_append(line) - persistent fig hEdit jScrollPane jTextArea - - if isempty(fig) || ~isvalid(fig) - fig = figure('Name', 'Log Window', 'Position', [100 100 600 400]); - hEdit = uicontrol('Style', 'edit', ... - 'Max', 2, 'Min', 0, ... - 'Enable', 'on', ... - 'FontName', 'Courier New', ... - 'Position', [10 10 580 380], ... - 'HorizontalAlignment', 'left', ... - 'BackgroundColor', 'white', ... - 'Tag', 'LogWindowFigure'); - - jScrollPane = findjobj(hEdit); % JScrollPane - jTextArea = jScrollPane.getViewport.getView; % JTextArea Π²Π½ΡƒΡ‚Ρ€ΠΈ JScrollPane - end - - oldText = get(hEdit, 'String'); - if ischar(oldText) - oldText = {oldText}; - end - - set(hEdit, 'String', [oldText; {line}]); - drawnow; - % Автоскролл Π²Π½ΠΈΠ·: - jTextArea.setCaretPosition(jTextArea.getDocument.getLength); - drawnow; -end - - -%% READ CONFIGS -function config = read_periph_config() - jsonText = fileread('periph_config.json'); - config = jsondecode(jsonText); -end - -function write_periph_config(config) - jsonText = jsonencode(config, 'PrettyPrint', true); - fid = fopen('periph_config.json', 'w'); - if fid == -1 - error('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» periph_config.json для записи.'); - end - fwrite(fid, jsonText, 'char'); - fclose(fid); -end - -%% CONFIG MASK TOOLS -function update_mask_from_config(blockPath, config) - blockPath = [blockPath '/MCU']; - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π±Ρ‹Π»Π° Π»ΠΈ маска ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - wasOpen = isMaskDialogOpen(blockPath); - close_system(blockPath, 0); - mask = Simulink.Mask.get(blockPath); - - tableNames = {'incTable', 'srcTable'}; - columns_backup = clear_tables(blockPath, tableNames); - - containerName = 'configTabAll'; - clear_all_from_container(mask, containerName); - - % Π˜Ρ‰Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - error('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ Π² маскС.', containerName); - end - - % ΠŸΡ€ΠΎΡ…ΠΎΠ΄ΠΈΠΌ ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ (ADC, TIM...) - periphs = fieldnames(config); - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - % Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ для модуля - tabCtrl = container.addDialogControl('tab', periph); - tabCtrl.Prompt = [periph ' Config']; - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - def = defines.(defPrompt); - prompt = def.Prompt; - - % Волько checkbox ΠΈ edit - switch lower(def.Type) - case 'checkbox' - paramType = 'checkbox'; - case 'edit' - paramType = 'edit'; - otherwise - continue; - end - - paramName = matlab.lang.makeValidName(defPrompt); - - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ - val = def.Default; - if islogical(val) - if val - valStr = 'on'; - else - valStr = 'off'; - end - elseif isnumeric(val) - valStr = num2str(val); - elseif ischar(val) - valStr = val; - else - error('Unsupported default value type for %s.%s', periph, defPrompt); - end - - % ДобавляСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ - param = mask.addParameter( ... - 'Type', paramType, ... - 'Prompt', prompt, ... - 'Name', paramName, ... - 'Value', valStr, ... - 'Container', periph ... - ); - - param.Alias = def.Def; - if def.NewRow - row_param = 'new'; - else - row_param = 'current'; - end - param.DialogControl.Row = row_param; - end - end - - % ВосстанавливаСм Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - restore_tables(blockPath, tableNames, columns_backup); - - % ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ маску, Ссли ΠΎΠ½Π° Π±Ρ‹Π»Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - if wasOpen - open_system(blockPath, 'mask'); - end -end - -function config = update_config_from_mask(blockPath, config) - blockPath = [blockPath '/MCU']; - mask = Simulink.Mask.get(blockPath); - - periphs = fieldnames(config); - - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - paramName = matlab.lang.makeValidName(defPrompt); - param = mask.getParameter(paramName); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· маски ΠΈ сохраняСм Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ - valStr = param.Value; - - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ строку Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ - if strcmpi(defines.(defPrompt).Type, 'checkbox') - config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on'); - elseif strcmpi(defines.(defPrompt).Type, 'edit') - valNum = str2double(valStr); - if isnan(valNum) - config.(periph).Defines.(defPrompt).Default = valStr; - else - config.(periph).Defines.(defPrompt).Default = valNum; - end - end - end - end -end - - -function clear_all_from_container(mask, containerName) - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - warning('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.', containerName); - return; - end - - % РСкурсивно ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ (Π½Π΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ) - paramsToDelete = collect_all_parameters(container); - - % УдаляСм всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ - for i = 1:numel(paramsToDelete) - try - mask.removeParameter(paramsToDelete{i}); - catch - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ %s', paramsToDelete{i}); - end - end - - % РСкурсивно ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ всС Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° - delete_all_tabs(mask, container); -end - -function params = collect_all_parameters(container) - params = {}; - children = container.DialogControls; - for i = 1:numel(children) - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Если Π²ΠΊΠ»Π°Π΄ΠΊΠ° β€” рСкурсивно собираСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Ρ‘ - params = [params, collect_all_parameters(ctrl)]; - else - % Π˜Π½Π°Ρ‡Π΅ это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” добавляСм имя - params{end+1} = ctrl.Name; %#ok - end - end -end - - - -function delete_all_tabs(mask, container) - children = container.DialogControls; - % Π˜Π΄Ρ‘ΠΌ Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ порядкС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ бСзопасно ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ - for i = numel(children):-1:1 - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Π‘Π½Π°Ρ‡Π°Π»Π° рСкурсивно удаляСм Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - delete_all_tabs(mask, ctrl); - try - container.removeDialogControl(ctrl.Name); - catch ME - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ %s: %s', ctrl.Name, ME.message); - end - end - end -end - - -function isOpen = isMaskDialogOpen(blockPath) - isOpen = false; - - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя Π±Π»ΠΎΠΊΠ° - blockName = get_param(blockPath, 'Name'); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список ΠΎΠΊΠΎΠ½ MATLAB GUI - jWindows = java.awt.Window.getWindows(); - - for i = 1:numel(jWindows) - win = jWindows(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, Ρ‡Ρ‚ΠΎ ΠΎΠΊΠ½ΠΎ Π²ΠΈΠ΄ΠΈΠΌΠΎΠ΅ ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ - if win.isShowing() - try - title = char(win.getTitle()); - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΌΡƒ слову, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΡƒ маски - if contains(title, ['Mask Editor: ' blockName]) || ... - contains(title, ['Mask: ' blockName]) || ... - contains(title, blockName) - isOpen = true; - return; - end - catch - % Окно Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° β€” пропускаСм - end - end - end - catch - isOpen = false; - end -end - - - -function column_titles = clear_tables(block, table_names) - % ΠžΡ‡ΠΈΡ‰Π°Π΅Ρ‚ столбцы Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ table_names - % Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ cell-массив с названиями ΠΏΠ΅Ρ€Π²Ρ‹Ρ… столбцов ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - % Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ cell-массив для хранСния Π½Π°Π·Π²Π°Π½ΠΈΠΉ столбцов - column_titles = cell(size(table_names)); - - for k = 1:numel(table_names) - table_name = table_names{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ количСство столбцов - nCols = tableControl.getNumberOfColumns; - - if nCols > 0 - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ) - column = tableControl.getColumn(1); - column_titles{k} = column.Name; - - % УдаляСм всС столбцы - % Π’Π°ΠΆΠ½ΠΎ: ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ столбцов индСксы ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, - % поэтому удаляСм всСгда ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц nCols Ρ€Π°Π· - for i = 1:nCols - tableControl.removeColumn(1); - end - else - % Если столбцов Π½Π΅Ρ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΏΡƒΡΡ‚ΡƒΡŽ строку - column_titles{k} = ''; - end - end -end - -function restore_tables(block, table_names, column_titles) - % ВосстанавливаСт ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ - % Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ массив column_titles для установки ΠΈΠΌΠ΅Π½ΠΈ столбца - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - for k = 1:numel(table_names) - table_name = table_names{k}; - title = column_titles{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ столбСц - column = tableControl.addColumn(Name='title', Type='edit'); - column.Name = title; - end -end - - - - -function tab = find_tab_by_name(controls, targetName) - tab = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π²ΠΊΠ»Π°Π΄ΠΊΠ° Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Tab') && strcmp(ctrl.Name, targetName) - tab = ctrl; - return; - end - - % Если это ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - tab = find_tab_by_name(children, targetName); - if ~isempty(tab) - return; - end - end - end -end - -function container = find_container_by_name(controls, targetName) - container = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Container') && strcmp(ctrl.Name, targetName) - container = ctrl; - return; - end - - % Если это Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - container = find_container_by_name(children, targetName); - if ~isempty(container) - return; - end - end - end -end - - -function children = get_children(ctrl) - if isprop(ctrl, 'DialogControls') - children = ctrl.DialogControls; - elseif isprop(ctrl, 'Controls') - children = ctrl.Controls; - elseif isprop(ctrl, 'Children') - children = ctrl.Children; - else - children = []; - end -end diff --git a/MCU_Wrapper/run_mex.bat b/MCU_Wrapper/run_mex.bat index 6cf6f4f..e59442c 100644 --- a/MCU_Wrapper/run_mex.bat +++ b/MCU_Wrapper/run_mex.bat @@ -11,33 +11,37 @@ :: %4 β€” Ρ€Π΅ΠΆΠΈΠΌ компиляции (debug/release) :: БохраняСм ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ -set includes_USER=%~1 -set code_USER=%~2 -set defines_USER=%~3 -set compil_mode=%~4 +set filename=%~1 +set includes_USER=%~2 +set code_USER=%~3 +set defines_USER=%~4 +set defines_CONFIG=%~5 +set compil_mode=%~6 :: ЗамСняСм __EQ__ Π½Π° = set defines_USER=%defines_USER:__EQ__==% +set defines_CONFIG=%defines_CONFIG:__EQ__==% set defines_WRAPPER=-D"MATLAB"^ -D"__sizeof_ptr=8" - :: -------------------------USERS PATHS AND CODE--------------------------- ::------------------------------------------------------------------------- -:: -----------------------MCU LIBRARIES & SIMULATOR------------------------ -:: -----MCU LIBRARIES STUFF---- -:: Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹ -set includes_MCU= -I".\MCU_STM32F1xx_Matlab"^ - -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK"^ - -I".\MCU_STM32F1xx_Matlab\Drivers\CMSIS"^ - -I".\MCU_STM32F1xx_Matlab\Drivers\CMSIS\Device\STM32F1xx"^ - -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Inc"^ - -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy" - -:: ΠΊΠΎΠ΄ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ МК, ΠΏΠ΅Ρ€Π΅Π΄Π΅Π»Π°Π½Π½Ρ‹ΠΉ для ΠΌΠ°Ρ‚Π»Π°Π± -set code_MCU= .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c^ +:: -------------------------WRAPPER PATHS AND CODE--------------------------- +:: ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ МК Π² симулинкС +set includes_WRAPPER=-I"."^ + -I".\MCU_Wrapper"^ + -I".\app_wrapper" + +set code_WRAPPER= .\MCU_Wrapper\MCU.c^ + .\MCU_Wrapper\mcu_wrapper.c^ + .\app_wrapper\app_init.c^ + .\app_wrapper\app_io.c^ + .\app_wrapper\app_wrapper.c + +:: PERIPH BAT START +set code_PERIPH=.\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c^ @@ -47,64 +51,56 @@ set code_MCU= .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c^ - .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c - -:: .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ramfunc.c^ -:: .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c^ -:: .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c^ -:: .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c^ - -:: --------MCU SIMULATOR------- -:: ΠΊΠΎΠ΄, которая Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΈΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ„ΠΈΡ€ΠΈΡŽ МК Π² симулинкС -set code_MCU_Sim= .\MCU_STM32F1xx_Matlab\stm32f1xx_matlab_conf.c^ + .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c^ + .\MCU_STM32F1xx_Matlab\stm32f1xx_matlab_conf.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK\stm32f1xx_matlab_gpio.c^ .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK\stm32f1xx_matlab_tim.c^ - .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK\stm32f1xx_periph_registers.c -::------------------------------------------------------------------------- + .\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK\stm32f1xx_periph_registers.c - -:: -------------------------WRAPPER PATHS AND CODE--------------------------- -:: ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ°, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ МК Π² симулинкС -set includes_WRAPPER= -I".\MCU_Wrapper" -set code_WRAPPER= .\MCU_Wrapper\MCU.c^ - .\MCU_Wrapper\mcu_wrapper.c^ - .\MCU_Wrapper\app_wrapper.c +set includes_PERIPH=-I".\MCU_STM32F1xx_Matlab"^ + -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_SIMULINK"^ + -I".\MCU_STM32F1xx_Matlab\Drivers\CMSIS"^ + -I".\MCU_STM32F1xx_Matlab\Drivers\CMSIS\Device\STM32F1xx"^ + -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Inc"^ + -I".\MCU_STM32F1xx_Matlab\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy" +:: PERIPH BAT END ::------------------------------------------------------------------------- :: ---------------------SET PARAMS FOR MEX COMPILING----------------------- -:: --------ALL INCLUDES-------- -set includes= %includes_USER% %includes_MCU% %includes_WRAPPER% -set codes= %code_WRAPPER% %code_USER% %code_MCU% %code_MCU_Sim% -set defines= %defines_USER% %defines_WRAPPER% +:: -------------ALL------------ +set includes= %includes_WRAPPER% %includes_PERIPH% %includes_USER% +set codes= %code_WRAPPER% %code_USER% %code_PERIPH% +set defines= %defines_WRAPPER% %defines_CONFIG% %defines_USER% :: -------OUTPUT FOLDER-------- -set output= -outdir "." +set output= -outdir "." -output %filename% -:: Ссли Π½ΡƒΠΆΠ΅Π½ Π΄Π΅Π±Π°Π³, Π΄ΠΎ запускаСм run mex с припиской debug -IF %compil_mode%==[debug] (set debug= -g) +:: Ссли Π½ΡƒΠΆΠ΅Π½ Π΄Π΅Π±Π°Π³, Π΄ΠΎ запускаСм run_mex с припиской debug +IF %compil_mode%==debug (set debug= -g) ::------------------------------------------------------------------------- ::------START COMPILING------- -if "%5"=="echo_enable" ( +if "%7"=="echo_enable" ( echo Compiling... echo =========================== - echo INCLUDES: + echo =========INCLUDES========== echo USER: for %%f in (%includes_USER%) do ( echo %%f ) echo INTERNAL: - for %%f in (%includes_MCU%) do ( + for %%f in (%includes_WRAPPER%) do ( echo %%f ) - for %%f in (%includes_WRAPPER%) do ( + echo PERIPH: + for %%f in (%includes_PERIPH%) do ( echo %%f ) echo =========================== - echo SOURCES: + echo ==========SOURCES========== echo USER: for %%f in (%code_USER%) do ( echo %%f @@ -113,19 +109,21 @@ if "%5"=="echo_enable" ( for %%f in (%code_WRAPPER%) do ( echo %%f ) - for %%f in (%code_MCU_Sim%) do ( - echo %%f - ) - for %%f in (%code_MCU%) do ( + echo PERIPH: + for %%f in (%code_PERIPH%) do ( echo %%f ) echo =========================== - echo DEFINES: + echo ==========DEFINES========== echo USER: for %%d in (%defines_USER%) do ( echo %%d ) + echo CONFIG: + for %%f in (%defines_CONFIG%) do ( + echo %%f + ) echo INTERNAL: for %%f in (%defines_WRAPPER%) do ( echo %%f @@ -134,6 +132,6 @@ if "%5"=="echo_enable" ( echo =========================== echo MODE: %compil_mode% echo =========================== - mex %output% %defines% %includes% %codes% %debug% -echo %DATE% %TIME% \ No newline at end of file +echo %DATE% %TIME% +exit /b %ERRORLEVEL% \ No newline at end of file diff --git a/app_wrapper/app_configs.h b/app_wrapper/app_configs.h new file mode 100644 index 0000000..e6b6b2e --- /dev/null +++ b/app_wrapper/app_configs.h @@ -0,0 +1,10 @@ +/** +************************************************************************** +* @file app_config.h +* @brief Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ. +**************************************************************************/ +#ifndef _APP_CONFIG +#define _APP_CONFIG + + +#endif //_APP_CONFIG diff --git a/app_wrapper/app_includes.h b/app_wrapper/app_includes.h new file mode 100644 index 0000000..d58ef24 --- /dev/null +++ b/app_wrapper/app_includes.h @@ -0,0 +1,17 @@ +/** +************************************************************************** +* @file app_includes.h +* @brief Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» для ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Π½ΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК. +**************************************************************************/ +#ifndef _APP_INCLUDES_H_ +#define _APP_INCLUDES_H_ + +#include "app_configs.h" + +// INCLUDES START +// Π˜Π½ΠΊΠ»ΡŽΠ΄Ρ‹ для доступа ΠΊ ΠΊΠΎΠ΄Ρƒ МК Π² ΠΊΠΎΠ΄Π΅ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠ΅ +#include "upp.h" +#include "main.h" +// INCLUDES END + +#endif //_APP_INCLUDES_H_ \ No newline at end of file diff --git a/app_wrapper/app_init.c b/app_wrapper/app_init.c new file mode 100644 index 0000000..2520f7f --- /dev/null +++ b/app_wrapper/app_init.c @@ -0,0 +1,38 @@ +/** +************************************************************************** +* @file app_init.h +* @brief Π€Π°ΠΉΠ» с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК @ref app_init. +**************************************************************************/ +#include "mcu_wrapper_conf.h" +#include "app_wrapper.h" + +/** + * @brief Ѐункция для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния МК + * @details Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² случаС симуляции Π±Π΅Π· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° для main(). + */ +void app_init(void) { +// USER APP INIT START +// Код для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния МК +// +// Π’Ρ‹Π·ΠΎΠ² Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π² случаС, +// Ссли Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ для main(). +HAL_Init(); +MX_GPIO_Init(); +MX_TIM2_Init(); +upp_init(); +// USER APP INIT END +} + + +/** + * @brief Ѐункция для Π΄Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния МК + */ +void app_deinit(void) { +// USER APP DEINIT START +// Код для Π΄Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ прилоТСния МК +// +// Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ Ρ‚Π°ΠΊ Π΄Π°Π»Π΅Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Π΄ΠΎ ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ, +// для ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ запуска симуляции. +deInitialize_MCU(); +// USER APP DEINIT END +} \ No newline at end of file diff --git a/app_wrapper/app_io.c b/app_wrapper/app_io.c new file mode 100644 index 0000000..d500615 --- /dev/null +++ b/app_wrapper/app_io.c @@ -0,0 +1,118 @@ +/** +************************************************************************** +* @file app_init.h +* @brief Π€Π°ΠΉΠ» с функциями записи Π²Ρ…ΠΎΠ΄ΠΎΠ²/Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ МК @ref app_init. +**************************************************************************/ +#include "mcu_wrapper_conf.h" +#include "app_wrapper.h" + +/** + * @brief Ѐункция для записи Π²Ρ…ΠΎΠ΄ΠΎΠ² Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ МК + * @param u - массив Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ + */ +void app_readInputs(const real_T* Buffer) { +// USER APP INPUT START +// Код для записи считывания Π²Ρ…ΠΎΠ΄ΠΎΠ² ΠΈΠ· IO Π±ΡƒΡ„Π΅Ρ€Π° +// Π‘ΡƒΡ„Π΅Ρ€ Π² Π½Π°Ρ‡Π°Π»Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠΎΡ€Ρ‚Ρ‹ S-Function, Π΄Π°Π»Π΅Π΅ ΠΈΠ΄ΡƒΡ‚ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠΎΡ€Ρ‚Ρ‹: +// Buffer[0:15] - Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ 1 ΠΏΠΎΡ€Ρ‚, Buffer[16:31] - Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ 2 ΠΏΠΎΡ€Ρ‚, +// Buffer[32:47] - Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ 1 ΠΏΠΎΡ€Ρ‚, Buffer[48:63] - Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ 2 ΠΏΠΎΡ€Ρ‚ +// +// Note: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ‚Π΅ для чтСния: +// val = ReadInputArray(arr_ind, val_ind) +// ΠŸΡ€ΠΈΠΌΠ΅Ρ€: +// // запись Π² Π²Ρ‚ΠΎΡ€ΠΎΠΉ элСмСнт ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ массива +// app_variable = ReadInputArray(0, 1); +// // Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· IO Π±ΡƒΡ„Π΅Ρ€Π° Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ +// app_variable_2 = Buffer[10]; + +#define detect_front(_in_numb_, _var_, _val_) { \ +if ((Buffer[_in_numb_] > 0.5) && (prev_in[_in_numb_] <= 0.5)) \ +{ \ + _var_ = _val_; \ +} } + +#define detect_rise(_in_numb_, _var_, _val_) { \ +if ((Buffer[_in_numb_] < 0.5) && (prev_in[_in_numb_] >= 0.5)) \ +{ \ + _var_ = _val_; \ +} } + + static real_T prev_in[TOTAL_IN_SIZE]; + + detect_front(0, phase_A.zc_detector.f.EXTIZeroCrossDetected, 1); + detect_rise(0, phase_A.zc_detector.f.EXTIZeroCrossDetected, 1); + + detect_front(1, phase_B.zc_detector.f.EXTIZeroCrossDetected, 1); + detect_rise(1, phase_B.zc_detector.f.EXTIZeroCrossDetected, 1); + + detect_front(2, phase_C.zc_detector.f.EXTIZeroCrossDetected, 1); + detect_rise(2, phase_C.zc_detector.f.EXTIZeroCrossDetected, 1); + + detect_front(3, Upp.GoSafe, 1); + detect_rise(3, Upp.GoSafe, 0); + + detect_front(4, Upp.Prepare, 1); + detect_rise(4, Upp.Prepare, 0); + + detect_front(5, Upp.ForceStop, 1); + detect_rise(5, Upp.ForceStop, 0); + + detect_front(6, Upp.ForceDisconnect, 1); + detect_rise(6, Upp.ForceDisconnect, 0); + + + Upp.sine_freq = Buffer[7]; + Upp.Duration = Buffer[8]; + + + for (int i = 0; i < TOTAL_IN_SIZE; i++) + { + prev_in[i] = Buffer[i]; + } +// USER APP INPUT END +} + +/** + * @brief Ѐункция для записи Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² прилоТСния МК + * @param xD - массив Π±ΡƒΡ„Ρ„Π΅Ρ€Π° Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ²(дискрСтных Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ²) + * @details Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ‚Π΅ WriteOutputArray(val, arr_ind, val_ind) для записи + */ +void app_writeOutputBuffer(real_T* Buffer) { +// USER APP OUTPUT START +// Код для записи Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠ² Π² IO Π±ΡƒΡ„Π΅Ρ€ +// Π‘ΡƒΡ„Π΅Ρ€ Π² Π½Π°Ρ‡Π°Π»Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠΎΡ€Ρ‚Ρ‹ S-Function, Π΄Π°Π»Π΅Π΅ ΠΈΠ΄ΡƒΡ‚ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠΎΡ€Ρ‚Ρ‹: +// Buffer[0:15] - Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ 1 ΠΏΠΎΡ€Ρ‚, Buffer[16:31] - Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ 2 ΠΏΠΎΡ€Ρ‚, +// Buffer[32:47] - Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ 1 ΠΏΠΎΡ€Ρ‚, Buffer[48:63] - Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ 2 ΠΏΠΎΡ€Ρ‚ +// +// Note: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ‚Π΅ для записи: +// WriteOutputArray(val, arr_ind, val_ind) +// ΠŸΡ€ΠΈΠΌΠ΅Ρ€: +// // запись Π² Π²Ρ‚ΠΎΡ€ΠΎΠΉ элСмСнт ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ массива +// WriteOutputArray(app_variable, 0, 1); +// // запись Π² IO Π±ΡƒΡ„Π΅Ρ€ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ +// Buffer[XD_OUTPUT_START + 10] = app_variable_2; + + + for (int i = 0; i < 16; i++) + { + if (GPIOA->ODR & (1 << i)) + { + WriteOutputArray(1, 0, i); + } + + if (GPIOB->ODR & (1 << i)) + { + WriteOutputArray(1, 1, i); + } + } + +int var = phase_A.ctrl.angle.delay_us; +WriteOutputArray(var, 2, 0); +var = (uint16_t)((uint16_t)TIMER->CNT - phase_A.ctrl.angle.start_delay_tick); +WriteOutputArray(var, 2, 1); +var = phase_A.ctrl.angle.start_delay_tick; +WriteOutputArray(var, 2, 2); +var = TIMER->CNT; +WriteOutputArray(var, 2, 3); +// USER APP OUTPUT END +} \ No newline at end of file diff --git a/app_wrapper/app_wrapper.c b/app_wrapper/app_wrapper.c new file mode 100644 index 0000000..b682334 --- /dev/null +++ b/app_wrapper/app_wrapper.c @@ -0,0 +1,27 @@ +#include "mcu_wrapper_conf.h" +#include "app_wrapper.h" + + +/** + * @brief Ѐункция для симуляции шага прилоТСния МК + * @details Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² случаС симуляции Π±Π΅Π· ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° для main(). + */ +void app_step(void) +{ +// USER APP STEP START +// Код прилоТСния МК для Π²Ρ‹Π·ΠΎΠ²Π° Π² шагС симуляции +// +// Π’Ρ‹Π·ΠΎΠ² Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½Π° шагС симуляции Π² случаС, +// Ссли Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ для main(). +//upp_main(); +// USER APP STEP END +} + + +// DUMMY START +// Π—Π°Π³Π»ΡƒΡˆΠΊΠΈ для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… + +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) {} +void SystemClock_Config(void) {} +void Error_Handler(void) {} +// DUMMY END \ No newline at end of file diff --git a/app_wrapper/app_wrapper.h b/app_wrapper/app_wrapper.h new file mode 100644 index 0000000..7a8022a --- /dev/null +++ b/app_wrapper/app_wrapper.h @@ -0,0 +1,12 @@ +#ifndef _APP_WRAPPER_H_ +#define _APP_WRAPPER_H_ + +#include "app_includes.h" + +void app_step(void); +void app_init(void); +void app_deinit(void); +void app_readInputs(const real_T* u); +void app_writeOutputBuffer(real_T* xD); + +#endif //_APP_WRAPPER_H_ diff --git a/mcu_test_r2023.slx b/mcu_test_r2023.slx index 68dd38e..16c4220 100644 Binary files a/mcu_test_r2023.slx and b/mcu_test_r2023.slx differ diff --git a/mexing.asv b/mexing.asv deleted file mode 100644 index 9284b7b..0000000 --- a/mexing.asv +++ /dev/null @@ -1,734 +0,0 @@ -% ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ S-function -function mexing(compile_mode) - global Ts - Ts = 0.00001; - - if compile_mode == 1 - delete("*.mexw64") - delete("*.mexw64.pdb") - delete(".\MCU_Wrapper\Outputs\*.*"); - set_param(gcb, 'consoleOutput', ''); - % Π”Π΅Ρ„Π°ΠΉΠ½Ρ‹ - definesWrapperArg = buildWrapperDefinesString(); - definesUserArg = parseDefinesMaskText(); - definesConfigArg = buildConfigDefinesString(); - definesAllArg = [definesUserArg + " " + definesWrapperArg + " " + definesConfigArg]; - - %Ρ€Π΅ΠΆΠΈΠΌΡ‹ компиляции - if read_checkbox('enableDebug') - modeArg = "debug"; - else - modeArg = "release"; - end - if read_checkbox('fullOutput') || read_checkbox('extConsol') - echoArg = 'echo_enable'; - else - echoArg = 'echo_disable'; - end - - [includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable'); - - % Π’Ρ‹Π·ΠΎΠ² Π±Π°Ρ‚Π½ΠΈΠΊΠ° с двумя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ: includes ΠΈ code - cmd = sprintf('.\\MCU_Wrapper\\run_mex.bat "%s" "%s" "%s" %s %s', includesArg, codeArg, definesAllArg, modeArg, echoArg); - - if read_checkbox('extConsol') - cmdout = runBatAndShowOutput(cmd); - else - [status, cmdout]= system(cmd); - end - - % Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ Π²Ρ‹Π²ΠΎΠ΄ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ маски с ΠΈΠΌΠ΅Π½Π΅ΠΌ 'consoleOutput' - set_param(gcb, 'consoleOutput', cmdout); - - beep - else - blockPath = bdroot; - config = read_periph_config(); - config = update_config_from_mask(blockPath, config); - write_periph_config(config); - update_mask_from_config(blockPath, config); - % set_param(gcb, 'consoleOutput', 'Peripheral configuration file loaded. Re-open Block Parameters'); - end -end - -%% COMPILE PARAMS - - -function [includesArg, codeArg] = make_mex_arguments(incTableName, srcTableame) -%MAKE_MEX_ARGUMENTS Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ строки Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для Π²Ρ‹Π·ΠΎΠ²Π° mex-компиляции Ρ‡Π΅Ρ€Π΅Π· Π±Π°Ρ‚Π½ΠΈΠΊ -% -% [includesArg, codeArg] = make_mex_arguments(includesCell, codeCell) -% -% Π’Ρ…ΠΎΠ΄: -% includesCell β€” ячСйковый массив ΠΏΡƒΡ‚Π΅ΠΉ ΠΊ дирСкториям include -% codeCell β€” ячСйковый массив исходных Ρ„Π°ΠΉΠ»ΠΎΠ² -% -% Π’Ρ‹Ρ…ΠΎΠ΄: -% includesArg β€” строка для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π² Π±Π°Ρ‚Π½ΠΈΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: "-I"inc1" -I"inc2"" -% codeArg β€” строка с исходниками, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: ""src1.c" "src2.cpp"" - - - % Π—Π΄Π΅ΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ получСния ΠΈΠ· маски Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ° (Π·Π°ΠΌΠ΅Π½ΠΈ ΠΏΠΎ своСму) - blockHandle = gcbh; % ΠΈΠ»ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈ Π½Π° Π½ΡƒΠΆΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ - - includesCell = parseCellString(get_param(blockHandle, incTableName)); - codeCell = parseCellString(get_param(blockHandle, srcTableame)); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΏΡƒΡ‚ΠΈ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΈ добавляСм -I - includesStr = strjoin(cellfun(@(f) ['-I"' f '"'], includesCell, 'UniformOutput', false), ' '); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠΌΠ΅Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ - codeStr = strjoin(cellfun(@(f) ['"' f '"'], codeCell, 'UniformOutput', false), ' '); - - % УдаляСм символ пСрСноса строки ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π» Π² ΠΊΠΎΠ½Ρ†Π΅, Ссли Π²Π΄Ρ€ΡƒΠ³ ΠΏΠΎΠΏΠ°Π» - codeStr = strtrim(codeStr); - includesStr = strtrim(includesStr); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ всю строку Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π°Ρ‚Π½ΠΈΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ понял - % includesArg = ['"' includesStr '"']; - % codeArg = ['"' codeStr '"']; - includesArg = includesStr; - codeArg = codeStr; - -end - - -function definesWrapperArg = buildWrapperDefinesString() - - definesWrapperArg = ''; - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableThreading', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableDeinit', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'threadCycles', 1); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'mcuClk', 1); -end - - -function definesUserArg = parseDefinesMaskText() - blockHandle = gcbh; - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues ΠΈ MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - - % ИндСкс ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° userDefs - idxUserDefs = find(strcmp(paramNames, 'userDefs')); - definesText = maskValues{idxUserDefs}; % ВСкст с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌΠΈ опрСдСлСниями - - % Π£Π±ΠΈΡ€Π°Π΅ΠΌ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½Ρ‹Π΅ символы \n ΠΈ \r - definesText = strrep(definesText, '\n', ' '); - definesText = strrep(definesText, '\r', ' '); - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ пСрСносам строк - lines = split(definesText, {'\n', '\r\n', '\r'}); - - parts = strings(1,0); % пустой массив строк - - for k = 1:numel(lines) - line = strtrim(lines{k}); - if isempty(line) - continue; - end - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ опрСдСлСния Π² строкС - tokens = split(line); - - for t = 1:numel(tokens) - token = strtrim(tokens{t}); - if isempty(token) - continue; - end - - eqIdx = strfind(token, '='); - if isempty(eqIdx) - % ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Π±Π΅Π· значСния - parts(end+1) = sprintf('-D"%s"', token); - else - key = strtrim(token(1:eqIdx(1)-1)); - val = strtrim(token(eqIdx(1)+1:end)); - parts(end+1) = sprintf('-D"%s__EQ__%s"', key, val); - end - end - end - - definesUserArg = strjoin(parts, ' '); -end - - - -function definesWrapperArg = buildConfigDefinesString() - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - tabName = 'configTabAll'; % Имя Π²ΠΊΠ»Π°Π΄ΠΊΠΈ (Prompt) - - allControls = mask.getDialogControls(); - tabCtrl = find_container_by_name(allControls, tabName); - - if isempty(tabCtrl) - error('Π’ΠΊΠ»Π°Π΄ΠΊΠ° с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° Π² маскС', tabName); - end - - collect_all_parameters - - definesWrapperArg = ''; - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ всС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - children = tabCtrl.DialogControls; - for i = 1:numel(children) - ctrl = children(i); - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΠ· ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π° - paramName = ctrl.Name; - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ - param = mask.getParameter(paramName); - - % ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ Ρ‚ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - switch lower(param.Type) - case 'checkbox' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 0); - case 'edit' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 1); - otherwise - % НСобрабатываСмыС Ρ‚ΠΈΠΏΡ‹ - end - catch ME - % warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ "%s": %s', paramName, ME.message); - end - end -end - - -%% PARSE FUNCTIONS - -function out = parseCellString(str) - str = strtrim(str); - if startsWith(str, '{') && endsWith(str, '}') - str = str(2:end-1); - end - - parts = split(str, ';'); - out = cell(numel(parts), 1); - for i = 1:numel(parts) - el = strtrim(parts{i}); - if startsWith(el, '''') && endsWith(el, '''') - el = el(2:end-1); - end - out{i} = el; - end - - if isempty(out) || (numel(out) == 1 && isempty(out{1})) - out = {}; - end -end - -function str = cellArrayToString(cellArray) - quoted = cellfun(@(s) ['''' s ''''], cellArray, 'UniformOutput', false); - str = ['{' strjoin(quoted, ';') '}']; -end - - -function definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, val_define) - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues, MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - param = mask.getParameter(paramName); % для alias - - % Найдём индСкс Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - idxParam = find(strcmp(paramNames, paramName), 1); - if isempty(idxParam) - error('Parameter "%s" not found in block mask parameters.', paramName); - end - - % Π‘Π΅Ρ€Ρ‘ΠΌ alias ΠΈΠ· маски - alias = param.Alias; - - if val_define ~= 0 - % Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - val = maskValues{idxParam}; - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ - newDefine = ['-D"' alias '__EQ__' val '"']; - else - if read_checkbox(paramName) - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ Π±Π΅Π· значСния - newDefine = ['-D"' alias '"']; - else - newDefine = ''; - end - end - - - - % ДобавляСм Π½ΠΎΠ²Ρ‹ΠΉ define ΠΊ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ (string) - if isempty(definesWrapperArg) || strlength(strtrim(definesWrapperArg)) == 0 - definesWrapperArg = newDefine; - else - definesWrapperArg = definesWrapperArg + " " + newDefine; - end -end - - - -function checkbox_state = read_checkbox(checkboxName) - maskValues = get_param(gcbh, 'MaskValues'); - paramNames = get_param(gcbh, 'MaskNames'); - - inxCheckBox = find(strcmp(paramNames, checkboxName)); - - checkbox_state_str = maskValues{inxCheckBox}; - if strcmpi(checkbox_state_str, 'on') - checkbox_state = 1; - else - checkbox_state = 0; - end -end - -%% CONSOLE FUNCTIONS - -function cmdret = runBatAndShowOutput(cmd) - import java.io.*; - import java.lang.*; - cmdEnglish = ['chcp 437 > nul && ' cmd]; - pb = java.lang.ProcessBuilder({'cmd.exe', '/c', cmdEnglish}); - pb.redirectErrorStream(true); - process = pb.start(); - - reader = BufferedReader(InputStreamReader(process.getInputStream())); - - cmdret = ""; % Π—Π΄Π΅ΡΡŒ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°Ρ‚ΡŒ вСсь Π²Ρ‹Π²ΠΎΠ΄ - - while true - if reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - % Π—Π΄Π΅ΡΡŒ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠ²ΡƒΡŽ строку - safeLine = strrep(line, '''', ''''''); % Π­ΠΊΡ€Π°Π½ΠΈΡ€ΡƒΠ΅ΠΌ апострофы - logWindow_append(safeLine); - drawnow; % обновляСм GUI - else - if ~process.isAlive() - % Π΄ΠΎΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ строки - while reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - safeLine = strrep(line, '''', ''''''); - logWindow_append(safeLine); - drawnow; - end - break; - end - pause(0.2); - end - end - process.waitFor(); -end - - -function logWindow_append(line) - persistent fig hEdit jScrollPane jTextArea - - if isempty(fig) || ~isvalid(fig) - fig = figure('Name', 'Log Window', 'Position', [100 100 600 400]); - hEdit = uicontrol('Style', 'edit', ... - 'Max', 2, 'Min', 0, ... - 'Enable', 'on', ... - 'FontName', 'Courier New', ... - 'Position', [10 10 580 380], ... - 'HorizontalAlignment', 'left', ... - 'BackgroundColor', 'white', ... - 'Tag', 'LogWindowFigure'); - - jScrollPane = findjobj(hEdit); % JScrollPane - jTextArea = jScrollPane.getViewport.getView; % JTextArea Π²Π½ΡƒΡ‚Ρ€ΠΈ JScrollPane - end - - oldText = get(hEdit, 'String'); - if ischar(oldText) - oldText = {oldText}; - end - - set(hEdit, 'String', [oldText; {line}]); - drawnow; - % Автоскролл Π²Π½ΠΈΠ·: - jTextArea.setCaretPosition(jTextArea.getDocument.getLength); - drawnow; -end - - -%% READ CONFIGS -function config = read_periph_config() - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - pathparam = mask.getParameter('periphPath'); - config_path = pathparam.Value; - - jsonText = fileread(config_path); - config = jsondecode(jsonText); -end - -function write_periph_config(config) - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - pathparam = mask.getParameter('periphPath'); - config_path = pathparam.Value; - - jsonText = jsonencode(config, 'PrettyPrint', true); - fid = fopen(config_path, 'w'); - if fid == -1 - error('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» periph_config.json для записи.'); - end - fwrite(fid, jsonText, 'char'); - fclose(fid); -end - -%% CONFIG MASK TOOLS -function update_mask_from_config(blockPath, config) - blockPath = [blockPath '/MCU']; - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π±Ρ‹Π»Π° Π»ΠΈ маска ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - wasOpen = isMaskDialogOpen(blockPath); - close_system(blockPath, 0); - mask = Simulink.Mask.get(blockPath); - - tableNames = {'incTable', 'srcTable'}; - columns_backup = clear_tables(blockPath, tableNames); - - containerName = 'configTabAll'; - clear_all_from_container(mask, containerName); - - % Π˜Ρ‰Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - error('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ Π² маскС.', containerName); - end - - % ΠŸΡ€ΠΎΡ…ΠΎΠ΄ΠΈΠΌ ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ (ADC, TIM...) - periphs = fieldnames(config); - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - % Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ для модуля - tabCtrl = container.addDialogControl('tab', periph); - tabCtrl.Prompt = [periph ' Config']; - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - def = defines.(defPrompt); - prompt = def.Prompt; - - % Волько checkbox ΠΈ edit - switch lower(def.Type) - case 'checkbox' - paramType = 'checkbox'; - case 'edit' - paramType = 'edit'; - otherwise - continue; - end - - paramName = matlab.lang.makeValidName(defPrompt); - - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ - val = def.Default; - if islogical(val) - if val - valStr = 'on'; - else - valStr = 'off'; - end - elseif isnumeric(val) - valStr = num2str(val); - elseif ischar(val) - valStr = val; - else - error('Unsupported default value type for %s.%s', periph, defPrompt); - end - - % ДобавляСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ - param = mask.addParameter( ... - 'Type', paramType, ... - 'Prompt', prompt, ... - 'Name', paramName, ... - 'Value', valStr, ... - 'Container', periph ... - ); - - param.Alias = def.Def; - if def.NewRow - row_param = 'new'; - else - row_param = 'current'; - end - param.DialogControl.Row = row_param; - end - end - - % ВосстанавливаСм Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - restore_tables(blockPath, tableNames, columns_backup); - - % ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ маску, Ссли ΠΎΠ½Π° Π±Ρ‹Π»Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - if wasOpen - open_system(blockPath, 'mask'); - end -end - -function config = update_config_from_mask(blockPath, config) - blockPath = [blockPath '/MCU']; - mask = Simulink.Mask.get(blockPath); - - periphs = fieldnames(config); - - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - paramName = matlab.lang.makeValidName(defPrompt); - param = mask.getParameter(paramName); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· маски ΠΈ сохраняСм Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ - valStr = param.Value; - - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ строку Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ - if strcmpi(defines.(defPrompt).Type, 'checkbox') - config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on'); - elseif strcmpi(defines.(defPrompt).Type, 'edit') - valNum = str2double(valStr); - if isnan(valNum) - config.(periph).Defines.(defPrompt).Default = valStr; - else - config.(periph).Defines.(defPrompt).Default = valNum; - end - end - end - end -end - - -function clear_all_from_container(mask, containerName) - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - warning('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.', containerName); - return; - end - - % РСкурсивно ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ (Π½Π΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ) - paramsToDelete = collect_all_parameters(container); - - % УдаляСм всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ - for i = 1:numel(paramsToDelete) - try - mask.removeParameter(paramsToDelete{i}); - catch - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ %s', paramsToDelete{i}); - end - end - - % РСкурсивно ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ всС Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° - delete_all_tabs(mask, container); -end - -function params = collect_all_parameters(container) - params = {}; - children = container.DialogControls; - for i = 1:numel(children) - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Если Π²ΠΊΠ»Π°Π΄ΠΊΠ° β€” рСкурсивно собираСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Ρ‘ - params = [params, collect_all_parameters(ctrl)]; - else - % Π˜Π½Π°Ρ‡Π΅ это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” добавляСм имя - params{end+1} = ctrl.Name; %#ok - end - end -end - - - -function delete_all_tabs(mask, container) - children = container.DialogControls; - % Π˜Π΄Ρ‘ΠΌ Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ порядкС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ бСзопасно ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ - for i = numel(children):-1:1 - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Π‘Π½Π°Ρ‡Π°Π»Π° рСкурсивно удаляСм Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - delete_all_tabs(mask, ctrl); - try - container.removeDialogControl(ctrl.Name); - catch ME - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ %s: %s', ctrl.Name, ME.message); - end - end - end -end - - -function isOpen = isMaskDialogOpen(blockPath) - isOpen = false; - - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя Π±Π»ΠΎΠΊΠ° - blockName = get_param(blockPath, 'Name'); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список ΠΎΠΊΠΎΠ½ MATLAB GUI - jWindows = java.awt.Window.getWindows(); - - for i = 1:numel(jWindows) - win = jWindows(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, Ρ‡Ρ‚ΠΎ ΠΎΠΊΠ½ΠΎ Π²ΠΈΠ΄ΠΈΠΌΠΎΠ΅ ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ - if win.isShowing() - try - title = char(win.getTitle()); - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΌΡƒ слову, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΡƒ маски - if contains(title, ['Mask Editor: ' blockName]) || ... - contains(title, ['Mask: ' blockName]) || ... - contains(title, blockName) - isOpen = true; - return; - end - catch - % Окно Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° β€” пропускаСм - end - end - end - catch - isOpen = false; - end -end - - - -function column_titles = clear_tables(block, table_names) - % ΠžΡ‡ΠΈΡ‰Π°Π΅Ρ‚ столбцы Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ table_names - % Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ cell-массив с названиями ΠΏΠ΅Ρ€Π²Ρ‹Ρ… столбцов ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - % Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ cell-массив для хранСния Π½Π°Π·Π²Π°Π½ΠΈΠΉ столбцов - column_titles = cell(size(table_names)); - - for k = 1:numel(table_names) - table_name = table_names{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ количСство столбцов - nCols = tableControl.getNumberOfColumns; - - if nCols > 0 - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ) - column = tableControl.getColumn(1); - column_titles{k} = column.Name; - - % УдаляСм всС столбцы - % Π’Π°ΠΆΠ½ΠΎ: ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ столбцов индСксы ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, - % поэтому удаляСм всСгда ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц nCols Ρ€Π°Π· - for i = 1:nCols - tableControl.removeColumn(1); - end - else - % Если столбцов Π½Π΅Ρ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΏΡƒΡΡ‚ΡƒΡŽ строку - column_titles{k} = ''; - end - end -end - -function restore_tables(block, table_names, column_titles) - % ВосстанавливаСт ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ - % Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ массив column_titles для установки ΠΈΠΌΠ΅Π½ΠΈ столбца - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - for k = 1:numel(table_names) - table_name = table_names{k}; - title = column_titles{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ столбСц - column = tableControl.addColumn(Name='title', Type='edit'); - column.Name = title; - end -end - - - - -function tab = find_tab_by_name(controls, targetName) - tab = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π²ΠΊΠ»Π°Π΄ΠΊΠ° Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Tab') && strcmp(ctrl.Name, targetName) - tab = ctrl; - return; - end - - % Если это ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - tab = find_tab_by_name(children, targetName); - if ~isempty(tab) - return; - end - end - end -end - -function container = find_container_by_name(controls, targetName) - container = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Container') && strcmp(ctrl.Name, targetName) - container = ctrl; - return; - end - - % Если это Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - container = find_container_by_name(children, targetName); - if ~isempty(container) - return; - end - end - end -end - - -function children = get_children(ctrl) - if isprop(ctrl, 'DialogControls') - children = ctrl.DialogControls; - elseif isprop(ctrl, 'Controls') - children = ctrl.Controls; - elseif isprop(ctrl, 'Children') - children = ctrl.Children; - else - children = []; - end -end diff --git a/mexing.m b/mexing.m deleted file mode 100644 index 0188a9d..0000000 --- a/mexing.m +++ /dev/null @@ -1,738 +0,0 @@ -% ΠšΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ S-function -function mexing(compile_mode) - global Ts - Ts = 0.00001; - - if compile_mode == 1 - delete("*.mexw64") - delete("*.mexw64.pdb") - delete(".\MCU_Wrapper\Outputs\*.*"); - set_param(gcb, 'consoleOutput', ''); - % Π”Π΅Ρ„Π°ΠΉΠ½Ρ‹ - definesWrapperArg = buildWrapperDefinesString(); - definesUserArg = parseDefinesMaskText(); - definesConfigArg = buildConfigDefinesString(); - definesAllArg = [definesUserArg + " " + definesWrapperArg + " " + definesConfigArg]; - - %Ρ€Π΅ΠΆΠΈΠΌΡ‹ компиляции - if read_checkbox('enableDebug') - modeArg = "debug"; - else - modeArg = "release"; - end - if read_checkbox('fullOutput') || read_checkbox('extConsol') - echoArg = 'echo_enable'; - else - echoArg = 'echo_disable'; - end - - [includesArg, codeArg] = make_mex_arguments('incTable', 'srcTable'); - - % Π’Ρ‹Π·ΠΎΠ² Π±Π°Ρ‚Π½ΠΈΠΊΠ° с двумя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ: includes ΠΈ code - cmd = sprintf('.\\MCU_Wrapper\\run_mex.bat "%s" "%s" "%s" %s %s', includesArg, codeArg, definesAllArg, modeArg, echoArg); - - if read_checkbox('extConsol') - cmdout = runBatAndShowOutput(cmd); - else - [status, cmdout]= system(cmd); - end - - % Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ Π²Ρ‹Π²ΠΎΠ΄ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ маски с ΠΈΠΌΠ΅Π½Π΅ΠΌ 'consoleOutput' - set_param(gcb, 'consoleOutput', cmdout); - - beep - else - blockPath = bdroot; - config = read_periph_config(); - config = update_config_from_mask(blockPath, config); - write_periph_config(config); - update_mask_from_config(blockPath, config); - % set_param(gcb, 'consoleOutput', 'Peripheral configuration file loaded. Re-open Block Parameters'); - end -end - -%% COMPILE PARAMS - - -function [includesArg, codeArg] = make_mex_arguments(incTableName, srcTableame) -%MAKE_MEX_ARGUMENTS Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ строки Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² для Π²Ρ‹Π·ΠΎΠ²Π° mex-компиляции Ρ‡Π΅Ρ€Π΅Π· Π±Π°Ρ‚Π½ΠΈΠΊ -% -% [includesArg, codeArg] = make_mex_arguments(includesCell, codeCell) -% -% Π’Ρ…ΠΎΠ΄: -% includesCell β€” ячСйковый массив ΠΏΡƒΡ‚Π΅ΠΉ ΠΊ дирСкториям include -% codeCell β€” ячСйковый массив исходных Ρ„Π°ΠΉΠ»ΠΎΠ² -% -% Π’Ρ‹Ρ…ΠΎΠ΄: -% includesArg β€” строка для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π² Π±Π°Ρ‚Π½ΠΈΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: "-I"inc1" -I"inc2"" -% codeArg β€” строка с исходниками, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€: ""src1.c" "src2.cpp"" - - - % Π—Π΄Π΅ΡΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ получСния ΠΈΠ· маски Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠ° (Π·Π°ΠΌΠ΅Π½ΠΈ ΠΏΠΎ своСму) - blockHandle = gcbh; % ΠΈΠ»ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈ Π½Π° Π½ΡƒΠΆΠ½Ρ‹ΠΉ Π±Π»ΠΎΠΊ - - includesCell = parseCellString(get_param(blockHandle, incTableName)); - codeCell = parseCellString(get_param(blockHandle, srcTableame)); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΏΡƒΡ‚ΠΈ Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ ΠΈ добавляСм -I - includesStr = strjoin(cellfun(@(f) ['-I"' f '"'], includesCell, 'UniformOutput', false), ' '); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ ΠΈΠΌΠ΅Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ - codeStr = strjoin(cellfun(@(f) ['"' f '"'], codeCell, 'UniformOutput', false), ' '); - - % УдаляСм символ пСрСноса строки ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π» Π² ΠΊΠΎΠ½Ρ†Π΅, Ссли Π²Π΄Ρ€ΡƒΠ³ ΠΏΠΎΠΏΠ°Π» - codeStr = strtrim(codeStr); - includesStr = strtrim(includesStr); - - % ΠžΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌ всю строку Π² ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π°Ρ‚Π½ΠΈΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ понял - % includesArg = ['"' includesStr '"']; - % codeArg = ['"' codeStr '"']; - includesArg = includesStr; - codeArg = codeStr; - -end - - -function definesWrapperArg = buildWrapperDefinesString() - - definesWrapperArg = ''; - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableThreading', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'enableDeinit', 0); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'threadCycles', 1); - definesWrapperArg = addDefineByParam(definesWrapperArg, 'mcuClk', 1); -end - - -function definesUserArg = parseDefinesMaskText() - blockHandle = gcbh; - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues ΠΈ MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - - % ИндСкс ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° userDefs - idxUserDefs = find(strcmp(paramNames, 'userDefs')); - definesText = maskValues{idxUserDefs}; % ВСкст с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌΠΈ опрСдСлСниями - - % Π£Π±ΠΈΡ€Π°Π΅ΠΌ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½Ρ‹Π΅ символы \n ΠΈ \r - definesText = strrep(definesText, '\n', ' '); - definesText = strrep(definesText, '\r', ' '); - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ пСрСносам строк - lines = split(definesText, {'\n', '\r\n', '\r'}); - - parts = strings(1,0); % пустой массив строк - - for k = 1:numel(lines) - line = strtrim(lines{k}); - if isempty(line) - continue; - end - - % Π Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ ΠΏΠΎ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ опрСдСлСния Π² строкС - tokens = split(line); - - for t = 1:numel(tokens) - token = strtrim(tokens{t}); - if isempty(token) - continue; - end - - eqIdx = strfind(token, '='); - if isempty(eqIdx) - % ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΊΠ»ΡŽΡ‡ Π±Π΅Π· значСния - parts(end+1) = sprintf('-D"%s"', token); - else - key = strtrim(token(1:eqIdx(1)-1)); - val = strtrim(token(eqIdx(1)+1:end)); - parts(end+1) = sprintf('-D"%s__EQ__%s"', key, val); - end - end - end - - definesUserArg = strjoin(parts, ' '); -end - - - -function definesWrapperArg = buildConfigDefinesString() - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - tabName = 'configTabAll'; % Имя Π²ΠΊΠ»Π°Π΄ΠΊΠΈ (Prompt) - - allControls = mask.getDialogControls(); - tabCtrl = find_container_by_name(allControls, tabName); - - if isempty(tabCtrl) - error('Π’ΠΊΠ»Π°Π΄ΠΊΠ° с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° Π² маскС', tabName); - end - - - params = collect_all_parameters(tabCtrl); - definesWrapperArg = ''; - for i = 1:numel(params) - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈΠ· ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π° - paramName = string(params(i)); - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ - param = mask.getParameter(paramName); - - % ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ Ρ‚ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - switch lower(param.Type) - case 'checkbox' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 0); - case 'edit' - definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, 1); - otherwise - % НСобрабатываСмыС Ρ‚ΠΈΠΏΡ‹ - end - catch ME - % warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ "%s": %s', paramName, ME.message); - end - end -end - - -%% PARSE FUNCTIONS - -function out = parseCellString(str) - str = strtrim(str); - if startsWith(str, '{') && endsWith(str, '}') - str = str(2:end-1); - end - - parts = split(str, ';'); - out = cell(numel(parts), 1); - for i = 1:numel(parts) - el = strtrim(parts{i}); - if startsWith(el, '''') && endsWith(el, '''') - el = el(2:end-1); - end - out{i} = el; - end - - if isempty(out) || (numel(out) == 1 && isempty(out{1})) - out = {}; - end -end - -function str = cellArrayToString(cellArray) - quoted = cellfun(@(s) ['''' s ''''], cellArray, 'UniformOutput', false); - str = ['{' strjoin(quoted, ';') '}']; -end - - -function definesWrapperArg = addDefineByParam(definesWrapperArg, paramName, val_define) - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ MaskValues, MaskNames - maskValues = get_param(blockHandle, 'MaskValues'); - paramNames = get_param(blockHandle, 'MaskNames'); - param = mask.getParameter(paramName); % для alias - - % Найдём индСкс Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - idxParam = find(strcmp(paramNames, paramName), 1); - if isempty(idxParam) - error('Parameter "%s" not found in block mask parameters.', paramName); - end - - % Π‘Π΅Ρ€Ρ‘ΠΌ alias ΠΈΠ· маски - alias = param.Alias; - - if val_define ~= 0 - % Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° - val = maskValues{idxParam}; - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ - newDefine = ['-D"' alias '__EQ__' val '"']; - else - if read_checkbox(paramName) - % Π€ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ define с ΠΊΠ°Π²Ρ‹Ρ‡ΠΊΠ°ΠΌΠΈ Π±Π΅Π· значСния - newDefine = ['-D"' alias '"']; - else - newDefine = ''; - end - end - - - - % ДобавляСм Π½ΠΎΠ²Ρ‹ΠΉ define ΠΊ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ (string) - if isempty(definesWrapperArg) || strlength(strtrim(definesWrapperArg)) == 0 - definesWrapperArg = newDefine; - else - definesWrapperArg = definesWrapperArg + " " + newDefine; - end -end - - - -function checkbox_state = read_checkbox(checkboxName) - maskValues = get_param(gcbh, 'MaskValues'); - paramNames = get_param(gcbh, 'MaskNames'); - - inxCheckBox = find(strcmp(paramNames, checkboxName)); - - checkbox_state_str = maskValues{inxCheckBox}; - if strcmpi(checkbox_state_str, 'on') - checkbox_state = 1; - else - checkbox_state = 0; - end -end - -%% CONSOLE FUNCTIONS - -function cmdret = runBatAndShowOutput(cmd) - import java.io.*; - import java.lang.*; - cmdEnglish = ['chcp 437 > nul && ' cmd]; - pb = java.lang.ProcessBuilder({'cmd.exe', '/c', cmdEnglish}); - pb.redirectErrorStream(true); - process = pb.start(); - - reader = BufferedReader(InputStreamReader(process.getInputStream())); - - cmdret = ""; % Π—Π΄Π΅ΡΡŒ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°Ρ‚ΡŒ вСсь Π²Ρ‹Π²ΠΎΠ΄ - - while true - if reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - % Π—Π΄Π΅ΡΡŒ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠ²ΡƒΡŽ строку - safeLine = strrep(line, '''', ''''''); % Π­ΠΊΡ€Π°Π½ΠΈΡ€ΡƒΠ΅ΠΌ апострофы - logWindow_append(safeLine); - drawnow; % обновляСм GUI - else - if ~process.isAlive() - % Π΄ΠΎΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ строки - while reader.ready() - line = char(reader.readLine()); - if isempty(line) - break; - end - cmdret = cmdret + string(line) + newline; % сохраняСм Π²Ρ‹Π²ΠΎΠ΄ - safeLine = strrep(line, '''', ''''''); - logWindow_append(safeLine); - drawnow; - end - break; - end - pause(0.2); - end - end - process.waitFor(); -end - - -function logWindow_append(line) - persistent fig hEdit jScrollPane jTextArea - - if isempty(fig) || ~isvalid(fig) - fig = figure('Name', 'Log Window', 'Position', [100 100 600 400]); - hEdit = uicontrol('Style', 'edit', ... - 'Max', 2, 'Min', 0, ... - 'Enable', 'on', ... - 'FontName', 'Courier New', ... - 'Position', [10 10 580 380], ... - 'HorizontalAlignment', 'left', ... - 'BackgroundColor', 'white', ... - 'Tag', 'LogWindowFigure'); - - jScrollPane = findjobj(hEdit); % JScrollPane - jTextArea = jScrollPane.getViewport.getView; % JTextArea Π²Π½ΡƒΡ‚Ρ€ΠΈ JScrollPane - end - - oldText = get(hEdit, 'String'); - if ischar(oldText) - oldText = {oldText}; - end - - set(hEdit, 'String', [oldText; {line}]); - drawnow; - % Автоскролл Π²Π½ΠΈΠ·: - jTextArea.setCaretPosition(jTextArea.getDocument.getLength); - drawnow; -end - - -%% READ CONFIGS -function config = read_periph_config() - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - pathparam = mask.getParameter('periphPath'); - config_path = pathparam.Value; - - jsonText = fileread(config_path); - config = jsondecode(jsonText); -end - -function write_periph_config(config) - blockHandle = gcbh; - mask = Simulink.Mask.get(blockHandle); - - pathparam = mask.getParameter('periphPath'); - config_path = pathparam.Value; - - jsonText = jsonencode(config, 'PrettyPrint', true); - fid = fopen(config_path, 'w'); - if fid == -1 - error('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» periph_config.json для записи.'); - end - fwrite(fid, jsonText, 'char'); - fclose(fid); -end - -%% CONFIG MASK TOOLS -function update_mask_from_config(blockPath, config) - blockPath = [blockPath '/MCU']; - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π±Ρ‹Π»Π° Π»ΠΈ маска ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - wasOpen = isMaskDialogOpen(blockPath); - close_system(blockPath, 0); - mask = Simulink.Mask.get(blockPath); - - tableNames = {'incTable', 'srcTable'}; - columns_backup = clear_tables(blockPath, tableNames); - - containerName = 'configTabAll'; - clear_all_from_container(mask, containerName); - - % Π˜Ρ‰Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - error('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ Π² маскС.', containerName); - end - - % ΠŸΡ€ΠΎΡ…ΠΎΠ΄ΠΈΠΌ ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ (ADC, TIM...) - periphs = fieldnames(config); - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - % Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ для модуля - tabCtrl = container.addDialogControl('tab', periph); - tabCtrl.Prompt = [periph ' Config']; - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - def = defines.(defPrompt); - prompt = def.Prompt; - - % Волько checkbox ΠΈ edit - switch lower(def.Type) - case 'checkbox' - paramType = 'checkbox'; - case 'edit' - paramType = 'edit'; - otherwise - continue; - end - - paramName = matlab.lang.makeValidName(defPrompt); - - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ Ρ‚ΠΈΠΏΡƒ - val = def.Default; - if islogical(val) - if val - valStr = 'on'; - else - valStr = 'off'; - end - elseif isnumeric(val) - valStr = num2str(val); - elseif ischar(val) - valStr = val; - else - error('Unsupported default value type for %s.%s', periph, defPrompt); - end - - % ДобавляСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ - param = mask.addParameter( ... - 'Type', paramType, ... - 'Prompt', prompt, ... - 'Name', paramName, ... - 'Value', valStr, ... - 'Container', periph ... - ); - - param.Alias = def.Def; - if def.NewRow - row_param = 'new'; - else - row_param = 'current'; - end - param.DialogControl.Row = row_param; - end - end - - % ВосстанавливаСм Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - restore_tables(blockPath, tableNames, columns_backup); - - % ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ маску, Ссли ΠΎΠ½Π° Π±Ρ‹Π»Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π° - if wasOpen - open_system(blockPath, 'mask'); - end -end - -function config = update_config_from_mask(blockPath, config) - blockPath = [blockPath '/MCU']; - mask = Simulink.Mask.get(blockPath); - maskParams = mask.Parameters; - paramNames = arrayfun(@(p) p.Name, maskParams, 'UniformOutput', false); - - periphs = fieldnames(config); - - for i = 1:numel(periphs) - periph = periphs{i}; - defines = config.(periph).Defines; - defNames = fieldnames(defines); - - for j = 1:numel(defNames) - defPrompt = defNames{j}; - paramName = matlab.lang.makeValidName(defPrompt); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, сущСствуСт Π»ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ с Ρ‚Π°ΠΊΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ - if ismember(paramName, paramNames) - param = mask.getParameter(paramName); - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· маски ΠΈ сохраняСм Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ - valStr = param.Value; - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, сущСствуСт Π»ΠΈ элСмСнт defPrompt Π² структурС defines - if isfield(defines, defPrompt) - % ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ строку Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ - if strcmpi(defines.(defPrompt).Type, 'checkbox') - config.(periph).Defines.(defPrompt).Default = strcmpi(valStr, 'on'); - elseif strcmpi(defines.(defPrompt).Type, 'edit') - valNum = str2double(valStr); - if isnan(valNum) - config.(periph).Defines.(defPrompt).Default = valStr; - else - config.(periph).Defines.(defPrompt).Default = valNum; - end - end - end - end - end - end -end - - -function clear_all_from_container(mask, containerName) - allControls = mask.getDialogControls(); - container = find_container_by_name(allControls, containerName); - if isempty(container) - warning('ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ "%s" Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½.', containerName); - return; - end - - % РСкурсивно ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ (Π½Π΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ) - paramsToDelete = collect_all_parameters(container); - - % УдаляСм всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ - for i = 1:numel(paramsToDelete) - try - mask.removeParameter(paramsToDelete{i}); - catch - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ %s', paramsToDelete{i}); - end - end - - % РСкурсивно ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ всС Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° - delete_all_tabs(mask, container); -end - -function params = collect_all_parameters(container) - params = {}; - children = container.DialogControls; - for i = 1:numel(children) - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Если Π²ΠΊΠ»Π°Π΄ΠΊΠ° β€” рСкурсивно собираСм ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Ρ‘ - params = [params, collect_all_parameters(ctrl)]; - else - % Π˜Π½Π°Ρ‡Π΅ это ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€” добавляСм имя - params{end+1} = ctrl.Name; %#ok - end - end -end - - - -function delete_all_tabs(mask, container) - children = container.DialogControls; - % Π˜Π΄Ρ‘ΠΌ Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ порядкС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ бСзопасно ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ - for i = numel(children):-1:1 - ctrl = children(i); - if isa(ctrl, 'Simulink.dialog.Tab') - % Π‘Π½Π°Ρ‡Π°Π»Π° рСкурсивно удаляСм Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ - delete_all_tabs(mask, ctrl); - try - container.removeDialogControl(ctrl.Name); - catch ME - warning('НС ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π²ΠΊΠ»Π°Π΄ΠΊΡƒ %s: %s', ctrl.Name, ME.message); - end - end - end -end - - -function isOpen = isMaskDialogOpen(blockPath) - isOpen = false; - - try - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ имя Π±Π»ΠΎΠΊΠ° - blockName = get_param(blockPath, 'Name'); - - % ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список ΠΎΠΊΠΎΠ½ MATLAB GUI - jWindows = java.awt.Window.getWindows(); - - for i = 1:numel(jWindows) - win = jWindows(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, Ρ‡Ρ‚ΠΎ ΠΎΠΊΠ½ΠΎ Π²ΠΈΠ΄ΠΈΠΌΠΎΠ΅ ΠΈ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ - if win.isShowing() - try - title = char(win.getTitle()); - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΌΡƒ слову, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΡƒ маски - if contains(title, ['Mask Editor: ' blockName]) || ... - contains(title, ['Mask: ' blockName]) || ... - contains(title, blockName) - isOpen = true; - return; - end - catch - % Окно Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° β€” пропускаСм - end - end - end - catch - isOpen = false; - end -end - - - -function column_titles = clear_tables(block, table_names) - % ΠžΡ‡ΠΈΡ‰Π°Π΅Ρ‚ столбцы Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ table_names - % Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ cell-массив с названиями ΠΏΠ΅Ρ€Π²Ρ‹Ρ… столбцов ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - % Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ cell-массив для хранСния Π½Π°Π·Π²Π°Π½ΠΈΠΉ столбцов - column_titles = cell(size(table_names)); - - for k = 1:numel(table_names) - table_name = table_names{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ количСство столбцов - nCols = tableControl.getNumberOfColumns; - - if nCols > 0 - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ) - column = tableControl.getColumn(1); - column_titles{k} = column.Name; - - % УдаляСм всС столбцы - % Π’Π°ΠΆΠ½ΠΎ: ΠΏΡ€ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΈ столбцов индСксы ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, - % поэтому удаляСм всСгда ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц nCols Ρ€Π°Π· - for i = 1:nCols - tableControl.removeColumn(1); - end - else - % Если столбцов Π½Π΅Ρ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΏΡƒΡΡ‚ΡƒΡŽ строку - column_titles{k} = ''; - end - end -end - -function restore_tables(block, table_names, column_titles) - % ВосстанавливаСт ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ столбСц Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈΠ· массива ΠΈΠΌΠ΅Π½ - % Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ массив column_titles для установки ΠΈΠΌΠ΅Π½ΠΈ столбца - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ маски Π±Π»ΠΎΠΊΠ° - maskObj = Simulink.Mask.get(block); - - for k = 1:numel(table_names) - table_name = table_names{k}; - title = column_titles{k}; - - % ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ управлСния Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ - tableControl = maskObj.getDialogControl(table_name); - - % Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ столбСц - column = tableControl.addColumn(Name='title', Type='edit'); - column.Name = title; - end -end - - - - -function tab = find_tab_by_name(controls, targetName) - tab = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π²ΠΊΠ»Π°Π΄ΠΊΠ° Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Tab') && strcmp(ctrl.Name, targetName) - tab = ctrl; - return; - end - - % Если это ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - tab = find_tab_by_name(children, targetName); - if ~isempty(tab) - return; - end - end - end -end - -function container = find_container_by_name(controls, targetName) - container = []; - - for i = 1:numel(controls) - ctrl = controls(i); - - % ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π»ΠΈ это ΠΈ совпадаСт Π»ΠΈ имя - if isa(ctrl, 'Simulink.dialog.Container') && strcmp(ctrl.Name, targetName) - container = ctrl; - return; - end - - % Если это Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» β€” ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ Π΄Π΅Ρ‚Π΅ΠΉ - children = get_children(ctrl); - if ~isempty(children) - container = find_container_by_name(children, targetName); - if ~isempty(container) - return; - end - end - end -end - - -function children = get_children(ctrl) - if isprop(ctrl, 'DialogControls') - children = ctrl.DialogControls; - elseif isprop(ctrl, 'Controls') - children = ctrl.Controls; - elseif isprop(ctrl, 'Children') - children = ctrl.Children; - else - children = []; - end -end diff --git a/periph_config.json b/periph_config.json deleted file mode 100644 index 768cae8..0000000 --- a/periph_config.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "RCC": { - "Defines": { - "HCLK_Clock": { - "Prompt": "HCLK Clock (Hz)", - "Def": "HCLK_Value", - "Type": "edit", - "Default": 7.2E+7, - "NewRow": true - }, - "ABP1_Clock": { - "Prompt": "ABP1 Clock (Hz)", - "Def": "ABP1_Value", - "Type": "edit", - "Default": 7.2E+7, - "NewRow": true - }, - "ABP1_TIMS_Clock": { - "Prompt": "ABP1 Tim's Clock (Hz)", - "Def": "ABP1_TIMS_Value", - "Type": "edit", - "Default": 7.2E+7, - "NewRow": true - }, - "ABP2_Clock": { - "Prompt": "ABP2 Clock (Hz)", - "Def": "ABP2_Value", - "Type": "edit", - "Default": 7.2E+7, - "NewRow": true - }, - "ABP2_TIMS_Clock": { - "Prompt": "ABP2 Tim's Clock (Hz)", - "Def": "ABP2_TIMS_Value", - "Type": "edit", - "Default": 7.2E+7, - "NewRow": true - } - } - }, - "TIM": { - "Defines": { - "TIM1_Enable": { - "Prompt": "TIM1 Enable", - "Def": "USE_TIM1", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM1_UP_TIM10_Handler": { - "Prompt": "TIM1_UP_TIM10 Handler", - "Def": "USE_TIM1_UP_TIM10_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM2_Enable": { - "Prompt": "TIM2 Enable", - "Def": "USE_TIM2", - "Type": "checkbox", - "Default": true, - "NewRow": true - }, - "TIM2_Handler": { - "Prompt": "TIM2 Handler", - "Def": "USE_TIM2_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM3_Enable": { - "Prompt": "TIM3 Enable", - "Def": "USE_TIM3", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM3_Handler": { - "Prompt": "TIM3 Handler", - "Def": "USE_TIM3_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM4_Enable": { - "Prompt": "TIM4 Enable", - "Def": "USE_TIM4", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM4_Handler": { - "Prompt": "TIM4 Handler", - "Def": "USE_TIM4_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM5_Enable": { - "Prompt": "TIM5 Enable", - "Def": "USE_TIM5", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM5_Handler": { - "Prompt": "TIM5 Handler", - "Def": "USE_TIM5_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM6_Enable": { - "Prompt": "TIM6 Enable", - "Def": "USE_TIM6", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM6_Handler": { - "Prompt": "TIM6 Handler", - "Def": "USE_TIM6_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM7_Enable": { - "Prompt": "TIM7 Enable", - "Def": "USE_TIM7", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM7_Handler": { - "Prompt": "TIM7 Handler", - "Def": "USE_TIM7_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM8_Enable": { - "Prompt": "TIM8 Enable", - "Def": "USE_TIM8", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM8_UP_TIM13_Handler": { - "Prompt": "TIM8_UP_TIM13 Handler", - "Def": "USE_TIM8_UP_TIM13_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM9_Enable": { - "Prompt": "TIM9 Enable", - "Def": "USE_TIM9", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM1_BRK_TIM9_Handler": { - "Prompt": "TIM1_BRK_TIM9 Handler", - "Def": "USE_TIM1_BRK_TIM9_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM10_Enable": { - "Prompt": "TIM10 Enable", - "Def": "USE_TIM10", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM11_Enable": { - "Prompt": "TIM11 Enable", - "Def": "USE_TIM11", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM1_TRG_COM_TIM11_Handler": { - "Prompt": "TIM1_TRG_COM_TIM11 Handler", - "Def": "USE_TIM1_TRG_COM_TIM11_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM12_Enable": { - "Prompt": "TIM12 Enable", - "Def": "USE_TIM12", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM8_BRK_TIM12_Handler": { - "Prompt": "TIM8_BRK_TIM12 Handler", - "Def": "USE_TIM8_BRK_TIM12_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - }, - "TIM13_Enable": { - "Prompt": "TIM13 Enable", - "Def": "USE_TIM13", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM14_Enable": { - "Prompt": "TIM14 Enable", - "Def": "USE_TIM14", - "Type": "checkbox", - "Default": false, - "NewRow": true - }, - "TIM8_TRG_COM_TIM14_Handler": { - "Prompt": "TIM8_TRG_COM_TIM14 Handler", - "Def": "USE_TIM8_TRG_COM_TIM14_HANDLER", - "Type": "checkbox", - "Default": false, - "NewRow": false - } - } - } - "ADC": { - "Defines": { - "ADC1_Enable": { - "Prompt": "ADC1 Enable", - "Def": "ADC1_ENABLE", - "Type": "checkbox", - "Default": true, - "NewRow": true - }, - "ADC2_Enable": { - "Prompt": "ADC2 Enable", - "Def": "ADC2_ENABLE", - "Type": "checkbox", - "Default": true, - "NewRow": true - }, - "Sample_Rate": { - "Prompt": "Sample Rate (Hz)", - "Def": "SAMPLE_RATE", - "Type": "edit", - "Default": 48000, - "NewRow": true - } - } - }, -} \ No newline at end of file