硬件设计
ps.本核心板属于本人的研究生毕业设计的一部分。
核心板主要参考龙芯开源的智龙开发板进行设计,设计很简单。由于龙芯的LS1C300B的芯片、SDRAM和Nand-Flash尺寸较大(主要是集成了很多控制器,但是没有DAC…),因此核心板无法做的非常小,SDRAM采用钰创科技的EM63A165TS-6G(高速数据线需要等长走线),Nand-Flash采用三星的K9F1G08U0E,CPU的资源和相关存储、配置协议信息可以阅读手册。本核心板采用了外置spi-flash启动的方式,spi-flash选用Winbond的W25X40作为存储。
硬件PCB测试没问题后会开源该核心板,采用四层板,大小为51.94mm x 43.02mm(已经不能再缩小了)。
先看原理图:
核心板介绍
该核心板使用3.3V供电,已将所有未使用到的IO均使用1.27mm的排针引出,累计引脚达80个左右,由于正反面都有元器件,所以无法设计成邮票孔结构。
LS1C300B的运行主频最高可达300MHz,可以引导运行Linux操作系统,非常方便第二次开发。
核心板上具有复位按键 x 1、电源指示灯 x 1、系统运行状态指示灯 x 1,需要先借助下载器将Pmon程序烧录进spi-flash芯片中,上电后,可以借助pmon的命令将裸机程序或操作系统的内核和根文件系统相关程序下载到Nand-Flash中,LS1C300B的启动位置是根据Nand控制器的4、5引脚电平状态来判断的,如下图所示。
核心板启动后,Nand-Flash内部是没有程序的,需要借助Pmon(Pmon也可以自己定制重新编译,方法可以查看相关手册)的命令将程序通过指定串口或FTP网络的方式传输进去,pmon的配置和烧录命令可以参考下面这张图片(FTP网络下载):
通过串口烧录的流程(速度较慢,不适合下载linux内核和根文件系统):
1、使用SecureCRT软件,执行mingl命令:ymodem base=0x81800000
2、通过软件自带的传输-发送ymodem功能,选择需要下载的文件进行发送
3、目前数据只是发送到了SDRAM中,需要借助命令将内存中的数据拷贝到Nand-Flash中,执行命令:mtd_erase /dev/mtd0 先擦除Nand-Flash,然后执行拷贝:devcp /dev/ram/ymodem /dev/mtd0
4、这个过程很快,拷贝完后就完成了,最后执行重启命令:reboot
下载linux系统后,启动全部输出如下图所示:
软件设计
龙芯应用程序的开发主要采用VSCode来开发,当然也可以使用龙芯自己的IDE进行开发,但是下载和调试需要EJTAG工具进行,所以本文就职采用VSCode快速编辑,借助mips-linux-gnu-gcc编译器进行编译调试,借助Pmon命令进行下载应用程序。
工程目录结构:
#include "stdio.h"
#include <string.h>
#include <math.h>
#include "../lib/ls1c_public.h"
#include "../lib/ls1c_irq.h"
#include "../lib/ls1c_gpio.h"
#include "../lib/ls1c_delay.h"
#include "../lib/ls1c_mipsregs.h"
#include "../lib/ls1c_uart.h"
#include "../lib/ls1c_sys_tick.h"
#include "../lib/ls1c_clock.h"
#include "../app/led.h"
#include "../app/key.h"
#include "../app/led_pwm.h"
#include "../app/usart.h"
#include "../app/timer.h"
#include "../app/SIO.h"
// 硬浮点初始化
void fpu_init(void)
{
unsigned int c0_status = 0;
unsigned int c1_status = 0;
// 使能协处理器1--FPU
c0_status = read_c0_status();
c0_status |= (ST0_CU1 | ST0_FR);
write_c0_status(c0_status);
// 配置FPU
c1_status = read_c1_status();
c1_status |= (FPU_CSR_FS | FPU_CSR_FO | FPU_CSR_FN); // set FS, FO, FN
c1_status &= ~(FPU_CSR_ALL_E); // disable exception
c1_status = (c1_status & (~FPU_CSR_RM)) | FPU_CSR_RN; // set RN
write_c1_status(c1_status);
return ;
}
void bsp_init(void)
{
// 初始化调试串口
uart2_init();
// 初始化通信串口
uart1_init();
// 硬浮点初始化
fpu_init();
// 初始化异常
exception_init();
// 显示时钟信息
clk_print_all();
// 滴答定时器初始化
sys_tick_init(100);
// LED初始化
LED_Init();
// 按键初始化
Key_Init();
// LED_PWM初始化
LED_PWM_Init();
// 定时器初始化
Timer_Init();
//安全输入输出初始化
SIO_Init();
return ;
}
int main(void)
{
bsp_init();
u2_printf("\r\n*******************Working***********************\r\n");
while (1)
{
u2_printf("system_tick = %d\r\n",system_tick);
delay_ms(500);
}
}
编译成功后,会生成二进制文件OpenLoongsonLib1c
PS E:\Program\C\Tasks\LS1C300\OpenLoongsonLib1c> make
mips-linux-gnu-gcc -g -O2 -Wall -fno-pic -N -o OpenLoongsonLib1c lib/start.S lib/ls1c_cache.c lib/ls1c_can.c lib/ls1c_clock.c lib/ls1c_delay.c lib/ls1c_gpio.c lib/ls1c_i2c.c lib/ls1c_irq.c lib/ls1c_pin.c lib/ls1c_public.c lib/ls1c_pwm.c lib/ls1c_simulate_i2c.c lib/ls1c_spi.c lib/ls1c_sys_tick.c lib/ls1c_timer.c lib/ls1c_uart.c app/key.c app/led.c app/led_pwm.c app/main.c app/SIO.c app/synchronized_operation.c app/timer.c app/usart.c app/Watch_Dog.c libc/atob.c libc/ctype.c libc/ffs.c libc/fls.c libc/memcpy.c libc/modf.c libc/printf.c libc/scanf.c libc/sprintf.c libc/str_fmt.c libc/strcat.c libc/strchr.c libc/strcmp.c libc/strcpy.c libc/strcspn.c libc/strichr.c libc/strlen.c libc/strncpy.c libc/strstr.c libc/strtoupp.c libc/toupper.c libc/vsprintf.c libm/e_pow.c libm/e_sqrt.c libm/s_copysign.c libm/s_fabs.c libm/s_scalbn.c -mno-abicalls -fno-pic -g -Wall -Wstrict-prototypes -Wno-uninitialized -Wno-format -Wno-main -O2 -G 0 -mips2 -fno-builtin -nostdinc -Iinclude -Ilib -Iexample -Iapp -static -nostartfiles -e main -Wl,-m -Wl,elf32ltsmip -T ld.script
Compile the complete.
编译完成后,就可以通过串口将该二进制文件下载到CPU内部,上电后跳过pmon,可以直接运行编写好的应用程序。