/* * yosys -- Yosys Open SYnthesis Suite * * Copyright (C) 2012 Claire Xenia Wolf * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef SIGTOOLS_H #define SIGTOOLS_H #include "kernel/yosys.h" YOSYS_NAMESPACE_BEGIN struct SigPool { struct bitDef_t : public std::pair { bitDef_t() : std::pair(NULL, 0) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } unsigned int hash() const { return first->name.hash() + second; } }; pool bits; void clear() { bits.clear(); } void add(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL) bits.insert(bit); } void add(const SigPool &other) { for (auto &bit : other.bits) bits.insert(bit); } void del(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL) bits.erase(bit); } void del(const SigPool &other) { for (auto &bit : other.bits) bits.erase(bit); } void expand(const RTLIL::SigSpec &from, const RTLIL::SigSpec &to) { log_assert(GetSize(from) == GetSize(to)); for (int i = 0; i < GetSize(from); i++) { bitDef_t bit_from(from[i]), bit_to(to[i]); if (bit_from.first != NULL && bit_to.first != NULL && bits.count(bit_from) > 0) bits.insert(bit_to); } } RTLIL::SigSpec extract(const RTLIL::SigSpec &sig) const { RTLIL::SigSpec result; for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) result.append(bit); return result; } RTLIL::SigSpec remove(const RTLIL::SigSpec &sig) const { RTLIL::SigSpec result; for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit) == 0) result.append(bit); return result; } bool check(const RTLIL::SigBit &bit) const { return bit.wire != NULL && bits.count(bit); } bool check_any(const RTLIL::SigSpec &sig) const { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) return true; return false; } bool check_all(const RTLIL::SigSpec &sig) const { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit) == 0) return false; return true; } RTLIL::SigSpec export_one() const { for (auto &bit : bits) return RTLIL::SigSpec(bit.first, bit.second); return RTLIL::SigSpec(); } RTLIL::SigSpec export_all() const { pool sig; for (auto &bit : bits) sig.insert(RTLIL::SigBit(bit.first, bit.second)); return sig; } size_t size() const { return bits.size(); } }; template struct SigSet { static_assert(!std::is_same::value, "Default value for `Compare' class not found for SigSet. Please specify."); struct bitDef_t : public std::pair { bitDef_t() : std::pair(NULL, 0) { } bitDef_t(const RTLIL::SigBit &bit) : std::pair(bit.wire, bit.offset) { } unsigned int hash() const { return first->name.hash() + second; } }; dict> bits; void clear() { bits.clear(); } void insert(const RTLIL::SigSpec &sig, T data) { for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].insert(data); } void insert(const RTLIL::SigSpec& sig, const std::set &data) { for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].insert(data.begin(), data.end()); } void erase(const RTLIL::SigSpec& sig) { for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].clear(); } void erase(const RTLIL::SigSpec &sig, T data) { for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].erase(data); } void erase(const RTLIL::SigSpec &sig, const std::set &data) { for (const auto &bit : sig) if (bit.wire != NULL) bits[bit].erase(data.begin(), data.end()); } void find(const RTLIL::SigSpec &sig, std::set &result) { for (const auto &bit : sig) if (bit.wire != NULL) { auto &data = bits[bit]; result.insert(data.begin(), data.end()); } } void find(const RTLIL::SigSpec &sig, pool &result) { for (const auto &bit : sig) if (bit.wire != NULL) { auto &data = bits[bit]; result.insert(data.begin(), data.end()); } } std::set find(const RTLIL::SigSpec &sig) { std::set result; find(sig, result); return result; } bool has(const RTLIL::SigSpec &sig) { for (auto &bit : sig) if (bit.wire != NULL && bits.count(bit)) return true; return false; } }; template class SigSet::value>::type> : public SigSet> {}; template using sort_by_name_id_guard = typename std::enable_if::value>::type; template class SigSet> : public SigSet::type>> {}; struct SigMap { mfp database; SigMap(RTLIL::Module *module = NULL) { if (module != NULL) set(module); } void swap(SigMap &other) { database.swap(other.database); } void clear() { database.clear(); } void set(RTLIL::Module *module) { int bitcount = 0; for (auto &it : module->connections()) bitcount += it.first.size(); database.clear(); database.reserve(bitcount); for (auto &it : module->connections()) add(it.first, it.second); } void add(const RTLIL::SigSpec& from, const RTLIL::SigSpec& to) { log_assert(GetSize(from) == GetSize(to)); for (int i = 0; i < GetSize(from); i++) { int bfi = database.lookup(from[i]); int bti = database.lookup(to[i]); const RTLIL::SigBit &bf = database[bfi]; const RTLIL::SigBit &bt = database[bti]; if (bf.wire || bt.wire) { database.imerge(bfi, bti); if (bf.wire == nullptr) database.ipromote(bfi); if (bt.wire == nullptr) database.ipromote(bti); } } } void add(const RTLIL::SigBit &bit) { const auto &b = database.find(bit); if (b.wire != nullptr) database.promote(bit); } void add(const RTLIL::SigSpec &sig) { for (const auto &bit : sig) add(bit); } inline void add(Wire *wire) { return add(RTLIL::SigSpec(wire)); } void apply(RTLIL::SigBit &bit) const { bit = database.find(bit); } void apply(RTLIL::SigSpec &sig) const { for (auto &bit : sig) apply(bit); } RTLIL::SigBit operator()(RTLIL::SigBit bit) const { apply(bit); return bit; } RTLIL::SigSpec operator()(RTLIL::SigSpec sig) const { apply(sig); return sig; } RTLIL::SigSpec operator()(RTLIL::Wire *wire) const { SigSpec sig(wire); apply(sig); return sig; } RTLIL::SigSpec allbits() const { RTLIL::SigSpec sig; for (const auto &bit : database) if (bit.wire != nullptr) sig.append(bit); return sig; } }; YOSYS_NAMESPACE_END #endif /* SIGTOOLS_H */ >137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
# QMK CLI コマンド

