システム設定>一般>プライバシーとセキュリティ>ローカルネットワーク
で
VNC Viewerのスライドボタンをオンにする。
以上
Raspberry Pi zero 2Wでピンヘッダからマイコン等とシリアル通信する。
まずシリアルコンソールを無効化する。
デフォルトでは/dev/serial0はLinuxコンソールに割り当てられているのでraspi-configで無効化する。
GUIからだとraspi-config>インターフェイスに入り
シリアルポート: 有効
シリアルコンソール: 無効
を選択し
すると再起動するかと聞かれるので再起動する。
次にBluetoothモジュールの接続を切り替える。
デフォルトでは
/dev/serial0 -> /dev/ttyS0
/dev/serial1 -> /dev/ttyAMA0
とシンボリックリンクが張られている。このままではBluetoothモジュールがUART0(/dev/ttyAMA0)を使ってしまっているので切り替えが必要。
一つの方法はdisable-btでBluetoothを無効化する方法。ただしこれだと多分Bluetoothが全く使えなくなる。
もう一つの方法はminiuart-btという方法で、こちらはBluetoothをmini UART(/dev/ttyS0)に割り当てる。結果的にBluetoothの速度は低下するが使えなくなることはない。
今回はこちらを採用する。
$ sudo nano /boot/config.txt # Use miniUART to connect to Bluetooth module dtoverlay=miniuart-bt core_freq=250
というふうに追記し、もう一度再起動する。
これによって
/dev/serial0 -> /dev/ttyAMA0
/dev/serial1 -> /dev/ttyS0
と入れ替わり、Primary UART(/dev/serial0)がUART0(/dev/ttyAMA0)のシンボリックリンクとなる。
この状態で
$ screen /dev/ttyAMA0 115200 8N1
のようにしてやればシリアル通信ができるようになっている。
なお使用するピンは8番ピンがTxDで、10番ピンがRxD、6番ピンのGNDと並びで3つのピンを3.3vマイコンのUART IOに直結で通信が可能である。
まちがって5Vの機器やRS232Cレベルと直結するとあっけなく壊れるらしいので要注意。
Ubuntu20.04にアップグレードできたことだし、Linuxマシンとして色々使うならやはりanaconda入れておきたいよね、と思ったんだがどうやらこれもまたJetsonNanoでは一筋縄では行かないらしい。
aarch64用のminiconda-likeな環境であるminiforge(https://github.com/conda-forge/miniforge)
をインストールするといいらしい。
方法はGitHubのページの通り。
確かにこれでcondaも使えるようになった。
メイン言語がpythonだからこれはありがたい。pythonのバージョンも3.10.14が入ったし。
特に2Gの方はこれでエッジAIとかなかなか厳しいから簡易なpython開発環境くらいがちょうどいいかな。ubuntuサーバのローカルテストベッドくらいで使うのがちょうどいいと思う。
長いことほったらかしにしていたJetson Nano 2GBの電源を久々に入れてみたら、Ubuntu18.04だった。
B01のほうすらほとんど使い道がなくて放置しているけど、あれは20.04にはしてあったはず。
というわけでいちおうシステムをアップデートしておこう。
多分トラブル頻発してすんなり行かないから記録しつつやってみよう。
まずは
sudo apt update && sudo apt -y upgrade
あ、なんだ、すんなりいけた。
sudo apt -y dist-upgrade && sudo apt -y autoremove
なんかchromiumをアンインストールしておかないとダメらしい。
sudo apt-get remove --purge chromium-browser chromium-browser-l10n
そして
sudo nano /etc/update-manager/release-upgrades
で、一番下の行の
prompt=never
を
prompt=normal
に変える。
一旦再起動して、
sudo do-release-upgrade
あれ?やっぱりここでだめだ。インデックスファイルのダウンロードが失敗して
システムを元に戻しています
中断します
とか言われてプロンプトに戻ってしまうよ。
んー。素直にJetPackをバージョンの上がったものにして再インストールかな。
と思ったらJetson NanoはB01も2GBもubuntu18.04ベースのJetPack4.6.4以上は対応してないのね。
ちょっと製品寿命短すぎない?
とりあえずJetPackをNanoの最終バージョンである4.6.4にしてクリーンインストールし、設定を一通りやった上で、上記のウップグレードをもう一度試してみる。
その結果無事に20.04にアップデートできた。
~$ screenfetch ./+o+- kkuro@kkuro-JN-2G yyyyy- -yyyyyy+ OS: Ubuntu 20.04 focal ://+//////-yyyyyyo Kernel: aarch64 Linux 4.9.253-tegra .++ .:/++++++/-.+sss/` Uptime: 12m .:++o: /++++++++/:--:/- Packages: 2465 o:+o+:++.`..```.-/oo+++++/ Shell: bash 5.0.17 .:+o:+o/. `+sssoo+/ Disk: 19G / 30G (68%) .++/+:+oo+o:` /sssooo. CPU: ARMv8 rev 1 (v8l) @ 4x 1.479GHz /+++//+:`oo+o /::--:. RAM: 730MiB / 1971MiB \+/+o+++`o++o ++////. .++.o+++oo+:` /dddhhh. .+.o+oo:. `oddhhhh+ \+.++o+o``-````.:ohdhhhhh+ `:o+++ `ohhhhhhhhyo++os: .o:`.syhhhhhhh/.oo++o` /osyyyyyyo++ooo+++/ ````` +oo+++o\: `oo++.
ちなみになんで今更Jetson Nanoなんて持ち出したかというと学会のポスターとしてディスプレイを貼り付けてやって、chromeのキオスクモードを使ってインタラクティブにいじれるとおもしろうそうかな、と思って、PCを持っていくのもアレなのでJetsonでいいんじゃないか?と思ったのでした。
時系列や各種処理を与えたサンプル間で比較するなら、それらをマージして同じクラスターで重ね合わせて考えたい。
まずはumapチャートを出力するまで。4つの実験区の比較を行う例をやってみたい。Seuratのハンズオンでは2区の重ね合わせなんだけど、実際に10xの出力として保存されたデータからではなく、ライブラリからサンプルデータを読み出して処理しており、実際的ではない。なのでCellrangerの出力するfiltered_feature_bc_matrixフォルダに3つのファイル(barcode.tsv.gz, features.tsv.gz, matrix.mtx.gz)が保存されているところをスタートとした解析を試してみる。
if(!require(Seurat)){install.packages("Seurat")} if(!require(patchwork)){install.packages("patchwork")} if(!require(dplyr)){install.packages("dplyr")} library(Seurat) library(patchwork) install.packages('BiocManager') # Bioconductorのバージョンを設定 BiocManager::install(version = "3.19") BiocManager::install('glmGamPoi') #####Remove all objects before running##### rm(list = ls()) input.dir <- "/path/to/sample/" # サンプル1のデータセットを読み込む sample1 <- Read10X(paste(input.dir, "sample1/filtered_feature_bc_matrix", sep="")) # サンプル2のデータセットを読み込む sample2 <- Read10X(paste(input.dir, "sample2/filtered_feature_bc_matrix", sep="")) # サンプル3のデータセットを読み込む sample3 <- Read10X(paste(input.dir, "sample3/filtered_feature_bc_matrix", sep="")) # サンプル4のデータセットを読み込む sample4 <- Read10X(paste(input.dir, "sample4/filtered_feature_bc_matrix", sep="")) sample1 <- CreateSeuratObject(counts = sample1, project = "sample1") sample2 <- CreateSeuratObject(counts = sample2, project = "sample2") sample3 <- CreateSeuratObject(counts = sample3, project = "sample3") sample4 <- CreateSeuratObject(counts = sample4, project = "sample4") # 各データセットにユニークなセル識別子を追加 sample1 <- RenameCells(sample1, new.names = paste("sample1", Cells(sample1), sep = "_")) sample2 <- RenameCells(sample2, new.names = paste("sample2", Cells(sample2), sep = "_")) sample3 <- RenameCells(sample3, new.names = paste("sample3", Cells(sample3), sep = "_")) sample4 <- RenameCells(sample4, new.names = paste("sample4", Cells(sample4), sep = "_")) # サンプルデータセットのリストを作成 datasets <- list(sample1, sample2, sample3, sample4) # データセットの前処理 datasets <- lapply(datasets, function(x) { x <- SCTransform(x, verbose = FALSE) x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 2000) x }) # 統合のためのアンカーフィーチャーの選択 features <- SelectIntegrationFeatures(object.list = datasets, nfeatures = 2000) # SCT正規化を使用した統合アンカーの発見 datasets <- PrepSCTIntegration(object.list = datasets, anchor.features = features) anchors <- FindIntegrationAnchors(object.list = datasets, normalization.method = "SCT", anchor.features = features) # データセットの統合 combined <- IntegrateData(anchorset = anchors, normalization.method = "SCT") # 統合データの次の解析ステップ combined <- ScaleData(combined, verbose = FALSE) combined <- RunPCA(combined, npcs = 30, verbose = FALSE) combined <- RunUMAP(combined, reduction = "pca", dims = 1:30) combined <- FindNeighbors(combined, reduction = "pca", dims = 1:30) combined <- FindClusters(combined, resolution = 0.5) # ここでデータを一旦保存しておく # 後で読み込むときはcombined <- readRDS(file =paste(input.dir, "combined.rds", sep="")) saveRDS(combined, file = paste(input.dir, "combined.rds", sep="")) # 結果の可視化 p1 <- DimPlot(combined, reduction = "umap", group.by = "orig.ident") p2 <- DimPlot(combined, reduction = "umap", label = TRUE, repel = TRUE) p1 + p2 DimPlot(combined, reduction = "umap", split.by = "orig.ident") # 出来上がったクラスターに名前をつけることができる combined <- RenameIdents(combined, `0` = "Cluster 0", `1` = "Cluster 1", `2` = "Cluster 2", `3` = "Cluster 3") DimPlot(combined, label = TRUE) # マーカー遺伝子の可視化 markers.to.plot <- c("GeneA", "GeneB", "GeneC") DotPlot(combined, features = markers.to.plot, cols = c("blue", "red"), dot.scale = 8, split.by = "orig.ident") + RotatedAxis() # Find Differentially Expressed Genes: fold_change_threshold <- 0.25 pct_threshold <- 0.25 p_value_threshold <- 0.01 # クラスタごとのDEG all_markers <- FindAllMarkers( object = combined, only.pos = FALSE, min.pct = pct_threshold, logfc.threshold = fold_change_threshold, test.use = "wilcox" ) # p値でフィルタリング significant_markers <- all_markers[all_markers$p_val_adj < p_value_threshold, ] # 結果をCSVファイルとして保存 write.csv(significant_markers, file = "Differentially_Expressed_Genes.csv", row.names = FALSE) # 上位10個のDEGを可視化 top10 <- significant_markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_log2FC) pdf(file = "Top10_Differentially_Expressed_Genes.pdf", width = 8.27, height = 11.69) DoHeatmap(combined, features = top10$gene) + NoLegend() dev.off()
ちょっとごちゃごちゃしてきたので一旦整理すると
#Seuartパッケージのインストール install.packages('Seurat') library(Seurat) #テストファイルの準備とdirectoryの移動 setwd("~/scrnaseqtest/immune_alignment_matrix/") #data読み込み ctrl.data <- read.table("immune_control_expression_matrix.txt", sep = '\t', row.names = 1) stim.data <- read.table("immune_stimulated_expression_matrix.txt", sep = "\t", row.names = 1) #Seuratオブジェクトの作成 ctrl <- CreateSeuratObject(counts = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5) stim <- CreateSeuratObject(counts = stim.data, project = "IMMUNE_STIM", min.cells = 5) #metadataの付与 ctrl@meta.data$ctrl <- "CTRL" stim@meta.data$stim <- "STIM" #フィルタリング ctrl <- subset(ctrl, subset = nFeature_RNA > 500) stim <- subset(stim, subset = nFeature_RNA > 500) #正規化 ctrl <- NormalizeData(ctrl, scale.factor = 10000) stim <- NormalizeData(stim, scale.factor = 10000) #Z-Scoreの算出 ctrl <- ScaleData(ctrl) stim <- ScaleData(stim) #使用する遺伝子の選定 ctrl <- FindVariableFeatures(ctrl) stim <- FindVariableFeatures(stim) # 上位1000の変動遺伝子を取得 g.1 <- head(VariableFeatures(ctrl), 1000) g.2 <- head(VariableFeatures(stim), 1000) #g1、g2で共通して発現変動の大きい遺伝子をunique関数で抽出 genes.use <- unique(c(g.1, g.2)) scaled_genes <- rownames(GetAssayData(ctrl, slot = "scale.data")) genes.use <- intersect(genes.use, scaled_genes) scaled_genes <- rownames(GetAssayData(stim, slot = "scale.data")) genes.use <- intersect(genes.use, scaled_genes)
とりあえずここまでは良さげ。
データを可視化していく。
CCA(Canonical Correlation Analysis)によるオブジェクトのマージ
# データセットをリストにまとめる immune.list <- list(ctrl = ctrl, stim = stim) # アンカーを見つける anchors <- FindIntegrationAnchors(object.list = immune.list, anchor.features = genes.use) # データセットの統合 immune.combined <- IntegrateData(anchorset = anchors, dims = 1:30) # 統合データのスケーリングと主成分分析 immune.combined <- ScaleData(immune.combined) immune.combined <- RunPCA(immune.combined)
PCAのプロットを出してみる
# 次元削減結果のプロット p1 <- DimPlot(object = immune.combined, reduction = "pca", group.by = "stim", pt.size = 0.5) p1
PC_1をy軸に取ったViolin plot
p2 <- VlnPlot(object = immune.combined, features = "PC_1", group.by = "stim") p2
各次元の重要な遺伝子のヒートマップを表示
DimHeatmap(object = immune.combined, dims = 1:2, cells = 500, balanced = TRUE)
とりあえずできた気になっているが、自分のデータで意味のある解析ができるかというとかなり怪しい。
とりあえずSeuratというRのパッケージで解析すると良いらしい。
ちなみに10xのCell Rangerでマッピングまではやっている前提で。
こちらの情報を参考にやってみることにする。ちょっと古いけど大丈夫かな?
Seuratを駆使する会 ① - ばいばいバイオ
Rはほんとうに敬遠していて何もわからないのだけど。
まずはパッケージをインストールから
わからないなりに環境だけいっちょ前にLinux上に構築してRStudioサーバを建ててあり、ネット越しにブラウザでアクセスして解析ができるようにしていたりする。なにもわからないのに。
Rのバージョンは4.4.0である。
> install.packages('Seuart')
とするといつ終わるかもわからないくらいずらずらとメッセージが流れる。
幸い、致命的エラーは出ずにインストールできたらしい。
> library(Seuart)
ライブラリインポートも問題なくできたっぽい。
さて、チュートリアルを一通りやっておこう。
ConsoleタブからTerminalタブに切り替えて、
$ mkdir scrnaseqtest (ngs) kuro@guilty6-x2110:~$ cd scrnaseqtest/ (ngs) kuro@guilty6-x2110:~/scrnaseqtest$ mkdir immune_alignment_matrix (ngs) kuro@guilty6-x2110:~/scrnaseqtest$ cd immune_alignment_matrix/ (ngs) kuro@guilty6-x2110:~/scrnaseqtest/immune_alignment_matrix$ wget https://www.dropbox.com/s/79q6dttg8yl20zg/immune_alignment_expression_matrices.zip `immune_alignment_expression_matrices.zip' へ保存完了 [21329741/21329741] (ngs) kuro@guilty6-x2110:~/scrnaseqtest/immune_alignment_matrix$ unzip immune_alignment_expression_matrices.zip Archive: immune_alignment_expression_matrices.zip inflating: immune_control_expression_matrix.txt.gz creating: __MACOSX/ inflating: __MACOSX/._immune_control_expression_matrix.txt.gz inflating: immune_stimulated_expression_matrix.txt.gz inflating: __MACOSX/._immune_stimulated_expression_matrix.txt.gz (ngs) kuro@guilty6-x2110:~/scrnaseqtest/immune_alignment_matrix$ rm immune_alignment_expression_matrices.zip (ngs) kuro@guilty6-x2110:~/scrnaseqtest/immune_alignment_matrix$ gunzip immune_control_expression_matrix.txt.gz (ngs) kuro@guilty6-x2110:~/scrnaseqtest/immune_alignment_matrix$ gunzip immune_stimulated_expression_matrix.txt.gz
と、これで下準備OK
さてConsoleに戻って
> ctrl.data <- read.table("immune_control_expression_matrix.txt", sep = '\t', row.names = 1) file(file, "rt") でエラー: コネクションを開くことができません 追加情報: 警告メッセージ: file(file, "rt") で: ファイル 'immune_control_expression_matrix.txt' を開くことができません: そのようなファイルやディレクトリはありません
ああ、そうかディレクトリを移動しないといけないのか。どうやって?(このレベルです)
> setwd("~/scrnaseqtest/immune_alignment_matrix/") > ctrl.data <- read.table("immune_control_expression_matrix.txt", sep = '\t', row.names = 1) > stim.data <- read.table("immune_stimulated_expression_matrix.txt", sep = "\t", row.names = 1) > ctrl <- CreateSeuratObject(raw.data = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5) CreateSeuratObject(raw.data = ctrl.data, project = "IMMUNE_CTRL", でエラー: 引数 "counts" がありませんし、省略時既定値もありません
またひっかかる。どうもバージョン3のSeuratでなにか変わっているらしい。なのでチャットGPTの出番。
エラーの原因は、CreateSeuratObject 関数の引数の名前が変更されたためです。Seuratのバージョン3以降では、raw.data 引数が counts 引数に変更されました。
> ctrl <- CreateSeuratObject(counts = ctrl.data, project = "IMMUNE_CTRL", min.cells = 5) 警告: Feature names cannot have underscores ('_'), replacing with dashes ('-') 警告: Data is of class data.frame. Coercing to dgCMatrix.
なんか警告は出たけどいいらしい。
続いてmetadataの付与
> ctrl@meta.data$stim <- "CTRL" > head(ctrl@meta.data$stim) [1] "CTRL" "CTRL" "CTRL" "CTRL" "CTRL" "CTRL"
フィルタリング
> ctrl <- FilterCells(ctrl, subset.names = "nGene", low.thresholds = 500, high.thresholds = Inf) FilterCells(ctrl, subset.names = "nGene", low.thresholds = 500, でエラー: 関数 "FilterCells" を見つけることができませんでした
chatGPT
FilterCells 関数は、Seuratのバージョン3以降では廃止されました。代わりに、subset 関数を使用します。
らしい。
> ctrl <- subset(ctrl, subset = nFeature_RNA > 500)
正規化
> ctrl <- NormalizeData(ctrl, scale.factor = 10000) Normalizing layer: counts Performing log-normalization 0% 10 20 30 40 50 60 70 80 90 100% [----|----|----|----|----|----|----|----|----|----| **************************************************|
z-scoreの算出
> ctrl <- ScaleData(ctrl) Centering and scaling data matrix |=================================================================================================================| 100%
同様にstimulatedのほうも
> stim <- CreateSeuratObject(counts = stim.data, project = "IMMUNE_STIM", min.cells = 5) 警告: Feature names cannot have underscores ('_'), replacing with dashes ('-') 警告: Data is of class data.frame. Coercing to dgCMatrix. > stim@meta.data$stim <- "STIM" > stim <- subset(stim, subset = nFeature_RNA > 500) > stim <- NormalizeData(stim) Normalizing layer: counts Performing log-normalization 0% 10 20 30 40 50 60 70 80 90 100% [----|----|----|----|----|----|----|----|----|----| **************************************************| > stim <- ScaleData(stim) Centering and scaling data matrix |=================================================================================================================| 100%
分散の大きい(発現変動の大きい)遺伝子を抽出
> ctrl <- FindVariableGenes(ctrl) FindVariableGenes(ctrl) でエラー: 関数 "FindVariableGenes" を見つけることができませんでした > ctrl <- FindVariableFeatures(ctrl) Finding variable features for layer counts Calculating gene variances 0% 10 20 30 40 50 60 70 80 90 100% [----|----|----|----|----|----|----|----|----|----| **************************************************| Calculating feature variances of standardized and clipped values 0% 10 20 30 40 50 60 70 80 90 100% [----|----|----|----|----|----|----|----|----|----| **************************************************|
FindVariableGenes 関数も、Seuratのバージョン3以降では廃止されました。代わりに FindVariableFeatures 関数を使用します。
> g.1 <- head(rownames(ctrl@hvg.info), 1000) dimnames(x)[[1L]] %||% if (do.NULL) NULL else { でエラー: 名前 "hvg.info" というスロットが、クラス "Seurat" のこのオブジェクトには存在しません > # 上位1000の変動遺伝子を取得 > g.1 <- head(VariableFeatures(ctrl), 1000) > g.2 <- head(VariableFeatures(stim), 1000)
hvg.info スロットも Seurat のバージョン3以降では変更されています。変動遺伝子の情報は VariableFeatures スロットに格納されています。
g1、g2で共通して発現変動の大きい遺伝子をunique関数で抽出
> genes.use <- unique(c(g.1, g.2)) > genes.use <- intersect(genes.use, rownames(ctrl@scale.data)) dimnames(x)[[1L]] %||% if (do.NULL) NULL else { でエラー: 名前 "scale.data" というスロットが、クラス "Seurat" のこのオブジェクトには存在しません
scale.data スロットはSeuratのバージョン3以降では存在しません。代わりに ScaleData 関数を使用してデータをスケーリングし、ctrl"RNA"@scale.data からスケールされたデータにアクセスできます。
だそうで
> genes.use <- intersect(genes.use, rownames(ctrl[["RNA"]]@scale.data)) dimnames(x)[[1L]] %||% if (do.NULL) NULL else { でエラー: 名前 "scale.data" というスロットが、クラス "Assay5" のこのオブジェクトには存在しません
まだだめ。
scale.data スロットが存在しないというエラーは、Seuratのバージョンによる変更の結果です。現在のSeuratバージョンでは、スケールされたデータは scale.data スロットではなく、ScaleData 関数が返すオブジェクト内に格納されます。
> scaled_genes <- rownames(ctrl[["RNA"]]@data) dimnames(x)[[1L]] %||% if (do.NULL) NULL else { でエラー: 名前 "data" というスロットが、クラス "Assay5" のこのオブジェクトには存在しません
Seuratの最新バージョンでは、スケールされたデータは ScaleData 関数の出力として直接取得できないため、正しいスロットにアクセスする必要があります。スケーリングされたデータは通常、ctrl"RNA"@scale.data ではなく、ctrl"RNA"@scale.data に格納されます。
しかし、最新のバージョンではスケールデータが標準的なアクセス方法ではなく、GetAssayData 関数を使う必要があります。
> scaled_genes <- rownames(GetAssayData(ctrl, slot = "scale.data")) 警告メッセージ: The `slot` argument of `GetAssayData()` is deprecated as of SeuratObject 5.0.0. ℹ Please use the `layer` argument instead. This warning is displayed once every 8 hours. Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated. > genes.use <- intersect(genes.use, scaled_genes)
なんかあやしくなってきたぞ?
一旦停止して整理する。
どうもこれに入っているLinuxはTina-LinuxといってOpenWRTに由来する組み込みLinuxらしいとの情報を得た。
Allwinner Tina Linux · GitHub
https://d1.docs.aw-ol.com/en/study/study_1tina/
OpenWRT懐かしい。2008年頃、FONという無線LANをみんなでシェアしようと言う趣旨のプロジェクトがあって、そこで安価で配布された無線LANルータのFoneraという装置があった。このFoneraの基板には意味ありげなピンヘッダが立っていて、それがシリアルコンソールであることに気がついた人たちのあいだで、そのコンソールからファームウェアを流し込んでもとの無線LANルータ機能を上書きしてしまうハックが流行った。そこで使われていたのがOpenWRTであった。基本無線LANルータとしてのファームウェアなんだけど、実態としては組み込みLinuxだということで、無線LANルータとしてではなく、安価なLinuxboxとして使ってしまおうというプロジェクトも派生していった。基板上のパターンを解析してSDカードを乗せるSPI接続を実現したり、シリアル通信でArduinoと接続してIOを制御したり、まさに現在、ラズベリーパイがやっているようなことを先駆けてやっていたのよね。当然GUIが動くほどの能力がルータのSOCにあるはずもなく、すべてCUI。多くのコマンドが入っているBusyBoxを駆使しまくってた。WebサーバとかSDカードを使ったファイル共有サーバとか温湿度計を繋いでエアコンリモート制御とか。
で、MAiX ll DOCKですよ。
BusyBox v1.27.2 () built-in shell (ash) ------run profile file----- _ .-') ('-. ) (`-. ( '.( OO )_ ( OO ).-. ( OO ). ,--. ,--.) / . --. / ,-.-')(_/. \_)-. | `.' | | \-. \ | |OO)\ `.' / | |.-'-' | | | | \ \ /\ | |'.'| | \| |_.' | | |(_/ \ \ | | | | | | .-. | ,| |_.' .' \_) | | | | | | | |(_| | / .'. \ `--' `--' `--' `--' `--' '--' '--' __ _ / / (_)__ __ ____ __ ------------------------ / /__/ / _ \/ // /\ \ / sipeed.com (Neptune) /____/_/_//_/\_,_//_\_\ ------------------------
ほらBusyBoxじゃん。
ということでかつてのお約束のようにシリアルコンソール接続でログインを試みる。
その前にネットワークにつなぐ設定をしておく。SDカードをカードリーダーで覗くとトップディレクトリにWIFIの設定ファイル wpa_supplicant.conf があるので、SSIDとパスワードを入力しておく。
(追記)技適取れてないので無線接続はしてはいけません。日本語の情報が極端に少ないのはこのせいか。
USBでMacとつなぐと/dev/cu.usbserial-14330が現れるので
cu -l /dev/cu.usbserial-14330 -s 115200
としてやってMAiXをリセットすると
Last login: Fri May 17 13:58:12 on ttys002 The default interactive shell is now zsh. To update your account to use zsh, please run `chsh -s /bin/zsh`. For more details, please visit https://support.apple.com/kb/HT208050. ------run rc.modules file----- ------run rc.final file----- Load mpp modules insmod: can't insert '/lib/modules/4.9.118/videobuf2-core.ko': No such file or directory insmod: can't insert '/lib/modules/4.9.118/videobuf2-memops.ko': No such file or directory insmod: can't insert '/lib/modules/4.9.118/videobuf2-v4l2.ko': No such file or directory load /etc/asound.conf ... alsactl: set_control:1461: Cannot write control '2:0:0:codec trigger playback time value:0' : Operation not permitted alsactl: set_control:1461: Cannot write control '2:0:0:codec trigger capture time value:0' : Operation not permitted exist /root/wpa_supplicant.conf Starting app... enable android usb Initializing random number generator... done. Starting network... Start dropbear: OK Starting ntpd: done BusyBox v1.27.2 () built-in shell (ash) ------run profile file----- _ .-') ('-. ) (`-. ( '.( OO )_ ( OO ).-. ( OO ). ,--. ,--.) / . --. / ,-.-')(_/. \_)-. | `.' | | \-. \ | |OO)\ `.' / | |.-'-' | | | | \ \ /\ | |'.'| | \| |_.' | | |(_/ \ \ | | | | | | .-. | ,| |_.' .' \_) | | | | | | | |(_| | / .'. \ `--' `--' `--' `--' `--' '--' '--' __ _ / / (_)__ __ ____ __ ------------------------ / /__/ / _ \/ // /\ \ / sipeed.com (Neptune) /____/_/_//_/\_,_//_\_\ ------------------------ root@sipeed:/# WARNING: Logging before InitGoogleLogging() is written to STDERR I0522 03:02:09.853097 795 dup2SeldomUsedFd.c:20] <dup2SeldomUsedFdInit> gFdLock init Successfully initialized wpa_supplicant udhcpc: started, v1.27.2 udhcpc: sending discover I0522 03:02:10.799209 795 mpi_sys.c:766] <AW_MPI_SYS_SetConf> kfctmpdir is [/tmp] I0522 03:02:10.800760 795 mpi_sys.c:1195] <AW_MPI_SYS_Init> ISP init I0522 03:02:10.800925 795 mpi_sys.c:1197] <AW_MPI_SYS_Init> ISP init done I0522 03:02:10.807874 795 hwdisplay.c:83] <hw_display_init> <(hwd_init 989)d_init:989> 95 hwdisplay.c:989] I0522 03:02:10.808255 795 hwdisplay.c:1044] <hwd_init> <hwd_iniret[0][2,0]ch[2]lyl[0] init: enable[1], screenwin[0,0, 240x240], zorder[16], alpha[mode:0, value:255] I0522 03:02:10.808458 795 alsa_interface.c:659] <alsaOpenMixer> open mixer:hw:0 I0522 03:02:10.848054 795 alsa_interface.c:721] <alsaOpenMixer> set player pa switch level 0 I0522 03:02:10.848312 795 alsa_interface.c:709] <alsaOpenMixer> set playback vol_val to value: 27 E0522 03:02:10.969903 795 video_buffer_manager.c:211] <VideoBufMgrCreate> Alloc 20 input frame buffers in list manager. E0522 03:02:10.970302 795 VideoVirVi_Component.c:481] <VideoViSetViDevAttr> fps 20 nbufs 3 E0522 03:02:11.001482 795 video_buffer_manager.c:211] <VideoBufMgrCreate> Alloc 20 input frame buffers in list manager. E0522 03:02:11.001873 795 VideoVirVi_Component.c:481] <VideoViSetViDevAttr> fps 20 nbufs 3 I0522 03:02:11.002887 795 hwdisplay.c:1244] <hwd_get_disp_type>Current the disp_type:0x1 tv_mode:0x0 I0522 03:02:11.003194 795 hwdisplay.c:1117] <hwd_layer_request_hlay:0, zorder=0, cnt:2t_hlay:1117> I0522 03:02:11.003396 795 mpi_vo.c:1030] <AW_MPI_VO_SetVideoLayerAttr> ch[0]lyl[0]:dispRect changed, [0, 0, 320x240]->[0, 0, 240x240] I0522 03:02:11.003574 795 hwdisplay.c:408] <hwd_layer_set_rectch[0]lyl[0]: screen_win[0,0, 240x240] E0522 03:02:11.004062 795 vo.c:683] <vo_init> debuf create vo channel[0] success! I0522 03:02:11.004436 896 Clock_Component.c:1109] <Clock_ComponentThread> ClockComp state[0x1]->Idle! E0522 03:02:11.004617 795 vo.c:718] <vo_init> debuf create clock channel[0] success! I0522 03:02:11.004777 896 cedarx_avs_counter.c:148] <avscounter_start> (f:avscounter_start, l:148) Avscounter status [pause]->[run], pauseDuration[0][0]ms I0522 03:02:11.004956 795 hwdisplay.c:1117] <hwd_layer_request_hlay:9, zorder=9, cnt:3t_hlay:1117> I0522 03:02:11.005098 795 mpi_vo.c:1030] <AW_MPI_VO_SetVideoLayerAttr> ch[2]lyl[1]:dispRect changed, [0, 0, 320x240]->[0, 0, 240x240] I0522 03:02:11.005194 795 hwdisplay.c:408] <hwd_layer_set_rectch[2]lyl[1]: screen_win[0,0, 240x240] I0522 03:02:11.005291 795 mpi_vo.c:1130] <AW_MPI_VO_SetVideoLayerAlpha> video layer alpha changed, [0, 128]->[0, 25] E0522 03:02:11.006791 795 vo.c:454] <CreateVoUiLayer> create vo channel[0] success! udhcpc: sending discover before paHostApiInitializers[0]. ALSA version (build): 1.1.4.1 ALSA version (runtime): 1.1.4.1 BuildDeviceList: Ignoring ALSA plugin device [cards] of type [unknown] BuildDeviceList: Found plugin [default] of type [unknown] BuildDeviceList: Found plugin [sysdefault] of type [unknown] BuildDeviceList: Found plugin [front] of type [unknown] BuildDeviceList: Found plugin [rear] of type [unknown] BuildDeviceList: Found plugin [center_lfe] of type [unknown] BuildDeviceList: Found plugin [side] of type [unknown] BuildDeviceList: Found plugin [surround21] of type [unknown] BuildDeviceList: Found plugin [surround40] of type [unknown] BuildDeviceList: Found plugin [surround41] of type [unknown] BuildDeviceList: Found plugin [surround50] of type [unknown] BuildDeviceList: Found plugin [surround51] of type [unknown] BuildDeviceList: Found plugin [surround71] of type [unknown] BuildDeviceList: Found plugin [iec958] of type [unknown] BuildDeviceList: Found plugin [spdif] of type [unknown] BuildDeviceList: Found plugin [hdmi] of type [unknown] BuildDeviceList: Found plugin [dmix] of type [unknown] BuildDeviceList: Ignoring ALSA plugin device [dsnoop] of type [unknown] BuildDeviceList: Found plugin [modem] of type [unknown] BuildDeviceList: Found plugin [phoneline] of type [unknown] BuildDeviceList: Ignoring ALSA plugin device [hw] of type [hw] BuildDeviceList: Ignoring ALSA plugin device [plughw] of type [plug] BuildDeviceList: Ignoring ALSA plugin device [plug] of type [plug] BuildDeviceList: Ignoring ALSA plugin device [shm] of type [shm] BuildDeviceList: Ignoring ALSA plugin device [tee] of type [file] BuildDeviceList: Ignoring ALSA plugin device [file] of type [file] BuildDeviceList: Ignoring ALSA plugin device [null] of type [null] BuildDeviceList: Filling device info for 19 devices FillInDevInfo: Filling device info for: sun8iw19-codec: - (hw:0,0) GropeDevice: collecting info .. GropeDevice: collecting info .. Default input device: sun8iw19-codec: - (hw:0,0) Default output device: sun8iw19-codec: - (hw:0,0) FillInDevInfo: Adding device sun8iw19-codec: - (hw:0,0): 0 FillInDevInfo: Filling device info for: sysdefault GropeDevice: collecting info .. GropeDevice: Limiting number of plugin channels to 128 GropeDevice: collecting info .. GropeDevice: Limiting number of plugin channels to 128 FillInDevInfo: Adding device sysdefault: 1 FillInDevInfo: Filling device info for: front ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.front OpenPcm: Opened device 'front' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: front, all channels == 0 FillInDevInfo: Filling device info for: rear ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear OpenPcm: Opened device 'rear' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: rear, all channels == 0 FillInDevInfo: Filling device info for: center_lfe ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe OpenPcm: Opened device 'center_lfe' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: center_lfe, all channels == 0 FillInDevInfo: Filling device info for: side ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side OpenPcm: Opened device 'side' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: side, all channels == 0 FillInDevInfo: Filling device info for: surround21 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 OpenPcm: Opened device 'surround21' ptr[0] - result: [-2:No such file or directory] ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround21 OpenPcm: Opened device 'surround21' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround21, all channels == 0 FillInDevInfo: Filling device info for: surround40 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround40 OpenPcm: Opened device 'surround40' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround40, all channels == 0 FillInDevInfo: Filling device info for: surround41 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround41 OpenPcm: Opened device 'surround41' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround41, all channels == 0 FillInDevInfo: Filling device info for: surround50 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround50 OpenPcm: Opened device 'surround50' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround50, all channels == 0 FillInDevInfo: Filling device info for: surround51 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround51 OpenPcm: Opened device 'surround51' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround51, all channels == 0 FillInDevInfo: Filling device info for: surround71 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.surround71 OpenPcm: Opened device 'surround71' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: surround71, all channels == 0 FillInDevInfo: Filling device info for: iec958 ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 OpenPcm: Opened device 'iec958' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: iec958, all channels == 0 FillInDevInfo: Filling device info for: spdif ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 OpenPcm: Opened device 'spdif' ptr[0] - result: [-2:No such file or directory] ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.iec958 OpenPcm: Opened device 'spdif' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: spdif, all channels == 0 FillInDevInfo: Filling device info for: hdmi ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi OpenPcm: Opened device 'hdmi' ptr[0] - result: [-2:No such file or directory] ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi OpenPcm: Opened device 'hdmi' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: hdmi, all channels == 0 FillInDevInfo: Filling device info for: modem ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem OpenPcm: Opened device 'modem' ptr[0] - result: [-2:No such file or directory] ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem OpenPcm: Opened device 'modem' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: modem, all channels == 0 FillInDevInfo: Filling device info for: phoneline ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline OpenPcm: Opened device 'phoneline' ptr[0] - result: [-2:No such file or directory] ALSA lib pcm.c:2501:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline OpenPcm: Opened device 'phoneline' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: phoneline, all channels == 0 FillInDevInfo: Filling device info for: default GropeDevice: collecting info .. GropeDevice: Limiting number of plugin channels to 128 GropeDevice: collecting info .. GropeDevice: Limiting number of plugin channels to 128 Default input device: default Default output device: default FillInDevInfo: Adding device default: 2 FillInDevInfo: Filling device info for: dmix ALSA lib pcm_direct.c:1421:(snd1_pcm_direct_initialize_poll_fd) unable to open timer 'hw:CLASS=3,SCLASS=0,CARD=0,DEV=0,SUBDEV=0' ALSA lib pcm_dmix.c:1183:(snd_pcm_dmix_open) unable to initialize poll_fd OpenPcm: Opened device 'dmix' ptr[0] - result: [-2:No such file or directory] FillInDevInfo: Skipped device: dmix, all channels == 0 BuildDeviceList: Building device list took 0.692696 seconds after paHostApiInitializers[0]. before paHostApiInitializers[1]. PaOSS BuildDeviceList: Total number of devices found: 0 after paHostApiInitializers[1]. PaAlsaStreamComponent_Initialize: Host Chans P 2 AlsaOpen: Opening device default PaAlsaStreamComponent_InitialConfigure: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: YES PaAlsaStreamComponent_InitialConfigure: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: YES PaAlsaStreamComponent_InitialConfigure: device can MMAP: YES PaAlsaStreamComponent_DetermineFramesPerBuffer: user-buffer (frames) = 1024 PaAlsaStreamComponent_DetermineFramesPerBuffer: user-buffer (sec) = 0.046440 PaAlsaStreamComponent_DetermineFramesPerBuffer: suggested latency (sec) = 0.008707 PaAlsaStreamComponent_DetermineFramesPerBuffer: suggested host buffer (frames) = 2048 PaAlsaStreamComponent_DetermineFramesPerBuffer: suggested host buffer (sec) = 0.092880 PaAlsaStreamComponent_DetermineFramesPerBuffer: periods min = 2, max = 512, req = 4 PaAlsaStreamComponent_DetermineFramesPerBuffer: suggested host buffer period = 1024 PaAlsaStreamComponent_DetermineFramesPerBuffer: device period minimum = 64 PaAlsaStreamComponent_DetermineFramesPerBuffer: device period maximum = 16384 PaAlsaStreamComponent_DetermineFramesPerBuffer: host buffer period = 1024 PaAlsaStreamComponent_DetermineFramesPerBuffer: host buffer period latency = 0.046440 PaAlsaStream_Configure: Playback period size: 1024, latency: 0.046440 OpenStream: Stream: framesPerBuffer = 1024, maxFramesPerHostBuffer = 1024, latency i=0.000000, o=0.046440 I0522 03:02:15.532507 891 VideoVirVi_Component.c:360] <DoVideoViReturnAllValidFrames> release [1]validFrames I0522 03:02:15.532899 891 VideoVirVi_Component.c:1077] <Vi_ComponentThread> wait using frame return done W0522 03:02:15.543506 890 videoInputHw.c:4128] <VideoInputHw_CapThread> VIPP[0], No Virvi Component, drop this one yuv data. E0522 03:02:15.548595 795 video_buffer_manager.c:211] <VideoBufMgrCreate> Alloc 20 input frame buffers in list manager. E0522 03:02:15.548939 795 VideoVirVi_Component.c:481] <VideoViSetViDevAttr> fps 20 nbufs 3 I0522 03:02:16.274793 897 video_render_linux.cpp:224] <vr4l_init> mDisplayFormat[0x200], new CedarXNativeRenderer I0522 03:02:16.275141 897 CedarXNativeRenderer.cpp:174] <CedarXNativeRenderer> hwc disp fmt[0x80], color space:260 I0522 03:02:16.275300 897 hwdisplay.c:239] <hwd_layer_set_src>x: 0, y: 0, width: 0xf0, height: 0xf0 I0522 03:02:16.275398 897 hwdisplay.c:246] <hwd_layer_set_src>width: 0xf000000000, height: 0xf000000000 I0522 03:02:16.275480 897 hwdisplay.c:366] <hwd_layer_set_src>set fb.format 128 0, color_space 260 end, size0[240x240], size1[0x0] E0522 03:02:16.275611 897 vo.c:281] <VoUiCallbackWrapper> debuf vo report video display size[240x240] I0522 03:02:16.275724 897 VideoRender_Component.c:2316] <VideoRender_ComponentThread> init video_render, param: displayRect[0,0][240x240], bufSize[240x240], vdecColorFormat[0xb] I0522 03:02:16.275821 897 mpi_vo.c:508] <VideoRenderEventHandler> KeyFrameDecoded, pts[0]us E0522 03:02:16.276000 897 vo.c:286] <VoUiCallbackWrapper> debuf vo report rendering start udhcpc: sending discover udhcpc: sending select for 10.0.1.201 udhcpc: sending select for 10.0.1.201 udhcpc: lease of 10.0.1.201 obtained, lease time 172800 udhcpc: ifconfig wlan0 10.0.1.201 netmask 255.255.255.0 broadcast + udhcpc: setting default routers: 10.0.1.1 root@sipeed:/# ls bin home overlay rom squashfs usr data lib proc root swapfile var dev lost+found pseudo_init run sys etc mnt rdinit sbin tmp
これは普通にLinux boxとして使えそうだ。エッジAIとして使うかどうかはさておき。
追記
とりあえずできること
viでテキスト編集
できないこと
すでに入っている以外のアプリケーションのopkgでのインストール
とりあえずファイルの転送手段としてネットワーク越しは一旦おいておくことにしてまずUSBでの転送を考える。
このデバイスにはUSB-Cが2つついていて、1つを電源&シリアルコンソールとして使っている。もう1つのUSBはOTGということだが、そのままではPCからUSBデバイスとして認識されるモードとなっているため、これをUSBホストに変えてやる。
echo "usb_host" > /sys/devices/platform/soc/usbc0/otg_role
これでOK。
ひとまずSDカードをリーダに入れて接続してみる。
exFATはだめっぽい
FAT32なら
mount -t vfat /dev/sda1 ./media
であらかじめ作っておいたマウントポイント./mediaにマウントすることができた。
これで、とりあえずMacでpythonコードを書いてMAiX IIに移して実行。ということは可能になった。アプリのインストールもできるかな。
しかし本格的に活用するなら、やはり無線LANに繋がないとどうにもならないだろうな。
一応無線LANチップ自体は技適が取れているようなので、
総務省 電波利用ホームページ|その他|技適未取得機器を用いた実験等の特例制度
こちらで申請すれば短期間なら試験できるようだけど、180日経ったら廃止申請を出すとか面倒すぎるので、やっぱり使い物にはならない。せめてUSB無線子機を繋いで使えるようにできればいいのだが、それもなかなかハードルが高い。
追記
色々と忘れてしまっていたのだが、OpenWRTではSquashFSを使っているため、読み込み専用でファイルへの書き込みができない。なので、設定を書き換えようが、なにかインストールしようが、電源を切るともとに戻ってしまう。overlayとかchrootを使うんだったかなあ。忘却の彼方。