blob: c0085ce5fba421fd3a9a7c2d8950b43b7cd301a6 [file] [view]
# USART Integration Test
## Overview
This directory contains a full system integration test for the USART (Universal Synchronous/Asynchronous Receiver-Transmitter) driver on the AST10x0 platform. The test validates that the USART server and client communicate correctly over IPC channels in a multi-process QEMU-based simulation.
## Test Structure
### Components
- **`target.rs`**: Kernel entry point for the AST10x0 virt target
- **`server_main.rs`**: USART server process - handles requests from clients
- **`client_main.rs`**: USART client process - sends configuration and write requests
- **`system.json5`**: System configuration file defining memory layout and process definitions
- **`BUILD.bazel`**: Bazel build rules and test targets
### Memory Layout
```
ARM Cortex-M4 @ 200 MHz, 768KB SRAM (0x00000000 - 0x000BFFFF)
0x00000000 - 0x00000500: Vector table (1280 bytes)
0x00000500 - 0x00020000: Kernel code (~126KB, ends at 128KB boundary)
0x00020000 - 0x00060000: ipc multi-process app code (256KB, two processes)
0x00060000 - 0x00080000: Kernel RAM (128KB)
0x00080000 - 0x000A0000: App RAM (128KB)
```
### Process Definition
The test instantiates two processes:
1. **USART Server** (`usart_server_bin`):
- Waits on IPC channel for client requests
- Services read/write operations via USART backend
- Manages UART5 IRQ and data flow
- Depends on `//drivers/usart/server:usart_server`
2. **USART Client** (`usart_client_app`):
- Configures USART to 1,500,000 baud
- Writes test message: `"usart client online\r\n"`
- Validates communication path
- Depends on `//drivers/usart/client:usart_client`
## Running the Test
### Prerequisites
- `bazelisk` installed and in PATH
- AST10x0 QEMU binaries available
- Working Rust/Bazel build environment
### Run the Test
```bash
# Run with virt_ast10x0 platform config
bazelisk test //target/ast10x0/tests/usart:usart_test --config=virt_ast10x0
# With verbose/streamed output
bazelisk test //target/ast10x0/tests/usart:usart_test --config=virt_ast10x0 --test_output=streamed
# Show all test output
bazelisk test //target/ast10x0/tests/usart:usart_test --config=virt_ast10x0 --test_output=all
```
### Expected Output
```
INFO: Found 1 test target...
Target //target/ast10x0/tests/usart:usart_test up-to-date:
bazel-bin/target/ast10x0/tests/usart/usart_test
INFO: Build completed successfully, X total actions
//target/ast10x0/tests/usart:usart_test PASSED in 0.4s
Executed 1 out of 1 test: 1 test passes.
```
## Test Flow
1. **System Initialization**:
- Kernel boots with multi-process IPC support
- Codegen establishes wait groups and channel handles
- Both processes start concurrently
2. **Server Setup**:
- Registers IPC channel with `Signals::READABLE`
- Registers UART5 IRQ with custom signal mask
- Enters dispatch loop in `runtime::run()`
3. **Client Execution**:
- Constructs `UsartClient` with IPC handle
- Issues `configure(1_500_000)` call
- Issues `write(b"usart client online\r\n")` call
- Gracefully shuts down
4. **Server Processing**:
- Receives client requests via `object_wait()`
- Dispatches to backend (AST10x0 UART5 driver)
- Responds via `channel_respond()`
5. **Test Completion**:
- Client calls `debug_shutdown(Ok(()))`
- QEMU halts with exit code 0 (success)
## Architecture
### USART Backend
The test uses the concrete AST10x0 USART backend:
- **Location**: `//target/ast10x0/backend/usart:usart_backend_ast10x0`
- **Hardware**: UART5 at 0x7e78_4000 (AST10x0 MMIO base)
- **Features**: Blocking read/write, IRQ masking, line status
### Wire Protocol
Defined in `//drivers/usart/api`:
- `UsartOp` enum: Configure, Write, Read, GetLineStatus, (Enable/Disable)Interrupts
- `UsartError` variants: Success, InvalidOperation, BufferTooSmall, Busy, Timeout, etc.
- Max payload per IPC request/response: 256 bytes
### Server Runtime
Dispatch loop in `//drivers/usart/server:runtime`:
1. Wait for IRQ or client channel readable
2. Route wake-ups by `user_data`:
- If IRQ: acknowledge and clear pending signals
- If channel: read request, dispatch, respond
3. Back to wait (infinite loop)
## Debugging
### Build Issues
If Bazel build fails with incompatibility error:
```
ERROR: Target is incompatible and cannot be built
```
**Solution**: Use `--config=virt_ast10x0` to set the correct platform.
### QEMU Timeout
If test hangs or times out:
- Check system.json5 for memory/process configuration correctness
- Verify UART5 device node exists in QEMU model
- Inspect server startup logs with `--test_output=all`
### Common Failures
| Symptom | Cause | Fix |
|---------|-------|-----|
| Process crashes at startup | Missing codegen or wait group | Rebuild with clean cache |
| IPC channel not found | Incorrect process/object names | Match system.json5 and codegen |
| USART timeout | Backend not driving UART5 | Check backend initialization |
| Data corruption | Buffer overflow or alignment | Verify MAX_PAYLOAD_SIZE contract |
## Future Extensions
This test is a foundation for:
- [ ] Non-blocking read/write (`try_read`, `try_write`)
- [ ] Async result polling (`get_async_result`)
- [ ] Multi-client concurrent operations
- [ ] Error injection and recovery testing
- [ ] Performance benchmarking
See [ASYNC_NONBLOCKING_IMPLEMENTATION_PLAN.md](../../drivers/usart/api/ASYNC_NONBLOCKING_IMPLEMENTATION_PLAN.md) for planned enhancements.
## Related Documentation
- [USART Driver API](../../drivers/usart/api/README.md) - Protocol and backend trait
- [USART Client](../../drivers/usart/client/README.md) - IPC wrapper usage
- [USART Server](../../drivers/usart/server/README.md) - Dispatch and runtime
- [AST10x0 Backend](../../target/ast10x0/backend/usart/README.md) - Hardware driver
- [Async Non-Blocking Plan](../../drivers/usart/api/ASYNC_NONBLOCKING_IMPLEMENTATION_PLAN.md) - Future work
## Build Artifacts
After a successful build, the test artifacts are located at:
```
bazel-bin/target/ast10x0/tests/usart/
├── usart # System image (kernel + rootfs)
├── usart_test # Test runner
├── usart_server_bin # Compiled server binary
└── usart_client_app # Compiled client binary
```
## Contributing
When modifying this test:
1. Keep system.json5 in sync with process/handle definitions
2. Update both server_main.rs and client_main.rs if changing IPC contract
3. Run test locally before committing
4. Document any new operations or error codes in USART API
## License
Licensed under the Apache-2.0 license. See LICENSE file in repository root.