メインコンテンツにスキップ

8051コア

はじめに

Duoで使用されているCPUには8051コアが含まれています。8051サブシステムはRTCによって独立して電源供給されるモジュール内に位置しています。サブシステムは8051、I2C/UART/SPI NOR/SDコントローラ、タイマー/WDT、割り込み管理、Mailbox IPで構成されています。システムソフトウェアは8051を利用してスリープモード中のウェイクアップ条件の管理や、外部デバイスとの通信を行うことができます。

クイックスタート

8051コアのコンパイルガイド

ソースコード: github

実行例:

git clone https://github.com/milkv-duo/duo-8051.git
cd duo-8051/sdcc/mars/project/base_project
make clean && make

コンパイルが成功すると、sdcc/mars/project/base_project/outputmars_mcu_fw.binが生成されます。

ファームウェアの書き込み方法

まずファームウェアとツールをダウンロードし、zipパッケージを解凍します:firmware.zip

Ⅰ. 8051-SRAMにファームウェアを書き込む場合:

  1. 8051_up, mars_mcu_fw.bin, blink.sh/mnt/dataにコピーし、実行・読取権限を付与します。

  2. 8051_upを実行してファームウェアを自動更新し、8051コアを起動します。

  3. blink.shを実行します。このスクリプトは8051コアにデータを送信し、青色LEDを点滅させます(実行前に/mnt/system/blink.shが削除されていることを確認してください)。

ヒント

この方法で動作する8051カーネルファームウェアは8KBを超えてはいけません。超えると動作しない場合があります。

Ⅱ. DDRメモリにファームウェアを書き込む場合:

  1. SDKのメモリ割り当てを変更し、build/boards/[chip model]/[board config]/memmap.pyを修正します。

MemoryMapに以下を追加:

# ==============
# 8051
# ==============
CHIP8051_SIZE = 512 * SIZE_1K
CHIP8051_ADDR = DRAM_BASE + DRAM_SIZE - CHIP8051_SIZE

以下を修正:

# ==============
# C906L FreeRTOS
# ==============
FREERTOS_SIZE = 768 * SIZE_1K
# FreeRTOSは8051の後
FREERTOS_ADDR = CHIP8051_ADDR - FREERTOS_SIZE
FSBL_C906L_START_ADDR = FREERTOS_ADDR
Document Pictures
  1. ファームウェアを再コンパイルし、Duoボードに書き込みます。

  2. 8051_up, mars_mcu_fw.bin, blink.sh, 8051_boot_cfg.ini/mnt/dataにコピーし、実行・読取権限を付与します。

  3. 8051_upを実行してファームウェアを自動更新し、8051コアを起動します。

  4. blink.shを実行します。このスクリプトは8051コアに情報を送信し、青色LEDを点滅させます(実行前に/mnt/system/blink.shが削除されていることを確認してください)。

ヒント

8051のDDRメモリサイズをカスタマイズしたい場合は、以下を修正してください:

CHIP8051_SIZE = 512 * SIZE_1K

ここで512はカスタムサイズです。また、8051_boot_cfg.iniのアドレスもカスタムアドレスに変更してください。

Duoのアドレス計算式は「2147483648+ 64*1048576-[カスタムサイズ]*1024」です。

Duo-256Mのアドレス計算式は「2147483648+256*1048576-[カスタムサイズ]*1024」です。

(configファイルにアドレスを記入する際は、必ず16進数アドレス 0xXXXXXXX に変換してください。)

8051 SDCC

概要

SDCCは8051をターゲットとしたクロスコンパイラです。Duoでは8051コア関連コードのコンパイルに使用します。

8051オンチップリソース

周辺リソース

8051標準搭載周辺機能
  1. 3つの16bitタイマー

  2. 1つのUART(PWR_UART_RX/PWR_UART_TXと多重化)

rtcドメイン周辺機能

8051は主に低消費電力用途で使われます。rtcドメインは電源断/サスペンド時も電力を失いません。8051が主に利用する周辺機能はrtcドメイン上にあります。rtcドメインの周辺機能一覧:

Document Pictures
APオンチップ周辺機能

APが起動している場合、8051は0x00xFFFFFFFFにアクセス可能です。理論上、AP側の全ての周辺機能にアクセスできます。ただし、対応する周辺機器の割り込み信号が8051に伝達できるかはaptortc割り込みテーブルを確認してください。

割り込みコントローラ

ハードウェア構成

8051の割り込み制御は3つに分かれます:

  1. 8051オンチップ割り込み

  2. rtc上の周辺割り込み信号

  3. AP側割り込み

