IDE-ChipBridge-Core
是一个用于芯片/FPGA连接调试的核心VSCode扩展。它提供GDB和TCL两种连接方式,并暴露API供其他扩展调用,实现寄存器、内存的读写操作。
功能特性
- 多端口支持:同时支持GDB、TCL三个端口
- 全局状态管理:多个VS Code窗口共享连接状态
- 心跳监控:实时检测连接状态,自动重连
- 完整API:提供丰富的API供其他插件调用
- 状态栏集成:显示连接状态,一键操作
按照依赖
其他扩展需要在 package.json 中声明对IDE-ChipBridge-Core的依赖:
{
"extensionDependencies": ["chipbridge.ide-chipbridge-core"]
}
API使用示例
// 获取API实例
import * as vscode from 'vscode';
async function getChipBridgeApi(): Promise<any> {
const extension = vscode.extensions.getExtension('chipbridge.ide-chipbridge-core');
if (!extension) {
throw new Error('IDE-ChipBridge-Core extension is not installed');
}
// 激活扩展
if (!extension.isActive) {
await extension.activate();
}
// 获取API
const api = extension.exports?.chipBridge;
if (!api) {
throw new Error('Failed to get ChipBridge API');
}
return api;
}
// 使用示例
const chipBridgeApi = await getChipBridgeApi();
数据类型定义
interface ChipHost {
name: string; // 主机名称
ip: string; // IP地址
gdbPort: number; // GDB端口
telnetPort: number;// Telnet端口
tclPort: number; // TCL端口
}
enum ConnectionType {
DISCONNECTED = 'Disconnected',
GDB = 'GDB',
TELNET = 'Telnet'
}
enum ConnectionStatus {
DISCONNECTED = 'Disconnected',
CONNECTING = 'Connecting',
CONNECTED = 'Connected'
}
interface ConnectionInfo {
host: ChipHost;
type: ConnectionType;
status: ConnectionStatus;
}
事件类型
interface ConnectionStatusChangedEvent {
status: ConnectionStatus;
type: ConnectionType;
host?: ChipHost;
}
interface ErrorEvent {
message: string;
code?: string;
details?: unknown;
}
API接口
1. 连接管理
获取连接信息
getConnectionInfo(): ConnectionInfo | null
示例:
const connectionInfo = chipBridgeApi.getConnectionInfo();
if (connectionInfo) {
console.log(`Connected to ${connectionInfo.host.name} via ${connectionInfo.type}`);
}
2. 寄存器操作
读取单个寄存器
readRegister(register: string): Promise<RegisterReadResult>
参数:
- register: 寄存器名称(如:'r0', 'pc', 'sp'等)
返回值:
interface RegisterReadResult {
register: string; // 寄存器名称
value: string; // 原始值字符串
hexValue: string; // 十六进制值(如:0x1234)
decimalValue: number; // 十进制值
}
示例:
try {
const result = await chipBridgeApi.readRegister('pc');
console.log(`PC: ${result.hexValue} (${result.decimalValue})`);
} catch (error) {
console.error('Failed to read register:', error);
}
批量读取地址范围
batchReadAddress(options: BatchAddressReadOptions): Promise<BatchAddressReadResult>
参数:
interface BatchAddressReadOptions {
startAddress: string | number; // 起始地址
count: number; // 读取数量
format?: 'hex' | 'decimal' | 'binary'; // 输出格式
wordSize?: number; // 字大小(1=字节,2=半字,4=字,默认4)
}
返回值:
interface BatchAddressReadResult {
addresses: string[]; // 地址数组
values: string[]; // 原始值数组
hexValues: string[]; // 十六进制值数组
decimalValues: number[]; // 十进制值数组
formattedValues: string[]; // 格式化后的值数组
}
示例:
// 读取内存区域的16个地址
const result = await chipBridgeApi.batchReadAddress({
startAddress: 0x20000000,
count: 16,
wordSize: 4,
format: 'hex'
});
// 输出结果
for (let i = 0; i < result.addresses.length; i++) {
console.log(`${result.addresses[i]}: ${result.formattedValues[i]}`);
}
写入寄存器
writeRegister(options: RegisterWriteOptions): Promise<boolean>
参数:
interface RegisterWriteOptions {
register: string; // 寄存器名称
value: string | number; // 值(支持字符串或数字)
format?: 'hex' | 'decimal' | 'binary'; // 值格式
}
示例:
// 写入十六进制值
const success = await chipBridgeApi.writeRegister({
register: 'r0',
value: 0x1234,
format: 'hex'
});
// 写入十进制值
const success2 = await chipBridgeApi.writeRegister({
register: 'r1',
value: 4660, // 0x1234的十进制
format: 'decimal'
});
3. 内存操作
读取内存
readMemory(options: MemoryReadOptions): Promise<MemoryReadResult>
参数:
interface MemoryReadOptions {
address: string | number; // 内存地址
size?: number; // 读取大小(默认4)
format?: 'hex' | 'decimal'; // 输出格式
}
返回值:
interface MemoryReadResult {
address: string; // 地址字符串
value: string; // 原始值
size: number; // 读取大小
}
示例:
const result = await chipBridgeApi.readMemory({
address: 0x20000000,
size: 4,
format: 'hex'
});
console.log(`Memory at ${result.address}: ${result.value}`);
批量读取内存
batchReadMemory(options: BatchMemoryReadOptions): Promise<BatchMemoryReadResult>
参数:
interface BatchMemoryReadOptions {
startAddress: string | number; // 起始地址
count: number; // 读取数量
wordSize?: number; // 字大小(默认4)
format?: 'hex' | 'decimal'; // 输出格式
}
返回值:
interface BatchMemoryReadResult {
addresses: string[]; // 地址数组
values: string[]; // 原始值数组
hexValues: string[]; // 十六进制值数组
decimalValues: number[]; // 十进制值数组
}
示例:
const result = await chipBridgeApi.batchReadMemory({
startAddress: '0x08000000', // Flash区域
count: 32,
wordSize: 4,
format: 'hex'
});
写入内存
writeMemory(options: MemoryWriteOptions): Promise<boolean>
参数:
interface MemoryWriteOptions {
address: string | number; // 内存地址
value: string | number; // 要写入的值
size?: number; // 数据大小
format?: 'hex' | 'decimal' | 'binary'; // 值格式
}
示例:
const success = await chipBridgeApi.writeMemory({
address: 0x20000000,
value: 0xDEADBEEF,
format: 'hex'
});
4. 事件监听
连接状态变化事件
onConnectionStatusChanged(callback: (event: ConnectionStatusChangedEvent) => void): vscode.Disposable
示例:
const disposable = chipBridgeApi.onConnectionStatusChanged((event) => {
console.log(`Connection status: ${event.status}, type: ${event.type}`);
if (event.status === ConnectionStatus.CONNECTED) {
console.log(`Connected to ${event.host?.name}`);
} else if (event.status === ConnectionStatus.DISCONNECTED) {
console.log('Disconnected');
}
});
// 使用后需要清理
disposable.dispose();
错误事件
onError(callback: (event: ErrorEvent) => void): vscode.Disposable
示例:
const errorDisposable = chipBridgeApi.onError((error) => {
console.error(`ChipBridge error: ${error.message}`);
if (error.code) {
console.error(`Error code: ${error.code}`);
}
});
使用注意事项
1. 连接状态检查
在进行寄存器或内存操作前,必须检查连接状态和连接类型:
const connectionInfo = chipBridgeApi.getConnectionInfo();
if (!connectionInfo || connectionInfo.status !== ConnectionStatus.CONNECTED) {
throw new Error('Not connected to any device');
}
if (connectionInfo.type !== ConnectionType.TELNET) {
throw new Error('Register/memory operations require Telnet connection');
}
2. 错误处理
所有API都可能抛出错误,建议使用try-catch:
try {
const result = await chipBridgeApi.readRegister('pc');
// 处理结果
} catch (error) {
console.error('Operation failed:', error);
if (error.message.includes('Telnet not connected')) {
// 处理连接错误
} else if (error.message.includes('Register not found')) {
// 处理寄存器不存在错误
}
}
3. 资源清理
事件监听器需要手动清理:
class MyExtension {
private disposables: vscode.Disposable[] = [];
activate() {
const chipBridgeApi = await getChipBridgeApi();
// 添加事件监听
const statusDisposable = chipBridgeApi.onConnectionStatusChanged(this.handleStatusChange);
const errorDisposable = chipBridgeApi.onError(this.handleError);
this.disposables.push(statusDisposable, errorDisposable);
}
deactivate() {
// 清理所有监听器
this.disposables.forEach(d => d.dispose());
}
}
完整示例
import * as vscode from 'vscode';
export class ChipDebugger {
private chipBridgeApi: any;
private isConnected = false;
async initialize() {
try {
// 获取API
this.chipBridgeApi = await this.getChipBridgeApi();
// 监听连接状态
this.chipBridgeApi.onConnectionStatusChanged((event) => {
this.isConnected = event.status === 'Connected';
console.log(`Connection status: ${event.status}`);
});
// 监听错误
this.chipBridgeApi.onError((error) => {
console.error(`ChipBridge error: ${error.message}`);
});
console.log('ChipDebugger initialized');
} catch (error) {
console.error('Failed to initialize ChipDebugger:', error);
}
}
async connectToDevice(hostName: string): Promise<boolean> {
const hosts = this.chipBridgeApi.getAvailableChipHosts();
const host = hosts.find(h => h.name === hostName);
if (!host) {
throw new Error(`Host ${hostName} not found`);
}
return await this.chipBridgeApi.connect(host, 'Telnet');
}
async readRegisters(registers: string[]): Promise<Map<string, number>> {
const result = new Map<string, number>();
for (const reg of registers) {
try {
const value = await this.chipBridgeApi.readRegister(reg);
result.set(reg, value.decimalValue);
} catch (error) {
console.warn(`Failed to read register ${reg}:`, error);
}
}
return result;
}
async dumpMemory(startAddr: number, size: number): Promise<void> {
const result = await this.chipBridgeApi.batchReadAddress({
startAddress: startAddr,
count: Math.ceil(size / 4),
wordSize: 4,
format: 'hex'
});
console.log('Memory Dump:');
for (let i = 0; i < result.addresses.length; i++) {
console.log(`${result.addresses[i]}: ${result.hexValues[i]}`);
}
}
private async getChipBridgeApi(): Promise<any> {
const extension = vscode.extensions.getExtension('chipbridge.ide-chipbridge-core');
if (!extension) {
throw new Error('IDE-ChipBridge-Core extension is not installed');
}
if (!extension.isActive) {
await extension.activate();
}
return extension.exports?.chipBridge;
}
}