<!---
  original document: 0.9.19:docs/cli_command.md
  git diff 0.9.19 HEAD -- docs/cli_command.md | cat
-->

# ユーザー用コマンド

## `qmk compile`

このコマンドにより、任意のディレクトリからファームウェアをコンパイルすることができます。<https://config.qmk.fm> からエクスポートした JSON をコンパイルするか、リポジトリ内でキーマップをコンパイルするか、現在の作業ディレクトリでキーボードをコンパイルすることができます。

このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。

**Configurator Exports での使い方**:

```
qmk compile <configuratorExport.json>
```

**キーマップでの使い方**:

```
qmk compile -kb <keyboard_name> -km <keymap_name>
```

**キーボードディレクトリでの使い方**:  

default キーマップのあるキーボードディレクトリ、キーボードのキーマップディレクトリ、`--keymap <keymap_name>` で与えられるキーマップディレクトリにいなければなりません。
```
qmk compile
```

**指定したキーマップをサポートする全てのキーボードをビルドする場合の使い方**:

```
qmk compile -kb all -km <keymap_name>
```

**例**:
```
$ qmk config compile.keymap=default
$ cd ~/qmk_firmware/keyboards/planck/rev6
$ qmk compile
Ψ Compiling keymap with make planck/rev6:default
...
```
あるいはオプションのキーマップ引数を指定して

```
$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4
$ qmk compile -km 66_iso
Ψ Compiling keymap with make clueboard/66/rev4:66_iso
...
```
あるいはキーマップディレクトリで

```
$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak
$ qmk compile
Ψ Compiling keymap with make make gh60/satan:colemak
...
```

**レイアウトディレクトリでの使い方**:  

`qmk_firmware/layouts/` 以下のキーマップディレクトリにいなければなりません。
```
qmk compile -kb <keyboard_name>
```

**例**:
```
$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi
$ qmk compile -kb dz60
Ψ Compiling keymap with make dz60:mechmerlin-ansi
...
```

## `qmk flash`

このコマンドは `qmk compile` に似ていますが、ブートローダを対象にすることもできます。ブートローダはオプションで、デフォルトでは `:flash` に設定されています。
違うブートローダを指定するには、`-bl <bootloader>` を使ってください。利用可能なブートローダの詳細については、[ファームウェアを書き込む](ja/flashing.md)を見てください。

このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。

**Configurator Exports での使い方**:

```
qmk flash <configuratorExport.json> -bl <bootloader>
```

**キーマップでの使い方**:

```
qmk flash -kb <keyboard_name> -km <keymap_name> -bl <bootloader>
```