8051で定義される割り込み番号と対応タイプは以下の表の通りです:

Document Pictures

rtc上の周辺割り込み信号はexternal interrupt 0external interrupt 1を通じて8051に接続されます。int0_nint1_n割り込みラインを共有します。下図のように、irq_ap2rtc[1:0]がAP上の割り込みイベントを処理します。

Document Pictures

AP側の割り込みイベントは0x30002500x3000254でORされ、AP側割り込みはirq_ap2rtc[0]にパッケージされて伝達されます。AP側割り込みイベントは0x30002600x3000264irq_ap2rtc[1]に伝達されます。

ヒント

AP側割り込みイベントの有効化や状態確認は「reg_top_misc.xlsx」を参照してください。対応する割り込みタイプとAP割り込み番号は「cv180x_interrupt.xlsx」の「toptortc」シートを参照してください。

割り込み設定手順
  1. 割り込みイベントを設定し、対応する割り込みを有効化

  2. 0x3000248 = 0x01でrtc2apバス変換を有効化

  3. 割り込み番号に対応するビットを有効化(rtcsys_ap2rtc_irq0_sigen0/rtcsys_ap2rtc_irq0_sigen1またはrtcsys_ap2rtc_irq1_sigen0/rtcsys_ap2rtc_irq1_sigen1

  4. irq_ap2rtc[0]またはirq_ap2rtc[1]を有効化

  5. int0_nまたはint1_nを有効化

  6. 割り込み応答で外部割り込み処理関数に入ったら、dw_ictlまたは0x502507cの状態を確認し、irq_ap2rtc[0]またはirq_ap2rtc[1]イベント応答かどうかを判定。該当する場合はrtcsys_ap2rtc_irq0_status0/crtcsys_ap2rtc_irq0_status1またはrtcsys_ap2rtc_irq1_status0/rtc sys_ap2rtc_irq1_status1で応答したAP割り込みイベントを確認。

割り込み制御例:

#if TEST_APTORTC_ICTL

static int __xdata aptortc_count = 0;
int test_aptortc_gpioa_isr(char irqn, int *priv)
{
write_robot(0x0302004c, 0x8000);
printf("gpio0 interrupt\n");
aptortc_count++;
}

void test_aptortc_irq()
{
printf("test aptortc irq\n");
write_robot(0x03020004, 0x100c0020); //gpioA gpio15を出力に設定
write_robot(0x03001908, 0x44); //ピンマルチをプルアップに切替
write_robot(0x03020030, 0xa000); //割り込み有効化
write_robot(0x03020038, 0x8000); //エッジトリガ設定

ap2rtc_irq_init();
ap2rtc_request_irq(17, test_aptortc_gpioa_isr, NULL);

ap2rtc_irq_unmask(17);
dw_ictl_unmask(IRQ_AP2RTC0_INTR);
irq_enable();

printf("REG_51_INT1_SRC_MASK: 0x%081x\n", read_robot(REG_51_INT1_SRC_MASK));
EX0 = 1;
EX1 = 1;
EA = 1;
while(aptortc_count == 0)
printf("gpioA irq 0x3020040 = %x, aptortc_irq status = %x\n",read_robot(0x3020040),read_robot(0x3000258));

printf("aptortc_count = %d\n",aptortc_count);
irq_disable();
}
#endif

8051アドレスマッピングと起動方法

8051コアのアドレス空間は以下の3つに分かれます:

  1. プログラムメモリ: 内蔵ROM(64K)+外部ROM(64K~4M、コードバンキングによる)

  2. データメモリ: 内蔵RAM(256byte)+外部RAM(64K~4G)

  3. 特殊レジスタ(128byte)

Document Pictures
ヒント

8051自体は外部ROMや外部RAMを搭載していません。ここで示すのはバスアドレス可能性です。システムでは外部ROM/RAMがチップ上のメモリに0x50250200x5025024またはsfr (0xfd, 0xfc)を通じてマッピングされます(例: AHB SRAM, TPU SRAM, DDR, SPINOR)。

8051モジュールのアドレスマッピング担当

  1. u_mcu_8051_iram

  2. u_mcu_8051_sfr_wp(SFR→AHBバス変換担当)

  3. u_mcu_8051_xdata_wp(外部ROM/RAMのマッピング担当)

Document Pictures

SFR→AHBバス変換は主にレジスタの読書きに使われます。コード上ではrobot_readrobot_writeがこのインターフェースを利用します。

8051のアドレス線は16bit幅、データ線は8bit幅です。XDATAインターフェースは外部ROM/RAMをAHB SRAM, TPU SRAM, DDR, SPINORなど32bitアドレス空間にマッピングします。

アドレスマッピングと起動方法の注意点

  1. cv181x/cv180xは0x5025020reg_51_rom_addr_def = 1を設定する必要があります。

  2. 8051 iromはデフォルトでAHB SRAMにのみマッピング可能です。0x5025024reg_51irom_ioffset[4:0]でAHB SRAMの先頭アドレスオフセットを設定できます。先頭アドレスは0x5200000 + reg_51irom_ioffset[4:0] * 2KBです。reg_51_mem_ea_n = 1(外部ROM未設定時)はiromから起動します。iromアドレスを超えると外部ROMからアドレスを取得します。reg_51_mem_ea_n = 0の場合は外部ROMから起動し、iromは使用しません。

  3. 外部ROMの先頭アドレスはAHB SRAM, TPU SRAM, DDR, SPINORにマッピング可能です。0x5025020reg_51xdata_ioffset0[20:0]でマッピングアドレスを設定します。外部ROMの先頭アドレスはreg_51xdata_ioffset0[20:0] * 2KBです。

  4. 外部RAMの先頭アドレスはAHB SRAM, TPU SRAM, DDRにマッピング可能で、reg_51xdata_doffset0[20:0]またはSFR(0xfd, 0xfc)で設定します。

  5. reg_51xdata_doffset0[20:0]を設定した場合、外部RAMの先頭アドレスはreg_51xdata_doffset0[20:0] * 2KBです。この時、sfr 0xfc = 0, 0xfd = 0も設定し、両方のアドレスを同時に設定する必要があります。両者は重ね合わせ効果になります。

  6. reg_51xdata_doffset0[20:0] = 0の場合、SFR{0xfd,0xfc}を設定すると外部RAMの先頭アドレスはSFR{0xfd,0xfc} * 64KBです。

ヒント

8051は主に低消費電力用途のため、プログラムメモリ・データメモリともにAHB SRAMにマッピングする起動方法が多いです。

外部ROM/RAMの分割方法変更

SDCCコードディレクトリsdcc/mars/project/base_projectMakeFileを修正:

# ------------------------------------------------------
# メモリレイアウト

# PRGサイズ = 4Kバイト
CODE_SIZE = --code-loc 0x0000 --code-size 0x1F00

# INT-MEMサイズ = 256バイト
#IRAM_SIZE = --idata-loc 0x0000 --iram-size 256

# EXT-MEMサイズ = 32Kバイト
XRAM_SIZE = --xram-loc 0x1900 --xram-size 0x400

# ------------------------------------------------------
# MCS51オプション

CODE_SIZE, XRAM_SIZEを変更することで外部ROM/RAMのサイズを調整できます。

ヒント

AHB SRAMレジスタサイズは8KBです。外部ROMとしてAHB SRAMを使う場合、8KBを超えないよう注意してください。

SFRレジスタ

SFR(特殊機能レジスタ)は80H~FFHに配置されています。SFRレジスタは8051標準搭載と拡張SFRの2種類があります。完全なSFRレジスタ一覧はd8051_db.pdfを参照してください。

ヒント

8051の基礎知識についてはlinkやデータシートd8051_db.pdfを参照してください。

robot_write/robot_readの実装

下図はrobot_write/robot_readを実装する関連SFRレジスタです:

Document Pictures

robot_write:

  1. reg_51robot_sizereg_51robot_adrreg_51robot_wdreg_51robot_we = 1を設定

  2. 書き込み時はreg_51robot_fireを1にし、reg_51robot_fire == 0になるまでポーリング

robot_read:

  1. reg_51robot_sizereg_51robot_adrreg_51robot_we = 0を設定

  2. 読み込み時はreg_51robot_fireを1にし、reg_51robot_fire == 0になるまでポーリング

  3. reg_51robot_rdからデータを取得

ファームウェア書き込みツール 8051_UP

このツールはbinファームウェアをメモリにロードし、8051コアを起動します。

ソースコード: github

コンパイル方法

実行例:

git clone https://github.com/milkv-duo/duo-examples.git
git clone https://github.com/milkv-duo/duo-8051.git
cp -r ./duo-8051/tools/8051_up ./duo-examples
cd ./duo-examples/8051_up
source ../envsetup.sh
make

コンパイルが成功すると、duo-examples/8051_upディレクトリに8051_up実行ファイルが生成されます。

ヒント

コンパイル済みソフトウェアはfirmware.zipに含まれています。コンパイル方法はduo-examplesのデモを参照してください。