Skip to content

Commit

Permalink
Merge pull request #29 from ARMmbed/f/rework
Browse files Browse the repository at this point in the history
Rework
  • Loading branch information
thegecko authored Jul 9, 2018

Unverified

No user is associated with the committer email.
2 parents c7e16b3 + 697b5af commit cee3cb5
Showing 90 changed files with 4,704 additions and 22,817 deletions.
258 changes: 194 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -3,92 +3,222 @@
[![Circle CI](https://circleci.com/gh/ARMmbed/dapjs.svg?style=shield&circle-token=d37ef109d0134f6f8e4eb12a65214a8b159f77d8)](https://circleci.com/gh/ARMmbed/dapjs/)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html)

DAP.js is a JavaScript interface to CMSIS-DAP, aiming to implement a subset of
the functionality provided by [pyOCD](https://github.com/mbedmicro/pyOCD), enabling
debugging of Arm Cortex-M devices in Node.js and in the browser using [WebUSB](https://developers.google.com/web/updates/2016/03/access-usb-devices-on-the-web).

## Features

- General
- Read core registers
- Run arbitrary assembled Arm machine code
- Debugging
- Set hardware and software breakpoints
- Step (instruction level)
- Memory
- Read blocks from memory:
- 16-bit reads/writes
- 32-bit reads/writes
- Word-aligned mass reads and writes
- Flashing
- Full-chip erase
- Flash binary files and intel hex files
- Support for the NRF51 (including the micro:bit) and NXP's FRDM-K64F.
- Performance
- Support for batched commands to improve HID report utilisation
- Flashing at ~10-20 kB/s, comparable with PyOCD and OpenOCD
DAP.js is a JavaScript interface to [CMSIS-DAP](https://www.keil.com/pack/doc/CMSIS/DAP/html/index.html), enabling access to Arm Microcontrollers using [Node.js](https://nodejs.org/) or in the browser using [WebUSB](https://wicg.github.io/webusb/).

## Prerequisites

[Node.js > v8.9.0](https://nodejs.org), which includes `npm 5`.
[Node.js > v6.10.0](https://nodejs.org), which includes `npm`.

## Installation

The SDK is distributed using npm. To install the package in your project:
The package is distributed using npm. To install the package in your project:

$ npm install dapjs
```bash
$ npm install dapjs
```

## Getting Started

Decide on a transport layer to use (see below) and refer to the [examples folder](https://github.com/ARMmbed/dapjs/tree/master/examples/) to get started.

The web example can be seen running at:

https://armmbed.github.io/dapjs/examples/daplink-flash/web.html

Refer to the [DAPjs API Documentation](https://armmbed.github.io/dapjs/) for more information.

## Choosing a Transport

In order to use DAPjs, you need to install support for one of the transports. Use the following information to help you choose which to use:

### WebUSB

## Development setup
If you wish to use DAPjs in a browser environment, you must use WebUSB. Please refer to the [implementation status](https://github.com/WICG/webusb#implementation-status) of WebUSB to understand browser support for this technology.

After cloning this repository:
__Note:__ WebUSB in the browser doesn't require any further libraries to be installed.

$ npm install
If you also want your program to work in a Node.js environment a [WebUSB library](https://github.com/thegecko/webusb) exists to allow your program to be ported to Node.js.

Then run one of the gulp commands:
To install the library for Node.js, use:

$ gulp
$ gulp watch
$ npm run gulp
```bash
$ npm install webusb
```

#### Example

## Examples
In the browser, require the library:

For more full-featured examples, please refer to the [examples](https://github.com/ARMmbed/dapjs/tree/master/examples) folder and see the web example running at:
```html
<script type="text/javascript" src="bundles/dap.bundle.js"></script>
```

https://armmbed.github.io/dapjs/
In Node.js Require the libraries:

```javascript
device = await navigator.usb.requestDevice({
filters: [{vendorId: 0x0d28}]
const usb = require("webusb").usb;
const DAPjs = require("dapjs");
```

Then in either environment:

```javascript
<navigator>.usb.requestDevice({
filters: [{vendorId: 0xD28}]
})
.then(device => {
const transport = new DAPjs.WebUSB(device);
const daplink = new DAPjs.DAPLink(transport);

return daplink.connect()
.then(() => daplink.disconnect())
.then(() => process.exit());
})
.catch(error => {
console.error(error.message || error);
process.exit();
});
```

#### Pros
- Works in the browser
- Programs are portable to Node.js environments

this.deviceCode = device.serialNumber.slice(0, 4);
selector = new DAPjs.PlatformSelector();
const info = await selector.lookupDevice(this.deviceCode);
this.hid = new DAPjs.HID(device);

// open hid device
await this.hid.open();
dapDevice = new DAPjs.DAP(this.hid);
// contains flash algorithms data and memory map
let flashAlgorithmsData = {};
let flashAlgorithm = new DAPjs.FlashAlgorithm(flashAlgorithmsData, this.deviceCode);
this.target = new DAPjs.FlashTarget(dapDevice, flashAlgorithm);

// init and halt target
await this.target.init();
await this.target.halt();

// program_data contains binary data
program_data = DAPjs.FlashProgram.fromBinary(0, program_data);
await this.target.program(program_data, (progress) => {
console.log(progress);
#### Cons
- Requires a recent version of [DAPLink](https://armmbed.github.io/DAPLink/) to be installed on your target device.

### HID

For the highest level of firmware compatibility in a Node.js environment, the HID transport is recommended. This utilises the `node-hid` library and is installed as follows:

```bash
$ npm install node-hid
```

#### Example

```javascript
const hid = require("node-hid");
const DAPjs = require("dapjs");

let devices = hid.devices();
devices = devices.filter(device => device.vendorId === 0xD28);

const transport = new DAPjs.HID(devices[0]);
const daplink = new DAPjs.DAPLink(transport);

daplink.connect()
.then(() => daplink.disconnect())
.then(() => process.exit())
.catch(error => {
console.error(error.message || error);
process.exit();
});
```

#### Pros
- Compatible with older CMSIS-DAP firmware.

#### Cons
- Requires HID access to JavaScript in your OS.

### USB

await this.target.reset();
A "pure" USB transport exists which bypasses requiring `WebUSB` and `HID`.
This utilises the `usb` library and is installed as follows:

```bash
$ npm install usb
```

## Documentation
#### Example

```javascript
const usb = require("usb");
const DAPjs = require("dapjs");

let devices = usb.getDeviceList();
devices = devices.filter(device => device.deviceDescriptor.idVendor === 0xD28);

API documentation can be viewed at:
const transport = new DAPjs.USB(devices[0]);
const daplink = new DAPjs.DAPLink(transport);

https://armmbed.github.io/dapjs/docs/
daplink.connect()
.then(() => daplink.disconnect())
.then(() => process.exit())
.catch(error => {
console.error(error.message || error);
process.exit();
});
```

#### Pros
- Doesn't require HID access to JavaScript in your OS.

#### Cons
- Requires a recent version of [DAPLink](https://armmbed.github.io/DAPLink/) to be installed on your target device.

## Architecture

The architecture of this project is built up in layers as follows:

### Transport

The `Transport` layer offers access to the USB device plugged into the host. Different transports are available based on user needs (see above).

### Proxy

The `Proxy` layer uses the transport layer to expose low-level `CMSIS-DAP` commands to the next layer. A common use for the proxy is as a debug chip attached to the main processor accessed over USB.

A CMSIS-DAP implementation is included, however a network proxy or similar could be introduced at this layer in order to remote commands.

### DAPLink

The `DAPLink` layer is a special derived implementation of the `CMSIS-DAP` proxy implementation. It adds DAPLink vendor specific functionality such as Mass Storage Device `firmware flashing` and `serial control`.

### DAP

The `DAP` (Debug Access Port) layer exposes low-level access to ports, registers and memory. An implementation exists for `ADI` (Arm Debug Interface).

### Processor

The `Processor` layer exposes access to the core processor registers.

## Development

After cloning this repository, install the development dependencies:

```bash
$ npm install
```

### Building

[Gulp](https://gulpjs.com/) is used as a task runner to build the project.
To build the project, simply run `gulp` or to continually build as source changes, run `gulp watch`:

```bash
$ gulp
$ gulp watch
```

A `package.json script` exists to run gulp if you don't have it installed globally:

```bash
$ npm run gulp
$ npm run gulp watch
```

### Running

A local [express](https://expressjs.com/) server is included to run the web example locally:

```bash
$ node server.js
```

The latest build of master is always available to be installed from the `gh-pages` branch:

```bash
$ npm install ARMmbed/dapjs#gh-pages
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
73 changes: 43 additions & 30 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
machine:
node:
version: 6.10.0
environment:
LIVE_BRANCH: gh-pages
version: 2

dependencies:
pre:
- sudo apt-get update
- sudo apt-get install libudev-dev
jobs:
build:
docker:
- image: circleci/node:6
steps:
- run: sudo apt-get update
- run: sudo apt-get install libudev-dev
- run: sudo apt-get install libusb-1.0-0-dev
- checkout
- run: npm install
- run: npm run gulp
- persist_to_workspace:
root: ../
paths:
- project

compile:
override:
- npm run gulp
deploy:
docker:
- image: circleci/node:6
steps:
- attach_workspace:
at: ../
- run: mkdir ~/.ssh/ && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" > ~/.ssh/config
- run: git config --global user.name thegecko
- run: git config --global user.email [email protected]
- run: git add --force bundles lib types docs
- run: git stash save
- run: git checkout gh-pages
- run: git merge master --no-commit
- run: git checkout stash -- .
- run: git commit --allow-empty --message "Automatic Deployment [skip ci]"
- run: git push

test:
override:
- exit 0

deployment:
staging:
branch: master
commands:
- echo Syncing to $LIVE_BRANCH on GitHub...
- git config --global user.name thegecko
- git config --global user.email [email protected]
- git add --force bundles lib types docs
- git stash save
- git checkout $LIVE_BRANCH
- git merge master --no-commit
- git checkout stash -- .
- git commit --allow-empty --message "Automatic Deployment [skip ci]"
- git push
workflows:
version: 2
commit:
jobs:
- build
- deploy:
requires:
- build
filters:
branches:
only: master
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit cee3cb5

Please sign in to comment.