当前位置: 首页 > news >正文

【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出

【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出

文章目录

  • 【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出
    • 1.简介
    • 2.验证用例
    • 3.软件代码
    • 4.链接脚本
    • 5.编译脚本
    • 6.仿真结果
      • 6.1 复位结束
      • 6.2 运行成功
      • 6.3 终端打印
    • 7.总结

1.简介

本文将详细阐述如何利用 printf 来打印字符串,在此过程中使用了一个开源的库 xprintfxprintf 是一个紧凑的字符串 I/O 库,它非常适用于程序存储器不足以用于常规 printf 函数的微型微控制器。通过调用 xprintf 函数成功输出了“Hello RISC-V World!”,同时还对该库的使用方法以及如何进行编译等内容加以介绍。xprintf库的地址为:http://elm-chan.org/fsw/strf/xprintf.html,下载后使将使用xprintf.cxprintf.h两个文件。

2.验证用例

// -------------------------------------------------------------------------------------------------
// Copyright 2024 Kearn Chen, kearn.chen@aliyun.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -------------------------------------------------------------------------------------------------
// Description :
//             1. Run Hello World!
// -------------------------------------------------------------------------------------------------task initcase;load_instr("hello_world_test/hello_world_test.bin");endtasktask testcase;#2_000_000;endtask

在验证用例中,任务initcase加载Bin文件到仿真模型中,任务testcase延迟2毫秒,等待CPU执行完软件指令。

3.软件代码

// -------------------------------------------------------------------------------------------------
// Copyright 2024 Kearn Chen, kearn.chen@aliyun.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -------------------------------------------------------------------------------------------------#include "xprintf.h"void xfunc_output_callback(int c)
{*((volatile unsigned int *)0xc0000) = c;
}void simulation_finish(void)
{*((volatile unsigned int *)0xc0004) = 0x12345678;
}int main(void)
{xfunc_output = xfunc_output_callback;xprintf("Hello RISC-V World!\n");simulation_finish();while(1);
}

上述代码中,首先是初始化打印输出的回调函数,在回调函数中,将要输出的字符写入地址0xc0000寄存器中,这个寄存器在之前的文章【RISC-V设计-12】- RISC-V处理器设计K0A之验证环境中第4部分有描述,写入此寄存器的数据会存入到一个队列里面,在遇到输出字符为\n时,将整个队列内的输出到终端。在输出完字符后,调用simulation_finish函数,仿真运行结束。在xprintf库中,有一些宏定义,如下所示,根据需要可以打开和关闭。

#define XF_USE_OUTPUT	1	/* 1: Enable output functions */
#define	XF_CRLF			0	/* 1: Convert \n ==> \r\n in the output char */
#define	XF_USE_DUMP		0	/* 1: Enable put_dump function */
#define	XF_USE_LLI		0	/* 1: Enable long long integer in size prefix ll */
#define	XF_USE_FP		0	/* 1: Enable support for floating point in type e and f */
#define XF_DPC			'.'	/* Decimal separator for floating point */
#define XF_USE_INPUT	0	/* 1: Enable input functions */
#define	XF_INPUT_ECHO	0	/* 1: Echo back input chars in xgets function */

4.链接脚本

