From a43d40cf52be45b0cd50c5737ad079a085a700d3 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 19 Sep 2022 16:10:27 +0000 Subject: [PATCH] Updated G4 dynamic SB demo. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15793 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../Makefile | 3 +- .../STM32G474xE_SB.ld | 12 +- .../cfg/halconf.h | 2 +- .../cfg/mcuconf.h | 6 +- .../cfg/sbconf.h | 2 +- .../cfg/vioconf.h | 49 +++++ ...ild-ch.elf)(OpenOCD, Flash and Run).launch | 4 +- ...1)(build-ch.elf)(OpenOCD, Just Run).launch | 4 +- ...ild-ch.elf)(OpenOCD, Flash and Run).launch | 2 +- .../main.c | 202 +++++++++++------- .../main.c | 3 - 11 files changed, 196 insertions(+), 93 deletions(-) create mode 100644 demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/vioconf.h diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/Makefile b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/Makefile index 9b846ed95..e66bd661b 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/Makefile +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/Makefile @@ -110,9 +110,10 @@ include $(CHIBIOS)/os/rt/rt.mk include $(CHIBIOS)/os/common/ports/ARMv7-M-ALT/compilers/GCC/mk/port.mk # SB files (optional). include $(CHIBIOS)/os/sb/host/compilers/GCC/sbhost.mk -#include $(CHIBIOS)/os/sb/vio/sbvio.mk +include $(CHIBIOS)/os/sb/vio/sbvio.mk # VFS files (optional). include $(CHIBIOS)/os/vfs/vfs.mk +#include $(CHIBIOS)/os/vfs/vfs_syscalls.mk # Auto-build files in ./source recursively. include $(CHIBIOS)/tools/mk/autobuild.mk # Other files (optional). diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/STM32G474xE_SB.ld b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/STM32G474xE_SB.ld index 0d4fee4a7..3191b9a1b 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/STM32G474xE_SB.ld +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/STM32G474xE_SB.ld @@ -19,17 +19,17 @@ */ MEMORY { - flash0 (rx) : org = 0x08000000, len = 512k - 64k /* Host code. */ - flash1 (rx) : org = 0x08070000, len = 32k /* Sandbox 1 code. */ - flash2 (rx) : org = 0x08078000, len = 32k /* Sandbox 2 code. */ + flash0 (rx) : org = 0x08000000, len = 512k - 256k /* Host code. */ + flash1 (rx) : org = 0x08040000, len = 128k /* Sandbox 1 code. */ + flash2 (rx) : org = 0x08060000, len = 128k /* Sandbox 2 code. */ flash3 (rx) : org = 0x00000000, len = 0 flash4 (rx) : org = 0x00000000, len = 0 flash5 (rx) : org = 0x00000000, len = 0 flash6 (rx) : org = 0x00000000, len = 0 flash7 (rx) : org = 0x00000000, len = 0 - ram0 (wx) : org = 0x20000000, len = 128k - 8k /* Host data. */ - ram1 (wx) : org = 0x2001E000, len = 4k /* Sandbox 1 data. */ - ram2 (wx) : org = 0x2001F000, len = 4k /* Sandbox 2 data. */ + ram0 (wx) : org = 0x20000000, len = 128k - 32k /* Host data. */ + ram1 (wx) : org = 0x20018000, len = 16k /* Sandbox 1 data. */ + ram2 (wx) : org = 0x2001C000, len = 16k /* Sandbox 2 data. */ ram3 (wx) : org = 0x00000000, len = 0 ram4 (wx) : org = 0x00000000, len = 0 ram5 (wx) : org = 0x00000000, len = 0 diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/halconf.h b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/halconf.h index 9ab717737..1a39abf0e 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/halconf.h +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/halconf.h @@ -156,7 +156,7 @@ * @brief Enables the SIO subsystem. */ #if !defined(HAL_USE_SIO) || defined(__DOXYGEN__) -#define HAL_USE_SIO FALSE +#define HAL_USE_SIO TRUE #endif /** diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/mcuconf.h b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/mcuconf.h index 77996c2dc..54b6ac6b2 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/mcuconf.h +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/mcuconf.h @@ -304,12 +304,12 @@ /* * SERIAL driver system settings. */ -#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART1 TRUE #define STM32_SERIAL_USE_USART2 FALSE #define STM32_SERIAL_USE_USART3 FALSE #define STM32_SERIAL_USE_UART4 FALSE #define STM32_SERIAL_USE_UART5 FALSE -#define STM32_SERIAL_USE_LPUART1 TRUE +#define STM32_SERIAL_USE_LPUART1 FALSE /* * SIO driver system settings. @@ -319,7 +319,7 @@ #define STM32_SIO_USE_USART3 FALSE #define STM32_SIO_USE_UART4 FALSE #define STM32_SIO_USE_UART5 FALSE -#define STM32_SIO_USE_LPUART1 FALSE +#define STM32_SIO_USE_LPUART1 TRUE /* * SPI driver system settings. diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/sbconf.h b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/sbconf.h index a096656ec..205745ade 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/sbconf.h +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/sbconf.h @@ -56,7 +56,7 @@ * @brief Enables support for sandbox virtualized I/O. */ #if !defined(SB_CFG_ENABLE_VIO) || defined(__DOXYGEN__) -#define SB_CFG_ENABLE_VIO FALSE +#define SB_CFG_ENABLE_VIO TRUE #endif /** diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/vioconf.h b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/vioconf.h new file mode 100644 index 000000000..638fb2bcb --- /dev/null +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/cfg/vioconf.h @@ -0,0 +1,49 @@ +/* + ChibiOS - Copyright (C) 2006..2022 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file templates/vioconf.h + * @brief VIO configuration header. + * @details VIO configuration file, this file allows to enable or disable the + * various virtual peripherals from your application. + * + * @addtogroup VIO_CONF + * @{ + */ + +#ifndef VIOCONF_H +#define VIOCONF_H + +#define __CHIBIOS_VIO_CONF__ +#define __CHIBIOS_VIO_CONF_VER_1_0__ + +/** + * @brief Enables the Virtual GPIO support. + */ +#if !defined(VIO_CFG_ENABLE_GPIO) || defined(__DOXYGEN__) +#define VIO_CFG_ENABLE_GPIO TRUE +#endif + +/** + * @brief Enables the Virtual UART support. + */ +#if !defined(VIO_CFG_ENABLE_UART) || defined(__DOXYGEN__) +#define VIO_CFG_ENABLE_UART TRUE +#endif + +#endif /* VIOCONF_H */ + +/** @} */ diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Flash and Run).launch b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Flash and Run).launch index c842b659c..4727e366c 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Flash and Run).launch +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Flash and Run).launch @@ -6,7 +6,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Just Run).launch b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Just Run).launch index db0c100f9..5d335341d 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Just Run).launch +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (SB1)(build-ch.elf)(OpenOCD, Just Run).launch @@ -16,7 +16,7 @@ - + @@ -43,4 +43,6 @@ + + diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (build-ch.elf)(OpenOCD, Flash and Run).launch b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (build-ch.elf)(OpenOCD, Flash and Run).launch index 1cb0df43d..f890f038b 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (build-ch.elf)(OpenOCD, Flash and Run).launch +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/debug/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC (build-ch.elf)(OpenOCD, Flash and Run).launch @@ -6,7 +6,7 @@ - + diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/main.c b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/main.c index ca267d47d..0a253447a 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/main.c +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_DYNAMIC/main.c @@ -19,13 +19,72 @@ #include "sb.h" #include "chprintf.h" -#include "rt_test_root.h" -#include "oslib_test_root.h" - #include "nullstreams.h" #include "startup_defs.h" + +/* Sandbox objects.*/ +sb_class_t sbx1, sbx2; + +/*===========================================================================*/ +/* VHAL-related. */ +/*===========================================================================*/ + +static vio_gpio_units_t gpio_units1 = { + .n = 1U, + .units = { + [0] = { + .permissions = VIO_GPIO_PERM_WRITE, + .port = GPIOA, + .mask = 1U, + .offset = GPIOA_LED_GREEN + } + } +}; + +static vio_uart_units_t uart_units1 = { + .n = 1U, + .units = { + [0] = { + .siop = &LPSIOD1, + .vrqsb = &sbx1, + .vrqn = 8 + } + } +}; + +static vio_uart_configs_t uart_configs1 = { + .n = 1U, + .cfgs = { + [0] = {NULL} + } +}; + +static vio_conf_t vio_config1 = { + .gpios = &gpio_units1, + .uarts = &uart_units1, + .uartconfs = &uart_configs1 +}; + +static vio_gpio_units_t gpio_units2 = { + .n = 0U +}; + +static vio_uart_units_t uart_units2 = { + .n = 0U +}; + +static vio_uart_configs_t uart_configs2 = { + .n = 0U +}; + +static vio_conf_t vio_config2 = { + .gpios = &gpio_units2, + .uarts = &uart_units2, + .uartconfs = &uart_configs2 +}; + /*===========================================================================*/ /* VFS-related. */ /*===========================================================================*/ @@ -49,7 +108,7 @@ static NullStream nullstream; /* Stream to be exposed under /dev as files.*/ static const drv_streams_element_t streams[] = { - {"VSD1", (BaseSequentialStream *)&LPSD1}, + {"VSD1", (BaseSequentialStream *)&SD1}, {"null", (BaseSequentialStream *)&nullstream}, {NULL, NULL} }; @@ -78,16 +137,18 @@ static const sb_config_t sb_config1 = { [0] = { (uint32_t)STARTUP_FLASH1_BASE, MPU_RASR_ATTR_AP_RO_RO | MPU_RASR_ATTR_CACHEABLE_WT_NWA | - MPU_RASR_SIZE_32K | + MPU_RASR_SIZE_128K | MPU_RASR_ENABLE }, [1] = { (uint32_t)STARTUP_RAM1_BASE, MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_CACHEABLE_WB_WA | - MPU_RASR_SIZE_4K | + MPU_RASR_SIZE_16K | MPU_RASR_ENABLE } }, + .vfs_driver = NULL, + .vioconf = &vio_config1 }; /* Sandbox 2 configuration.*/ @@ -110,16 +171,18 @@ static const sb_config_t sb_config2 = { [0] = { (uint32_t)STARTUP_FLASH2_BASE, MPU_RASR_ATTR_AP_RO_RO | MPU_RASR_ATTR_CACHEABLE_WT_NWA | - MPU_RASR_SIZE_32K | + MPU_RASR_SIZE_128K | MPU_RASR_ENABLE }, [1] = { (uint32_t)STARTUP_RAM2_BASE, MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_CACHEABLE_WB_WA | - MPU_RASR_SIZE_4K | + MPU_RASR_SIZE_16K | MPU_RASR_ENABLE } }, + .vfs_driver = (vfs_driver_c *)&root_overlay_driver, + .vioconf = &vio_config2 }; static const char *sbx1_argv[] = { @@ -140,9 +203,6 @@ static const char *sbx2_envp[] = { NULL }; -/* Sandbox objects.*/ -sb_class_t sbx1, sbx2; - static THD_WORKING_AREA(waUnprivileged1, 512); static THD_WORKING_AREA(waUnprivileged2, 512); @@ -150,18 +210,57 @@ static THD_WORKING_AREA(waUnprivileged2, 512); /* Main and generic code. */ /*===========================================================================*/ +static void start_sb1(void) { + thread_t *utp; + + /* Starting sandboxed thread 1.*/ + utp = sbStartThread(&sbx1, "sbx1", + waUnprivileged1, sizeof (waUnprivileged1), + NORMALPRIO - 1, sbx1_argv, sbx1_envp); + if (utp == NULL) { + chSysHalt("sbx1 failed"); + } +} + +static void start_sb2(void) { + thread_t *utp; + msg_t ret; + vfs_node_c *np; + + /* + * Associating standard input, output and error to sandbox 2.*/ + ret = vfsOpen("/dev/VSD1", 0, &np); + if (CH_RET_IS_ERROR(ret)) { + chSysHalt("VFS"); + } + sbRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); + sbRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); + vfsClose(np); + + /* Starting sandboxed thread 2.*/ + utp = sbStartThread(&sbx2, "sbx2", + waUnprivileged2, sizeof (waUnprivileged2), + NORMALPRIO - 2, sbx2_argv, sbx2_envp); + if (utp == NULL) { + chSysHalt("sbx2 failed"); + } +} + /* - * Green LED blinker thread, times are in milliseconds. + * Messenger thread, times are in milliseconds. */ static THD_WORKING_AREA(waThread1, 256); static THD_FUNCTION(Thread1, arg) { + unsigned i = 1U; (void)arg; - chRegSetThreadName("blinker"); + chRegSetThreadName("messenger"); while (true) { - palToggleLine(LINE_LED_GREEN); chThdSleepMilliseconds(500); + // sbSendMessage(&sbx2, (msg_t)i); + i++; } } @@ -169,10 +268,8 @@ static THD_FUNCTION(Thread1, arg) { * Application entry point. */ int main(void) { - unsigned i = 1U; - thread_t *utp1, *utp2; +// unsigned i = 1U; event_listener_t el1; - vfs_node_c *np; msg_t ret; /* @@ -192,11 +289,11 @@ int main(void) { /* * Starting a serial port for I/O, initializing other streams too. */ - sdStart(&LPSD1, NULL); + sdStart(&SD1, NULL); nullObjectInit(&nullstream); /* - * Creating a blinker thread. + * Creating a messenger thread. */ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO+10, Thread1, NULL); @@ -218,37 +315,9 @@ int main(void) { sbObjectInit(&sbx1, &sb_config1); sbObjectInit(&sbx2, &sb_config2); - /* - * Associating standard input, output and error to sandboxes. Both sandboxes - * use the same serial port in this setup. - */ - ret = vfsOpen("/dev/VSD1", 0, &np); - if (CH_RET_IS_ERROR(ret)) { - chSysHalt("VFS"); - } - sbRegisterDescriptor(&sbx1, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); - sbRegisterDescriptor(&sbx1, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); - sbRegisterDescriptor(&sbx1, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); - sbRegisterDescriptor(&sbx2, STDIN_FILENO, (vfs_node_c *)roAddRef(np)); - sbRegisterDescriptor(&sbx2, STDOUT_FILENO, (vfs_node_c *)roAddRef(np)); - sbRegisterDescriptor(&sbx2, STDERR_FILENO, (vfs_node_c *)roAddRef(np)); - vfsClose(np); - - /* Starting sandboxed thread 1.*/ - utp1 = sbStartThread(&sbx1, "sbx1", - waUnprivileged1, sizeof (waUnprivileged1), - NORMALPRIO - 1, sbx1_argv, sbx1_envp); - if (utp1 == NULL) { - chSysHalt("sbx1 failed"); - } - - /* Starting sandboxed thread 2.*/ - utp2 = sbStartThread(&sbx2, "sbx2", - waUnprivileged2, sizeof (waUnprivileged2), - NORMALPRIO - 1, sbx2_argv, sbx2_envp); - if (utp1 == NULL) { - chSysHalt("sbx2 failed"); - } + /* Starting sandboxed threads.*/ + start_sb1(); + start_sb2(); /* * Listening to sandbox events. @@ -256,39 +325,24 @@ int main(void) { chEvtRegister(&sb.termination_es, &el1, (eventid_t)0); /* - * Normal main() thread activity, in this demo it monitors the user button - * and checks for sandboxes state. + * Normal main() thread activity, in this demo it checks for sandboxes state. */ while (true) { - /* Checking for user button, launching test suite if pressed.*/ - if (palReadLine(LINE_BUTTON)) { - test_execute((BaseSequentialStream *)&LPSD1, &rt_test_suite); - test_execute((BaseSequentialStream *)&LPSD1, &oslib_test_suite); - } - /* Waiting for a sandbox event or timeout.*/ if (chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)) != (eventmask_t)0) { - if (chThdTerminatedX(utp1)) { - chprintf((BaseSequentialStream *)&LPSD1, "SB1 terminated\r\n"); + if (!sbIsThreadRunningX(&sbx1)) { + chprintf((BaseSequentialStream *)&SD1, "SB1 terminated\r\n"); + chThdSleepMilliseconds(100); + start_sb1(); } - if (chThdTerminatedX(utp2)) { - chprintf((BaseSequentialStream *)&LPSD1, "SB2 terminated\r\n"); + if (!sbIsThreadRunningX(&sbx2)) { + chprintf((BaseSequentialStream *)&SD1, "SB2 terminated\r\n"); + chThdSleepMilliseconds(100); + start_sb2(); } } - - if ((i & 1) == 0U) { - if (!chThdTerminatedX(utp1)) { - (void) sbSendMessageTimeout(&sbx1, (msg_t)i, TIME_MS2I(10)); - } - } - else { - if (!chThdTerminatedX(utp2)) { - (void) sbSendMessageTimeout(&sbx2, (msg_t)i, TIME_MS2I(10)); - } - } - i++; } } diff --git a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c index cc022fadc..1f8a563ec 100644 --- a/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c +++ b/demos/STM32/RT-STM32G474RE-NUCLEO64-SB_HOST_STATIC/main.c @@ -19,9 +19,6 @@ #include "sb.h" #include "chprintf.h" -#include "rt_test_root.h" -#include "oslib_test_root.h" - #include "nullstreams.h" #include "startup_defs.h"