**ブートローダの列挙**

```
qmk flash -b
```

## `qmk config`

このコマンドにより QMK の挙動を設定することができます。完全な `qmk config` のドキュメントについては、[CLI 設定](ja/cli_configuration.md)を見てください。

**使用法**:

```
qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN]
```

## `qmk doctor`

このコマンドは環境を調査し、潜在的なビルドあるいは書き込みの問題について警告します。必要に応じてそれらの多くを修正できます。

**使用法**:

```
qmk doctor [-y] [-n]
```

**例**:

環境に問題がないか確認し、それらを修正するよう促します:

    qmk doctor

環境を確認し、見つかった問題を自動的に修正します:

    qmk doctor -y

環境を確認し、問題のみをレポートします:

    qmk doctor -n

## `qmk info`

QMK のキーボードやキーマップに関する情報を表示します。キーボードに関する情報を取得したり、レイアウトを表示したり、基礎となるキーマトリックスを表示したり、JSON キーマップをきれいに印刷したりするのに使用できます。

**使用法**:

```
qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD]
```

このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。

**例**:

キーボードの基本情報を表示する:

    qmk info -kb planck/rev5

キーボードのマトリクスを表示する:

    qmk info -kb ergodox_ez -m

キーボードの JSON キーマップを表示する:

    qmk info -kb clueboard/california -km default

## `qmk json2c`

QMK Configurator からエクスポートしたものから keymap.c を生成します。

**使用法**:

```
qmk json2c [-o OUTPUT] filename
```

## `qmk list-keyboards`

このコマンドは現在 `qmk_firmware` で定義されている全てのキーボードを列挙します。

**使用法**:

```
qmk list-keyboards
```

## `qmk list-keymaps`

このコマンドは指定されたキーボード(とリビジョン)の全てのキーマップを列挙します。

このコマンドはディレクトリを認識します。キーボードのディレクトリにいる場合、自動的に KEYBOARD を入力します。

**使用法**:

```
qmk list-keymaps -kb planck/ez
```

## `qmk new-keymap`

このコマンドは、キーボードの既存のデフォルトのキーマップに基づいて新しいキーマップを作成します。

このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。

**使用法**:

```
qmk new-keymap [-kb KEYBOARD] [-km KEYMAP]
```

---

# 開発者用コマンド

## `qmk cformat`

このコマンドは clang-format を使って C コードを整形します。

引数無しで実行すると、変更された全てのコアコードを整形します。デフォルトでは `git diff``origin/master` をチェックし、ブランチは `-b <branch_name>` を使って変更できます。

`-a` で全てのコアコードを整形するか、コマンドラインでファイル名を渡して特定のファイルに対して実行します。

**指定したファイルに対する使い方**:

```
qmk cformat [file1] [file2] [...] [fileN]
```

**全てのコアファイルに対する使い方**:

```
qmk cformat -a
```

**origin/master で変更されたファイルのみに対する使い方**:

```
qmk cformat
```

**branch_name で変更されたファイルのみに対する使い方**:

```
qmk cformat -b branch_name
```

## `qmk docs`

このコマンドは、ドキュメントを参照または改善するために使うことができるローカル HTTP サーバを起動します。デフォルトのポートは 8936 です。

**使用法**:

```
qmk docs [-p PORT]
```

## `qmk kle2json`

このコマンドにより、生の KLE データから QMK Configurator の JSON へ変換することができます。絶対パスあるいは現在のディレクトリ内のファイル名のいずれかを受け取ります。デフォルトでは、`info.json` が既に存在している場合は上書きしません。上書きするには、`-f` あるいは `--force` フラグを使ってください。

**使用法**:

```
qmk kle2json [-f] <filename>
```

**例**:

```
$ qmk kle2json kle.txt 
☒ File info.json already exists, use -f or --force to overwrite.
```

```
$ qmk kle2json -f kle.txt -f
Ψ Wrote out to info.json
```

## `qmk pyformat`

このコマンドは `qmk_firmware` 内の python コードを整形します。

**使用法**:

```
qmk pyformat
```

## `qmk pytest`

このコマンドは python のテストスィートを実行します。python コードに変更を加えた場合、これの実行が成功することを確認する必要があります。

**使用法**:

```
qmk pytest
```