ENTRY( _start )__stack_size = 2048;PROVIDE( _stack_size = __stack_size );MEMORY
{ROM (rx)  : ORIGIN = 0x00000, LENGTH = 512KRAM (xrw) : ORIGIN = 0x80000, LENGTH = 256K
}SECTIONS
{.init :{_sinit = .;. = ALIGN(4);KEEP(*(SORT_NONE(.init))). = ALIGN(4);_einit = .;} >ROM.text :{. = ALIGN(4);*(.text)*(.text.*)*(.rodata)*(.rodata*)*(.gnu.linkonce.t.*). = ALIGN(4);} >ROM.fini :{KEEP(*(SORT_NONE(.fini))). = ALIGN(4);} >ROMPROVIDE( _etext = . );PROVIDE( _eitcm = . );  .preinit_array :{PROVIDE_HIDDEN (__preinit_array_start = .);KEEP (*(.preinit_array))PROVIDE_HIDDEN (__preinit_array_end = .);} >ROM.init_array :{PROVIDE_HIDDEN (__init_array_start = .);KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))PROVIDE_HIDDEN (__init_array_end = .);} >ROM.fini_array :{PROVIDE_HIDDEN (__fini_array_start = .);KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))PROVIDE_HIDDEN (__fini_array_end = .);} >ROM.ctors :{KEEP (*crtbegin.o(.ctors))KEEP (*crtbegin?.o(.ctors))KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))KEEP (*(SORT(.ctors.*)))KEEP (*(.ctors))} >ROM.dtors :{KEEP (*crtbegin.o(.dtors))KEEP (*crtbegin?.o(.dtors))KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))KEEP (*(SORT(.dtors.*)))KEEP (*(.dtors))} >ROM.dalign :{. = ALIGN(4);PROVIDE(_data_vma = .);} >RAM AT>ROM  .dlalign :{. = ALIGN(4); PROVIDE(_data_lma = .);} >ROM.data :{. = ALIGN(4);*(.gnu.linkonce.r.*)*(.data .data.*)*(.gnu.linkonce.d.*). = ALIGN(8);PROVIDE( __global_pointer$ = . + 0x800 );*(.sdata .sdata.*)*(.sdata2*)*(.gnu.linkonce.s.*). = ALIGN(8);*(.srodata.cst16)*(.srodata.cst8)*(.srodata.cst4)*(.srodata.cst2)*(.srodata .srodata.*). = ALIGN(4);PROVIDE( _edata = .);} >RAM AT>ROM.bss :{. = ALIGN(4);PROVIDE( _sbss = .);*(.sbss*)*(.gnu.linkonce.sb.*)*(.bss*)*(.gnu.linkonce.b.*)    *(COMMON*). = ALIGN(4);PROVIDE( _ebss = .);} >RAM AT>ROMPROVIDE( _end = _ebss);PROVIDE( end = . );.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :{PROVIDE( _heap_end = . );. = ALIGN(4);PROVIDE(_susrstack = . );. = . + __stack_size;PROVIDE( _eusrstack = .);} >RAM 
}

5.编译脚本

