跳到主要内容

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/output 中可以找到编译好的固件 mars_mcu_fw.bin

加载固件方法

首先下载固件及工具,并将压缩包解压:firmware.zip

一、在8051-SRAM中加载固件:

  1. 8051_upmars_mcu_fw.binblink.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 is after 8051
FREERTOS_ADDR = CHIP8051_ADDR - FREERTOS_SIZE
FSBL_C906L_START_ADDR = FREERTOS_ADDR
Document Pictures
  1. 重新编译固件并烧录到开发板。

  2. 8051_upmars_mcu_fw.binblink.sh8051_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" 。

(注意地址填写时必须转换成16进制地址0xXXXXXXX。)

8051 SDCC

简介

SDCC 是一个目标CPU为8051的交叉编译器,在Duo中用于编译8051核相关代码。

8051片上资源

外设资源

8051 IP自带外设
  1. 3个16bit Timer。

  2. 1个uart,复用PWR_UART_RX/PWR_UART_TX

rtc domain外设

8051一般使用在低功耗场景,rtc domain 在 poweroff/suspend 时候不会掉电, 即为 no die domain ,所以8051大部分情况使用的外设都在 rtc domain 上。rtc domain 的外设表有如下:

Document Pictures
AP片上外设

8051在AP不掉电的情况下可访问 0x0 ~ 0xFFFFFFFF ,理论上AP侧的外设都可以访问,但是对应外设的中断信号是否能传到8051,需要查看 aptortc 中断表。

中断控制器

硬件结构

8051的中断控制分为三部分:

  1. 8051片上中断。

  2. rtc上的外设中断信号。

  3. AP侧中断。

8051 IP定义的中断号和支持的中断类型,使用到的如下表所示:

Document Pictures

rtc上的外设中断信号,可以通过 外部中断0外部中断1 打包接入8051,可以理解为共用 int0_nint1_n 中断线。如下图所示,其中 irq_ap2rtc[1:0] 处理AP上的中断事件。

Document Pictures

AP侧的中断事件通过 0x30002500x3000254 作或逻辑运算,打包AP侧的中断传输至 irq_ap2rtc[0] , 通过 0x30002600x3000264 打包ap侧中断事件传输到传输至 irq_ap2rtc[1]

提示

AP侧中断事件enable和查看status请查阅《reg_top_misc.xlsx》, 支持的中断类型和对应ap中断中断编号请查阅 《cv180x_interrupt.xlsx》中sheet “toptortc”。

中断配置流程
  1. 配置IP的中断事件并使能对应中断。

  2. 0x3000248 = 0x01使能 rtc2ap 总线转换。

  3. 查看对应中断号enable rtcsys_ap2rtc_irq0_sigen0/rtcsys_ap2rtc_irq0_sigen1rtcsys_ap2rtc_irq1_sigen0/ rtcsys_ap2rtc_irq1_sigen1对应的bit。

  4. enable irq_ap2rtc[0] 或 enable irq_ap2rtc[1]

  5. enable int0_n 或 enable int1_n

  6. 中断响应进入外部中断处理函数后,查看 dw_ictl 或reg 0x502507c status,是否是由于 irq_ap2rtc[0]irq_ap2rtc[1] 事件响应,如果是,再往下查看 rtcsys_ap2rtc_irq0_status0/crtcsys_ap2rtc_irq0_status1rtcsys_ap2rtc_irq1_status0/ rtcsys_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); //切换pinmux为上拉
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核地址空间分为以下三部分:

  1. Program memory:Internal rom(64K)+External rom(64K~4M by code banking)。

  2. Data memory:Internal ram(256byte)+External ram(64K~4G)。

  3. Special register(128byte)。

Document Pictures
提示

8051本身不自带externel rom、externel ram,这里表述的是总线可寻址能力,在系统中通过 0x50250200x5025024sfr(0xfd,0xfc) 把 externel rom , externel rom 映射到芯片上的存储器如AHB SRAM, TPU SRAM, DDR,SPINOR地址空间。

8051 IP负责地址映射的模块

  1. u_mcu_8051_iram

  2. u_mcu_8051_sfr_wp(负责SFR到AHB总线的转换)。

  3. u_mcu_8051_xdata_wp(负责映射externel rom和externel ram)。

Document Pictures

SFR到AHB总线的转换主要用来读写寄存器,在代码中 robot_read , robot_write 就是通过此接口。

8051地址线位宽16bit,数据线位宽8bit, XDATA 接口把 externel rom 和 externel ram 映射到32bit的存储空间如AHB SRAM、TPU SRAM,DDR和SPINOR。

关于地址映射和启动方式的注意事项

  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(配置externel rom不存在)时,mcu才会从irom启动,超过irom地址则去externel rom取指。reg_51_mem_ea_n = 0时则从externel rom启动,不使用irom。

  3. externel rom首地址可以映射到AHB SRAM,TPU SRAM, DDR和SPINOR地址空间, 可配置 0x5025020reg_51xdata_ioffset0[20:0] 确定映射地址,externel rom的首地址为在 reg_51xdata_ioffset0[20:0] * 2KB

  4. Externel ram的首地址可以映射到AHB SRAM,TPU SRAM,DDR,可配置 reg_51xdata_doffset0[20:0]SFR(0xfd, 0xfc)

  5. 如果配置 reg_51xdata_doffset0[20:0] 此时externel ram的首地址为 reg_51xdata_doffset0[20:0] * 2KB ,此时必须设置 sfr 0xfc = 00xfd = 0reg_51xdata_doffset0[20:0]SFR 同时配置地址会是两者之和的叠加效果。

  6. reg_51xdata_doffset0[20:0] = 0,配置SFR{0xfd,0xfc},则externel ram的首地址为 SFR{0xfd,0xfc} * 64KB

提示

由于大部分情况8051是应用在低功耗场景,所以启动方式绝大多是program memory和data memory都映射到AHB SRAM。

修改external rom和external ram的划分

修改SDCC代码目录 sdcc/mars/project/base_projectMakeFile :

# ------------------------------------------------------
# Memory Layout

# PRG Size = 4K Bytes
CODE_SIZE = --code-loc 0x0000 --code-size 0x1F00

# INT-MEM Size = 256 Bytes
#IRAM_SIZE = --idata-loc 0x0000 --iram-size 256

# EXT-MEM Size = 32K Bytes
XRAM_SIZE = --xram-loc 0x1900 --xram-size 0x400

# ------------------------------------------------------
# MCS51 Options

修改 CODE_SIZE , XRAM_SIZE 以变更external rom和external ram的大小。

提示

AHB SRAM寄存器大小8KB,在使用AHB SRAM作为external rom时注意内存分配不要大于8KB。

SFR 寄存器

SFR特殊功能寄存器也称专用寄存器,位于80H~FFH。SFR寄存器分为两类,一类是8051自带的SFR寄存器,另一类是扩展的SFR寄存器,完整的SFR寄存器可查阅 d8051_db.pdf

提示

关于更多8051基础知识的补充请查阅网址 link 和IP手册 d8051_db.pdf

robot_write 和 robot_read 的实现

下图是实现 robot_writerobot_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 中的Demo。

  • Rjgawuie
  • carbonfix