Skip to main content
Glama
apolosan

Design Patterns MCP Server

by apolosan
embedded-systems-patterns.json29.7 kB
{ "patterns": [ { "id": "state-machine", "name": "State Machine", "category": "Embedded Systems", "description": "Manages system behavior through discrete states and transitions, fundamental to embedded systems for handling complex logic flows", "when_to_use": "Complex system behavior with multiple operating modes\nEvent-driven systems requiring predictable responses\nResource-constrained environments needing deterministic behavior\nSystems with clear state boundaries and transitions", "benefits": "Predictable behavior\nEasier debugging and testing\nClear system state visibility\nReduced complexity in large systems", "drawbacks": "Can become complex with many states\nState explosion in large systems\nRequires careful transition design\nMay need different implementations for different constraints", "use_cases": "Device control systems\nCommunication protocol handlers\nUser interface state management\nProcess control systems\nReal-time system event handling", "complexity": "Medium", "tags": ["embedded", "state-management", "event-driven", "deterministic", "real-time"], "examples": { "c": { "language": "c", "code": "typedef enum {\n STATE_IDLE,\n STATE_RUNNING,\n STATE_ERROR,\n STATE_SHUTDOWN\n} SystemState;\n\nSystemState current_state = STATE_IDLE;\n\nvoid state_machine_update(Event event) {\n switch (current_state) {\n case STATE_IDLE:\n if (event == EVENT_START) {\n current_state = STATE_RUNNING;\n start_system();\n }\n break;\n \n case STATE_RUNNING:\n if (event == EVENT_STOP) {\n current_state = STATE_SHUTDOWN;\n stop_system();\n } else if (event == EVENT_ERROR) {\n current_state = STATE_ERROR;\n handle_error();\n }\n break;\n \n case STATE_ERROR:\n if (event == EVENT_RESET) {\n current_state = STATE_IDLE;\n reset_system();\n }\n break;\n \n case STATE_SHUTDOWN:\n // Terminal state\n break;\n }\n}" }, "typescript": { "language": "typescript", "code": "enum DeviceState {\n OFF = 'off',\n STARTING = 'starting',\n RUNNING = 'running',\n ERROR = 'error'\n}\n\nclass DeviceStateMachine {\n private state: DeviceState = DeviceState.OFF;\n \n transition(event: string): void {\n switch (this.state) {\n case DeviceState.OFF:\n if (event === 'power_on') {\n this.state = DeviceState.STARTING;\n this.initializeDevice();\n }\n break;\n \n case DeviceState.STARTING:\n if (event === 'initialized') {\n this.state = DeviceState.RUNNING;\n this.startOperation();\n } else if (event === 'error') {\n this.state = DeviceState.ERROR;\n this.handleError();\n }\n break;\n \n case DeviceState.RUNNING:\n if (event === 'power_off') {\n this.state = DeviceState.OFF;\n this.shutdownDevice();\n }\n break;\n \n case DeviceState.ERROR:\n if (event === 'reset') {\n this.state = DeviceState.OFF;\n this.resetDevice();\n }\n break;\n }\n }\n \n private initializeDevice(): void {\n console.log('Initializing device...');\n }\n \n private startOperation(): void {\n console.log('Device running');\n }\n \n private shutdownDevice(): void {\n console.log('Shutting down device');\n }\n \n private handleError(): void {\n console.log('Error occurred');\n }\n \n private resetDevice(): void {\n console.log('Resetting device');\n }\n}" } } }, { "id": "table-driven-state-machine", "name": "Table-Driven State Machine", "category": "Embedded Systems", "description": "Implements state machines using data tables for transitions and actions, separating logic from data for easier maintenance and modification", "when_to_use": "Complex state machines with many states and transitions\nSystems requiring runtime reconfiguration\nEmbedded systems with limited code space\nWhen state logic needs to be easily modifiable without code changes", "benefits": "Separation of logic and data\nEasier to modify and extend\nReduced code duplication\nBetter testability\nCompact representation", "drawbacks": "Table maintenance complexity\nDebugging can be harder\nMemory overhead for tables\nLimited expressiveness compared to code", "use_cases": "Protocol parsers\nDevice state management\nUser interface workflows\nCommunication state machines\nProcess control systems", "complexity": "Medium", "tags": ["embedded", "state-machine", "table-driven", "data-driven", "configurable"], "examples": { "c": { "language": "c", "code": "typedef enum {\n STATE_INIT,\n STATE_READY,\n STATE_BUSY,\n STATE_ERROR\n} State;\n\ntypedef enum {\n EVENT_START,\n EVENT_PROCESS,\n EVENT_COMPLETE,\n EVENT_FAIL\n} Event;\n\ntypedef void (*ActionFunc)(void);\n\ntypedef struct {\n State next_state;\n ActionFunc action;\n} Transition;\n\n// State transition table\nTransition state_table[4][4] = {\n // EVENT_START, EVENT_PROCESS, EVENT_COMPLETE, EVENT_FAIL\n { {STATE_READY, init_action}, {STATE_INIT, NULL}, {STATE_INIT, NULL}, {STATE_INIT, NULL} }, // STATE_INIT\n { {STATE_READY, NULL}, {STATE_BUSY, start_process}, {STATE_READY, NULL}, {STATE_READY, NULL} }, // STATE_READY\n { {STATE_BUSY, NULL}, {STATE_BUSY, NULL}, {STATE_READY, complete_process}, {STATE_ERROR, handle_error} }, // STATE_BUSY\n { {STATE_INIT, reset_system}, {STATE_ERROR, NULL}, {STATE_ERROR, NULL}, {STATE_ERROR, NULL} } // STATE_ERROR\n};\n\nState current_state = STATE_INIT;\n\nvoid process_event(Event event) {\n Transition transition = state_table[current_state][event];\n if (transition.action != NULL) {\n transition.action();\n }\n current_state = transition.next_state;\n}\n\n// Action functions\nvoid init_action(void) { printf(\"Initializing...\\n\"); }\nvoid start_process(void) { printf(\"Starting process\\n\"); }\nvoid complete_process(void) { printf(\"Process completed\\n\"); }\nvoid handle_error(void) { printf(\"Error occurred\\n\"); }\nvoid reset_system(void) { printf(\"Resetting system\\n\"); }" }, "typescript": { "language": "typescript", "code": "enum DeviceState {\n INIT = 0,\n READY = 1,\n BUSY = 2,\n ERROR = 3\n}\n\nenum DeviceEvent {\n START = 0,\n PROCESS = 1,\n COMPLETE = 2,\n FAIL = 3\n}\n\ntype ActionFunction = () => void;\n\ninterface Transition {\n nextState: DeviceState;\n action?: ActionFunction;\n}\n\n// State transition table\nconst stateTable: Transition[][] = [\n // [START, PROCESS, COMPLETE, FAIL]\n [\n { nextState: DeviceState.READY, action: () => console.log('Initializing...') },\n { nextState: DeviceState.INIT },\n { nextState: DeviceState.INIT },\n { nextState: DeviceState.INIT }\n ], // INIT\n [\n { nextState: DeviceState.READY },\n { nextState: DeviceState.BUSY, action: () => console.log('Starting process') },\n { nextState: DeviceState.READY },\n { nextState: DeviceState.READY }\n ], // READY\n [\n { nextState: DeviceState.BUSY },\n { nextState: DeviceState.BUSY },\n { nextState: DeviceState.READY, action: () => console.log('Process completed') },\n { nextState: DeviceState.ERROR, action: () => console.log('Error occurred') }\n ], // BUSY\n [\n { nextState: DeviceState.INIT, action: () => console.log('Resetting system') },\n { nextState: DeviceState.ERROR },\n { nextState: DeviceState.ERROR },\n { nextState: DeviceState.ERROR }\n ] // ERROR\n];\n\nclass TableDrivenStateMachine {\n private currentState: DeviceState = DeviceState.INIT;\n \n processEvent(event: DeviceEvent): void {\n const transition = stateTable[this.currentState][event];\n if (transition.action) {\n transition.action();\n }\n this.currentState = transition.nextState;\n }\n \n getCurrentState(): DeviceState {\n return this.currentState;\n }\n}\n\n// Usage\nconst fsm = new TableDrivenStateMachine();\nfsm.processEvent(DeviceEvent.START); // Initializes and moves to READY\nfsm.processEvent(DeviceEvent.PROCESS); // Starts process and moves to BUSY\nfsm.processEvent(DeviceEvent.COMPLETE); // Completes and moves to READY" } } }, { "id": "circular-buffer", "name": "Circular Buffer", "category": "Embedded Systems", "description": "Fixed-size buffer that wraps around when full, providing efficient FIFO storage with constant-time operations for embedded systems with limited memory", "when_to_use": "Streaming data processing\nInterrupt-driven data collection\nProducer-consumer scenarios\nLimited memory environments\nReal-time data buffering\nUART/SPI communication buffers", "benefits": "Constant time complexity O(1)\nFixed memory usage\nNo dynamic allocation\nThread-safe with proper implementation\nEfficient for embedded systems", "drawbacks": "Fixed size limitation\nData loss on overflow\nComplexity with multiple producers/consumers\nPointer management required", "use_cases": "Serial communication buffers\nAudio/video streaming\nSensor data collection\nEvent logging\nNetwork packet buffering\nReal-time data acquisition", "complexity": "Medium", "tags": [ "embedded", "data-structure", "fifo", "ring-buffer", "memory-efficient", "real-time" ], "examples": { "c": { "language": "c", "code": "#define BUFFER_SIZE 256\n\ntypedef struct {\n uint8_t buffer[BUFFER_SIZE];\n volatile uint16_t head;\n volatile uint16_t tail;\n volatile uint16_t count;\n} CircularBuffer;\n\nvoid circular_buffer_init(CircularBuffer* cb) {\n cb->head = 0;\n cb->tail = 0;\n cb->count = 0;\n}\n\nbool circular_buffer_put(CircularBuffer* cb, uint8_t data) {\n if (cb->count >= BUFFER_SIZE) {\n return false; // Buffer full\n }\n \n cb->buffer[cb->head] = data;\n cb->head = (cb->head + 1) % BUFFER_SIZE;\n __disable_irq(); // Critical section\n cb->count++;\n __enable_irq();\n return true;\n}\n\nbool circular_buffer_get(CircularBuffer* cb, uint8_t* data) {\n if (cb->count == 0) {\n return false; // Buffer empty\n }\n \n *data = cb->buffer[cb->tail];\n cb->tail = (cb->tail + 1) % BUFFER_SIZE;\n __disable_irq(); // Critical section\n cb->count--;\n __enable_irq();\n return true;\n}\n\nuint16_t circular_buffer_count(CircularBuffer* cb) {\n return cb->count;\n}\n\nbool circular_buffer_is_empty(CircularBuffer* cb) {\n return cb->count == 0;\n}\n\nbool circular_buffer_is_full(CircularBuffer* cb) {\n return cb->count >= BUFFER_SIZE;\n}\n\n// Usage example\nCircularBuffer rx_buffer;\ncircular_buffer_init(&rx_buffer);\n\n// In UART interrupt\nvoid UART_IRQHandler(void) {\n uint8_t data = UART->DR;\n circular_buffer_put(&rx_buffer, data);\n}\n\n// In main loop\nuint8_t data;\nif (circular_buffer_get(&rx_buffer, &data)) {\n process_received_data(data);\n}" }, "typescript": { "language": "typescript", "code": "class CircularBuffer<T> {\n private buffer: T[];\n private head: number = 0;\n private tail: number = 0;\n private count: number = 0;\n \n constructor(private capacity: number) {\n this.buffer = new Array(capacity);\n }\n \n put(item: T): boolean {\n if (this.count >= this.capacity) {\n return false; // Buffer full\n }\n \n this.buffer[this.head] = item;\n this.head = (this.head + 1) % this.capacity;\n this.count++;\n return true;\n }\n \n get(): T | null {\n if (this.count === 0) {\n return null; // Buffer empty\n }\n \n const item = this.buffer[this.tail];\n this.tail = (this.tail + 1) % this.capacity;\n this.count--;\n return item;\n }\n \n peek(): T | null {\n if (this.count === 0) {\n return null;\n }\n return this.buffer[this.tail];\n }\n \n size(): number {\n return this.count;\n }\n \n isEmpty(): boolean {\n return this.count === 0;\n }\n \n isFull(): boolean {\n return this.count >= this.capacity;\n }\n \n clear(): void {\n this.head = 0;\n this.tail = 0;\n this.count = 0;\n }\n}\n\n// Usage example\nconst buffer = new CircularBuffer<number>(10);\n\n// Producer\nbuffer.put(1);\nbuffer.put(2);\nbuffer.put(3);\n\n// Consumer\nconsole.log(buffer.get()); // 1\nconsole.log(buffer.get()); // 2\nconsole.log(buffer.size()); // 1\n\n// Check status\nconsole.log(buffer.isEmpty()); // false\nconsole.log(buffer.isFull()); // false" } } }, { "id": "watchdog-timer", "name": "Watchdog Timer", "category": "Embedded Systems", "description": "Hardware timer that resets the system if not periodically serviced, ensuring system reliability and preventing hangs in embedded applications", "when_to_use": "Mission-critical embedded systems\nSystems with real-time requirements\nApplications running without supervision\nSystems exposed to harsh environments\nWhen software reliability is paramount", "benefits": "Automatic recovery from software faults\nIncreased system reliability\nPrevents infinite loops and deadlocks\nLow overhead implementation\nHardware-based reliability", "drawbacks": "Can cause unnecessary resets\nRequires careful timeout selection\nDebugging can be challenging\nMay mask underlying issues\nPower consumption considerations", "use_cases": "Industrial control systems\nMedical devices\nAutomotive electronics\nAerospace systems\nIoT devices\nRemote monitoring systems", "complexity": "Low", "tags": [ "embedded", "reliability", "hardware", "fault-tolerance", "system-monitoring", "reset" ], "examples": { "c": { "language": "c", "code": "// Watchdog Timer Interface\nvoid watchdog_init(uint32_t timeout_ms) {\n // Configure watchdog timer with specified timeout\n WDT->LOAD = (SystemCoreClock / 1000) * timeout_ms;\n WDT->CTRL = WDT_CTRL_ENABLE;\n}\n\nvoid watchdog_feed(void) {\n // Reset the watchdog timer\n WDT->FEED = WDT_FEED_SEQUENCE1;\n WDT->FEED = WDT_FEED_SEQUENCE2;\n}\n\nvoid watchdog_disable(void) {\n // Disable watchdog (use with caution)\n WDT->CTRL &= ~WDT_CTRL_ENABLE;\n}\n\n// Application watchdog service\nvoid watchdog_service(void) {\n static uint32_t last_feed_time = 0;\n uint32_t current_time = get_system_time_ms();\n \n // Feed watchdog every 100ms if system is healthy\n if (current_time - last_feed_time >= 100) {\n if (system_is_healthy()) {\n watchdog_feed();\n last_feed_time = current_time;\n }\n }\n}\n\nbool system_is_healthy(void) {\n // Check critical system components\n return (\n uart_is_responsive() &&\n sensors_are_reading() &&\n memory_is_accessible() &&\n !critical_error_flag\n );\n}\n\n// Main application loop\nint main(void) {\n system_init();\n watchdog_init(500); // 500ms timeout\n \n while (1) {\n process_inputs();\n update_outputs();\n watchdog_service(); // Must be called regularly\n \n // If this loop hangs or watchdog_service isn't called,\n // the system will automatically reset\n }\n}\n\n// Watchdog interrupt handler (if available)\nvoid WDT_IRQHandler(void) {\n // System is about to reset due to watchdog timeout\n // Perform emergency cleanup if possible\n emergency_save_state();\n \n // Clear interrupt flag\n WDT->INTCLR = 1;\n}" }, "typescript": { "language": "typescript", "code": "// Software watchdog implementation for systems without hardware watchdog\nclass WatchdogTimer {\n private timeoutId: NodeJS.Timeout | null = null;\n private lastFeedTime: number = Date.now();\n private readonly timeoutMs: number;\n private onTimeout: () => void;\n \n constructor(timeoutMs: number, onTimeout: () => void) {\n this.timeoutMs = timeoutMs;\n this.onTimeout = onTimeout;\n this.start();\n }\n \n private start(): void {\n this.timeoutId = setInterval(() => {\n const now = Date.now();\n if (now - this.lastFeedTime >= this.timeoutMs) {\n console.error('Watchdog timeout - system reset');\n this.onTimeout();\n }\n }, 100); // Check every 100ms\n }\n \n feed(): void {\n this.lastFeedTime = Date.now();\n }\n \n dispose(): void {\n if (this.timeoutId) {\n clearInterval(this.timeoutId);\n this.timeoutId = null;\n }\n }\n}\n\n// System health monitor\nclass SystemHealthMonitor {\n private watchdog: WatchdogTimer;\n private errorCount: number = 0;\n private maxErrors: number = 5;\n \n constructor() {\n this.watchdog = new WatchdogTimer(2000, () => this.handleTimeout());\n }\n \n checkHealth(): void {\n try {\n // Perform health checks\n if (this.checkMemoryUsage() && \n this.checkNetworkConnectivity() && \n this.checkDatabaseConnection()) {\n \n this.errorCount = 0;\n this.watchdog.feed(); // System is healthy\n \n } else {\n this.errorCount++;\n if (this.errorCount >= this.maxErrors) {\n console.error('Too many health check failures');\n this.triggerReset();\n }\n }\n \n } catch (error) {\n console.error('Health check failed:', error);\n this.errorCount++;\n }\n }\n \n private checkMemoryUsage(): boolean {\n // Check if memory usage is within limits\n return process.memoryUsage().heapUsed < 100 * 1024 * 1024; // 100MB\n }\n \n private checkNetworkConnectivity(): boolean {\n // Check network connectivity\n return true; // Simplified\n }\n \n private checkDatabaseConnection(): boolean {\n // Check database connection\n return true; // Simplified\n }\n \n private handleTimeout(): void {\n console.error('Watchdog timeout - initiating system reset');\n this.triggerReset();\n }\n \n private triggerReset(): void {\n // Perform emergency cleanup\n this.saveCriticalState();\n \n // Reset the system\n process.exit(1); // In a real embedded system, this would trigger hardware reset\n }\n \n private saveCriticalState(): void {\n console.log('Saving critical system state...');\n // Save important state to persistent storage\n }\n \n dispose(): void {\n this.watchdog.dispose();\n }\n}\n\n// Usage\nconst healthMonitor = new SystemHealthMonitor();\n\n// Main application loop\nsetInterval(() => {\n healthMonitor.checkHealth();\n // Perform normal operations\n}, 500);\n\n// Cleanup on exit\nprocess.on('exit', () => {\n healthMonitor.dispose();\n});" } } }, { "id": "interrupt-service-routine", "name": "Interrupt Service Routine", "category": "Embedded Systems", "description": "Handles asynchronous hardware events with minimal, time-critical code that quickly services the interrupt and defers complex processing to main execution context", "when_to_use": "Hardware event handling\nReal-time response requirements\nAsynchronous I/O operations\nTime-critical signal processing\nDevice driver implementation\nSensor data acquisition", "benefits": "Fast response to hardware events\nMinimal interrupt latency\nSeparation of urgent vs. complex processing\nEfficient resource utilization\nPredictable timing behavior", "drawbacks": "Complex concurrency management\nLimited operations in ISR context\nPotential for race conditions\nDebugging challenges\nStack usage considerations", "use_cases": "UART/serial communication\nTimer events\nGPIO pin changes\nADC/DAC conversions\nDMA completion\nExternal device interrupts", "complexity": "High", "tags": ["embedded", "interrupt", "asynchronous", "real-time", "hardware", "concurrency"], "examples": { "c": { "language": "c", "code": "// Global variables for ISR communication\nvolatile uint8_t uart_rx_buffer[256];\nvolatile uint16_t rx_head = 0;\nvolatile uint16_t rx_tail = 0;\nvolatile bool data_ready = false;\n\n// UART Interrupt Service Routine\nvoid UART0_IRQHandler(void) {\n uint32_t status = UART0->MIS; // Masked Interrupt Status\n \n // Clear interrupt flags\n UART0->ICR = status;\n \n if (status & UART_MIS_RXMIS) { // Receive interrupt\n // Read data quickly\n while (!(UART0->FR & UART_FR_RXFE)) { // While data available\n uint8_t data = UART0->DR;\n \n // Store in circular buffer (ISR-safe)\n uint16_t next_head = (rx_head + 1) % 256;\n if (next_head != rx_tail) { // Check for overflow\n uart_rx_buffer[rx_head] = data;\n rx_head = next_head;\n data_ready = true;\n }\n // Note: No complex processing here!\n }\n }\n \n if (status & UART_MIS_TXMIS) { // Transmit interrupt\n // Handle transmit completion\n // Could signal main loop to send more data\n }\n}\n\n// Timer Interrupt Service Routine\nvoid TIMER0_IRQHandler(void) {\n // Clear interrupt flag\n TIMER0->ICR = TIMER_ICR_TATOCINT;\n \n // Minimal processing - just set flags or update counters\n static uint32_t tick_count = 0;\n tick_count++;\n \n // Signal main loop for time-based tasks\n volatile bool timer_event = true;\n}\n\n// GPIO Interrupt Service Routine (Button debouncing)\nvoid GPIOA_IRQHandler(void) {\n uint32_t pin_status = GPIOA->MIS;\n GPIOA->ICR = pin_status; // Clear interrupts\n \n if (pin_status & (1 << BUTTON_PIN)) {\n // Button press detected\n static uint32_t last_press_time = 0;\n uint32_t current_time = get_system_ticks();\n \n // Simple debouncing in ISR\n if (current_time - last_press_time > DEBOUNCE_TICKS) {\n volatile bool button_pressed = true;\n last_press_time = current_time;\n }\n }\n}\n\n// Main application loop\nint main(void) {\n system_init();\n enable_interrupts();\n \n while (1) {\n // Check for ISR signals and perform complex processing\n if (data_ready) {\n process_received_data();\n data_ready = false;\n }\n \n if (timer_event) {\n handle_timer_tasks();\n timer_event = false;\n }\n \n if (button_pressed) {\n handle_button_press();\n button_pressed = false;\n }\n \n // Other main loop tasks...\n }\n}\n\n// Functions called from main loop (not ISR)\nvoid process_received_data(void) {\n // Complex processing: parse commands, update state, etc.\n while (rx_tail != rx_head) {\n uint8_t data = uart_rx_buffer[rx_tail];\n rx_tail = (rx_tail + 1) % 256;\n \n // Process data (parsing, validation, response generation)\n handle_received_byte(data);\n }\n}" }, "typescript": { "language": "typescript", "code": "// Simulated interrupt handling for demonstration\nclass InterruptController {\n private interrupts: Map<string, () => void> = new Map();\n private volatileFlags: Map<string, boolean> = new Map();\n \n // Register an interrupt handler\n registerInterrupt(name: string, handler: () => void): void {\n this.interrupts.set(name, handler);\n this.volatileFlags.set(name, false);\n }\n \n // Simulate hardware interrupt (called asynchronously)\n triggerInterrupt(name: string): void {\n const handler = this.interrupts.get(name);\n if (handler) {\n // ISR execution - keep it minimal!\n handler();\n }\n }\n \n // Check if interrupt flag is set (called from main loop)\n isInterruptPending(name: string): boolean {\n return this.volatileFlags.get(name) || false;\n }\n \n // Clear interrupt flag (called from main loop)\n clearInterrupt(name: string): void {\n this.volatileFlags.set(name, false);\n }\n}\n\n// UART-like device simulation\nclass UARTDevice {\n private rxBuffer: number[] = [];\n private interruptController: InterruptController;\n \n constructor(interruptController: InterruptController) {\n this.interruptController = interruptController;\n \n // Register RX interrupt handler\n interruptController.registerInterrupt('UART_RX', () => {\n this.handleRxInterrupt();\n });\n }\n \n // Simulate receiving data (would be hardware-triggered)\n receiveData(data: number): void {\n // In real ISR, this would be called by hardware\n this.rxBuffer.push(data);\n this.interruptController.triggerInterrupt('UART_RX');\n }\n \n private handleRxInterrupt(): void {\n // Minimal ISR processing\n // Just signal that data is ready\n // Don't do complex parsing here!\n console.log('UART RX interrupt: data ready');\n }\n \n // Called from main loop to process received data\n processReceivedData(): void {\n while (this.rxBuffer.length > 0) {\n const data = this.rxBuffer.shift()!;\n console.log('Processing received byte: ' + data);\n // Complex processing: parsing, validation, etc.\n this.handleReceivedByte(data);\n }\n }\n \n private handleReceivedByte(data: number): void {\n // Simulate command processing\n if (data === 0x01) {\n console.log('Command: Start');\n } else if (data === 0x02) {\n console.log('Command: Stop');\n } else {\n console.log(`Data: ${data}`);\n }\n }\n}\n\n// Timer simulation\nclass Timer {\n private intervalId: NodeJS.Timeout | null = null;\n private interruptController: InterruptController;\n \n constructor(interruptController: InterruptController) {\n this.interruptController = interruptController;\n \n interruptController.registerInterrupt('TIMER', () => {\n this.handleTimerInterrupt();\n });\n }\n \n start(intervalMs: number): void {\n this.intervalId = setInterval(() => {\n this.interruptController.triggerInterrupt('TIMER');\n }, intervalMs);\n }\n \n stop(): void {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n }\n \n private handleTimerInterrupt(): void {\n // Minimal timer ISR\n console.log('Timer interrupt: tick');\n // Just signal - don't do timing-dependent work here\n }\n}\n\n// Main application\nclass EmbeddedSystem {\n private interruptController = new InterruptController();\n private uart = new UARTDevice(this.interruptController);\n private timer = new Timer(this.interruptController);\n \n start(): void {\n this.timer.start(1000); // 1 second timer\n \n // Simulate receiving UART data\n setTimeout(() => this.uart.receiveData(0x01), 500);\n setTimeout(() => this.uart.receiveData(0x42), 1500);\n setTimeout(() => this.uart.receiveData(0x02), 2500);\n \n // Main loop\n setInterval(() => {\n this.mainLoop();\n }, 100);\n }\n \n private mainLoop(): void {\n // Check for pending interrupts and handle them\n if (this.interruptController.isInterruptPending('UART_RX')) {\n this.uart.processReceivedData();\n this.interruptController.clearInterrupt('UART_RX');\n }\n \n if (this.interruptController.isInterruptPending('TIMER')) {\n this.handleTimerEvent();\n this.interruptController.clearInterrupt('TIMER');\n }\n \n // Other main loop tasks...\n }\n \n private handleTimerEvent(): void {\n console.log('Timer event: performing periodic tasks');\n // Complex timer-based processing\n }\n}\n\n// Usage\nconst system = new EmbeddedSystem();\nsystem.start();" } } } ] }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apolosan/design_patterns_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server