# -------------------------------------------------------------------------------------------------
# Copyright 2024 Kearn Chen, kearn.chen@aliyun.com
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------------------------------------PREFIX := riscv-none-embed-LINKER := ../common/link.ldOBJECT += ../common/startup.o
OBJECT += ../common/xprintf.o
OBJECT += main.oCFLAGS := -march=rv32e -mabi=ilp32e -I../commonLFLAGS := -march=rv32e -mabi=ilp32e -T$(LINKER) -nostartfilesTARGET := $(notdir $(shell pwd))all : $(TARGET).asm $(TARGET).bin%.bin : %.elf$(PREFIX)objcopy -Obinary $< $@%.asm : %.elf$(PREFIX)objdump -D $< > $@%.elf : $(OBJECT)$(PREFIX)gcc $(LFLAGS) -o $@ $^$(PREFIX)size $@%.o : %.S$(PREFIX)gcc $(CFLAGS) -c -o $@ $<%.o : %.c$(PREFIX)gcc $(CFLAGS) -c -o $@ $<clean :@rm -rf *.o *.elf *.asm *.bin ../common/*.o.PHONY: clean all.SECONDARY:

上述脚本中所使用的startup.o文件为startup.S文件所编译产生,这个文件在之前的文章【RISC-V设计-09】- RISC-V处理器设计K0A之CIC中第5部分已有介绍,这个文件为RISCV-K0A的启动文件,同时还具有中断处理的功能。编译结果如下

riscv-none-embed-gcc -march=rv32e -mabi=ilp32e -I../common -c -o ../common/startup.o ../common/startup.S
riscv-none-embed-gcc -march=rv32e -mabi=ilp32e -I../common -c -o ../common/xprintf.o ../common/xprintf.c
riscv-none-embed-gcc -march=rv32e -mabi=ilp32e -I../common -c -o main.o main.c
riscv-none-embed-gcc -march=rv32e -mabi=ilp32e -T../common/link.ld -nostartfiles -o hello_world_test.elf ../common/startup.o ../common/xprintf.o main.o
riscv-none-embed-size hello_world_test.elftext	   data	    bss	    dec	    hex	filename3164	      0	   2056	   5220	   1464	hello_world_test.elf
riscv-none-embed-objdump -D hello_world_test.elf > hello_world_test.asm
riscv-none-embed-objcopy -Obinary hello_world_test.elf hello_world_test.bin

6.仿真结果

6.1 复位结束

6.2 运行成功

6.3 终端打印

*Verdi* FSDB WARNING: The FSDB file already exists. Overwriting the FSDB file may crash the programs that are using this file.
*Verdi* : Create FSDB file 'novas.fsdb'
*Verdi* : Begin traversing the scopes, layer (0).
*Verdi* : End of traversing.
[MCU_INFO] : Hello RISC-V World!
$finish called from file "../env/slave_model.v", line 136.
$finish at simulation time                43210

7.总结

本文介绍了如何在RISCV-K0A上使用xprintf库文件,并通过xprintf输出了"Hello RISC-V World!"到终端显示。

相关文章:

【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出

【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出 文章目录 【RISC-V设计-14】- RISC-V处理器设计K0A之打印输出1.简介2.验证用例3.软件代码4.链接脚本5.编译脚本6.仿真结果6.1 复位结束6.2 运行成功6.3 终端打印 7.总结 1.简介 本文将详细阐述如何利用 printf 来打印字符串…...

时序预测|基于变分模态分解-时域卷积-双向长短期记忆-注意力机制多变量时间序列预测VMD-TCN-BiLSTM-Attention

时序预测|基于变分模态分解-时域卷积-双向长短期记忆-注意力机制多变量时间序列预测VMD-TCN-BiLSTM-Attention 文章目录 前言时序预测|基于变分模态分解-时域卷积-双向长短期记忆-注意力机制多变量时间序列预测VMD-TCN-BiLSTM-Attention 一、VMD-TCN-BiLSTM-Attention模型1. **…...

Python知识点:如何使用Godot与Python进行游戏脚本编写

在Godot中使用Python进行游戏脚本编写&#xff0c;你需要通过一个插件来实现&#xff0c;因为Godot原生支持的脚本语言是GDScript、VisualScript和C#。这个插件被称为Godot-Python&#xff0c;它允许你在Godot引擎中使用Python编写脚本。以下是详细的步骤指导你如何配置和使用G…...

Spring MVC数据绑定和响应学习笔记

学习视频:12001 数据绑定_哔哩哔哩_bilibili 目录 1.数据绑定 简单数据绑定 默认类型数据绑定 简单数据类型绑定的概念 参数别名的设置 PathVariable注解的两个常用属性 POJO绑定 自定义类型转换器 xml方式 注解方式 数组绑定 集合绑定 复杂POJO绑定 属性为对象类…...

Vulnhub JIS-CTF靶机详解

项目地址 https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/ 修改靶机的网卡 开机时长按shift&#xff0c;进入此页面 选择root模式进入 将只读模式改为读写模式 mount -o remount,rw / 查看本机的网卡名称 …...

FPGA资源评估

FPGA资源评估 文章目录 FPGA资源评估前言一、资源评估1.1 资源有哪些1.2 资源统计 二、 FPGA 的基本结构三、 更为复杂的 FPGA 架构 前言 一、资源评估 大家在项目中一般会要遇到需要资源评估的情况&#xff0c;例如立了新项目&#xff0c;前期需要确定使用什么FPGA片子&…...

REST framework中Views API学习

REST framework提供了一个APIView类&#xff0c;它是Django的View类的子类。 APIView类和一般的View类有以下不同&#xff1a; 被传入到处理方法的请求不会是Django的HttpRequest类的实例&#xff0c;而是REST framework的Request类的实例。处理方法可以返回REST framework的…...

Vue(四)——总结

渐进式JavaScript框架 Vue.js是一套构建用户界面&#xff08;UI&#xff09;的渐进式JavaScript框架。 1、库和框架的区别&#xff1f; 库&#xff1a;库是提供给开发者的一个封装好的特定于某一方面的集合&#xff08;方法和函数&#xff09;&#xff0c;库没有控制权&…...

计算机毕业设计 招生宣传管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

练习题PHP5.6+变长参数 ⇒ usort回调后门 ⇒ 任意代码执行

突破长度限制 使用usort上传后门 usort — 使用用户自定义的比较函数对数组中的值进行排序 paramusort(...$GET); ...为php设置可变长参数 在url地址栏中输入[]test&1[]phpinfo();&2assert 包含了phpiinfo&#xff08;&#xff09;命令执行 结合usort使用 assert…...

EPLAN关于PLC的输入输出模块绘制

EPLAN关于PLC的输入输出模块绘制 总览图上的PLC绘制原理图上的PLC绘制编辑IO注释显示总览界面IO注释自动关联总览IO地址 总览图上的PLC绘制 右键项目【新建】 页类型选择【总览】&#xff0c;描述可以自由编辑&#xff0c;之后确认即可。 由于我们需要绘制PLC的输入输出&#x…...

【Linux】sersync 实时同步

原理 rsync 是不支持实时同步的&#xff0c;通常我们借助于 inotify 这个软件来实时监控文件变化&#xff0c;一旦inotify 监控到文件变化&#xff0c;则立即调用 rsync 进行同步&#xff0c;推送到 rsync 服务端。 环境准备 步骤1&#xff1a;获取数据包 获取 sersync 的包…...

Unity 资源分享 之 恐龙Ceratosaurus资源模型携 82 个动画来袭

Unity 资源分享 之 恐龙Ceratosaurus资源模型携 82 个动画来袭 一、前言二&#xff0c;资源包内容三、免费获取资源包 一、前言 亲爱的 Unity 开发者和爱好者们&#xff0c;大家好&#xff01;今天要为大家分享一份超级酷炫的 Unity 资源——恐龙资源模型&#xff0c;而且它还…...

【AI绘画】 学习内容简介

AI绘画-学习内容简介 1. 效果展示 本次测试主要结果展示如下&#xff1a; 卡通手办定制1 卡通手办定制2 艺术写真定制 2. 主要目录 AI 绘画- 文生图&#xff0c;图生图及lora使用&#xff08;基于diffusers&#xff09; AI 绘画- 模型转换与快速生图&#xff08;基于diffus…...

树形结构查找(B树、B+树)

平衡树结构的树高为 O(logn) &#xff0c;平衡树结构包括两种平衡二叉树结构&#xff08;分别为 AVL 树和 RBT&#xff09;以及一种树结构&#xff08;B-Tree&#xff0c;又称 B 树&#xff0c;它的度大于 2 &#xff09;。AVL 树和 RBT 适合内部存储的应用&#xff0c;而 B 树…...

网络通信(TCP/UDP协议 三次握手四次挥手 )

三、TCP协议与UDP协议 1、TCP/IP、TCP、 UDP是什么 TCP/IP协议是一个协议簇&#xff0c;里面包括很多协议的&#xff0c; UDP只是其中的一个&#xff0c; 之所以命名为TCP/IP协议&#xff0c; 因为TCP、 IP协议是两个很重要的协议&#xff0c;就用他两命名了&#xff0c;而TCP…...

C# ADO.Net 通用按月建表插入数据

原理是获取原表表结构以及索引动态拼接建表SQL&#xff0c;如果月表存在则不创建&#xff0c;不存在则创建表结构 代码如下 /// <summary>/// 根据指定的表名和时间按月进行建表插入&#xff08;如果不存在对应的月表&#xff09;/// </summary>/// <param nam…...

19-ESP32-C3加大固件储存区

1默认编译情况。 2、改flash4M。ESP-IDF Partition Table Editor修改。 3、设置输入Partition Table 改自定义.CSV。保存。 4、查看命令输入Partition Table Editor打开-分区表编辑器UI。按图片增加。 nvs,data,nvs,0x9000,0x6000,, phy_init,data,phy,0xF000,0x1000,, factory…...

【STL】stack/queue 容器适配器 deque

1.stack的介绍和使用 1.1.stack的介绍 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容…...

(回溯) LeetCode 17. 电话号码的组合

原题链接 一. 题目描述 17. 电话号码的字母组合 已解答 中等 相关标签 相关企业 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...

高效的后台管理系统——可进行二次开发

随着互联网技术的迅猛发展&#xff0c;企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心&#xff0c;成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统&#xff0c;它不仅支持跨平台应用&#xff0c;还能提供丰富…...

如何做好一份技术文档?从规划到实践的完整指南

如何做好一份技术文档&#xff1f;从规划到实践的完整指南 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...

Qt的学习(二)

1. 创建Hello Word 两种方式&#xff0c;实现helloworld&#xff1a; 1.通过图形化的方式&#xff0c;在界面上创建出一个控件&#xff0c;显示helloworld 2.通过纯代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c; 显示hello world&#xff1b; …...

算法刷题-回溯

今天给大家分享的还是一道关于dfs回溯的问题&#xff0c;对于这类问题大家还是要多刷和总结&#xff0c;总体难度还是偏大。 对于回溯问题有几个关键点&#xff1a; 1.首先对于这类回溯可以节点可以随机选择的问题&#xff0c;要做mian函数中循环调用dfs&#xff08;i&#x…...

Electron简介(附电子书学习资料)

一、什么是Electron&#xff1f; Electron 是一个由 GitHub 开发的 开源框架&#xff0c;允许开发者使用 Web技术&#xff08;HTML、CSS、JavaScript&#xff09; 构建跨平台的桌面应用程序&#xff08;Windows、macOS、Linux&#xff09;。它将 Chromium浏览器内核 和 Node.j…...