STM32G474--Whetstone程序移植(双精度)笔记
1 获取Whetstone程序
Whetstone程序,我用github被墙了,所以用了KK的方式。

获取的程序目录如上所示。
2 新建STM32工程






配置如上,生成工程即可。
3 在生成的工程中添加并修改Whetstone程序
3.1 实现串口打印功能
在生成的usart.c文件中添加些代码,实现串口打印(注意串口的IO引脚,STM32G4的评估板需要外部连接串口,USB口没有连接串口线)。
#ifndef __MICROLIB
#define __FILE_INCOMPLETE 1
#endif
#include <stdio.h>#ifndef __MICROLIB
struct __FILE
{int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling *//* is required. */
}__stdout;
#endif
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)// 该函数放在usart.c文件最后即可
PUTCHAR_PROTOTYPE
{/* e.g. write a character to the LPUART1 and Loop until the end of transmission */HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}
此外,需要在MX_LPUART1_UART_Init()函数中添加USART外设初始化函数。
HAL_UART_MspInit(&hlpuart1);
至此串口打印功能即添加完成。
3.2 修改whetstone.c
工程目录下新建Whetstone文件夹,并将whetstone.c拷贝进去

给工程添加源文件

/*******************************whetstone.c*************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>// 添加头文件
#include "main.h" // 我将Whetstone的函数声明放在main.h了
#include <stdint.h>
#include "stm32g4xx_hal.h"//stm32G4的hal库头文件,若更换芯片型哈需要更改// 添加systick计时
#define GETMYTIME(_t) (*_t = HAL_GetTick())//使用Systick获取时间
uint64_t TickValue = 0;// 中间变量/* map the FORTRAN math functions, etc. to the C versions */
#define DSIN sin
#define DCOS cos
#define DATAN atan
#define DLOG log
#define DEXP exp
#define DSQRT sqrt
#define IF if/* function prototypes */
void POUT(long N, long J, long K, double X1, double X2, double X3, double X4);
void PA(double E[]);
void P0(void);
void P3(double X, double Y, double *Z);
#define USAGE "usage: whetdc [-c] [loops]\n"//#define PRINTOUT 1uint32_t time_in_secs(uint64_t ticks);
uint64_t get_timer_value(void);/*COMMON T,T1,T2,E1(4),J,K,L
*/
double T,T1,T2,E1[5];
int J,K,L;
int argc = 0; //Mod for nucleo. Change in code below if you want non-default loop count//************************************
//** Whetstone 64b-DP **
//** SUB **
//************************************
int Whetstone(void) // ------------ Metoda -----------
{printf("Beginning Whetstone benchmark at ");printf(" %d MHz ...\n\n", SystemCoreClock/1000000);/* used in the FORTRAN version */long I;long N1, N2, N3, N4, N6, N7, N8, N9, N10, N11;double X1,X2,X3,X4,X,Y,Z;long LOOP;int II, JJ;/* added for this version */long loopstart = 0;uint64_t startsec,finisec = 0;double KIPS;int continuous;loopstart = 25000; /* 1000 see the note about LOOP below */continuous = 0;II = 1; /* start at the first arg (temp use of II here) */LCONT:
/*
********************************************
* Start benchmark timing at this point.
********************************************
*/startsec = 0;finisec = 0;startsec = get_timer_value();/*
********************************************
* The actual benchmark starts here.
********************************************
*/T = .499975;T1 = 0.50025;T2 = 2.0;
/*
********************************************
* With loopcount LOOP=10, one million Whetstone instructions
* will be executed in EACH MAJOR LOOP..A MAJOR LOOP IS EXECUTED
* 'II' TIMES TO INCREASE WALL-CLOCK TIMING ACCURACY.
*
* LOOP = 1000;
*/LOOP = loopstart;II = 1;JJ = 1;IILOOP:N1 = 0;N2 = 12 * LOOP;N3 = 14 * LOOP;N4 = 345 * LOOP;N6 = 210 * LOOP;N7 = 32 * LOOP;N8 = 899 * LOOP;N9 = 616 * LOOP;N10 = 0;N11 = 93 * LOOP;
/*
********************************************
* Module 1: Simple identifiers
********************************************
*/X1 = 1.0;X2 = -1.0;X3 = -1.0;X4 = -1.0;for (I = 1; I <= N1; I++){X1 = (X1 + X2 + X3 - X4) * T;X2 = (X1 + X2 - X3 + X4) * T;X3 = (X1 - X2 + X3 + X4) * T;X4 = (-X1+ X2 + X3 + X4) * T;}
#ifdef PRINTOUTIF (JJ==II) POUT(N1,N1,N1,X1,X2,X3,X4);
#endif/*
********************************************
* Module 2: Array elements
********************************************
*/E1[1] = 1.0;E1[2] = -1.0;E1[3] = -1.0;E1[4] = -1.0;for (I = 1; I <= N2; I++){E1[1] = ( E1[1] + E1[2] + E1[3] - E1[4]) * T;E1[2] = ( E1[1] + E1[2] - E1[3] + E1[4]) * T;E1[3] = ( E1[1] - E1[2] + E1[3] + E1[4]) * T;E1[4] = (-E1[1] + E1[2] + E1[3] + E1[4]) * T;}#ifdef PRINTOUTIF (JJ==II) POUT(N2,N3,N2,E1[1],E1[2],E1[3],E1[4]);
#endif/*
********************************************
* Module 3: Array as parameter
********************************************
*/for (I = 1; I <= N3; I++){PA(E1);}
#ifdef PRINTOUTIF (JJ==II) POUT(N3,N2,N2,E1[1],E1[2],E1[3],E1[4]);
#endif/*
********************************************
* Module 4: Conditional jumps
********************************************
*/J = 1;for (I = 1; I <= N4; I++){if (J == 1)J = 2;elseJ = 3;if (J > 2)J = 0;elseJ = 1;if (J < 1)J = 1;elseJ = 0;}#ifdef PRINTOUTIF (JJ==II) POUT(N4,J,J,X1,X2,X3,X4);
#endif/*
********************************************
* Module 5: Omitted
* Module 6: Integer arithmetic
********************************************
*/J = 1;K = 2;L = 3;for (I = 1; I <= N6; I++){J = J * (K-J) * (L-K);K = L * K - (L-J) * K;L = (L-K) * (K+J);E1[L-1] = J + K + L;E1[K-1] = J * K * L;}#ifdef PRINTOUTIF (JJ==II) POUT(N6,J,K,E1[1],E1[2],E1[3],E1[4]);
#endif/*
********************************************
* Module 7: Trigonometric functions
********************************************
*/X = 0.5;Y = 0.5;for (I = 1; I <= N7; I++){X = T * DATAN(T2*DSIN(X)*DCOS(X)/(DCOS(X+Y)+DCOS(X-Y)-1.0));Y = T * DATAN(T2*DSIN(Y)*DCOS(Y)/(DCOS(X+Y)+DCOS(X-Y)-1.0));}#ifdef PRINTOUTIF (JJ==II)POUT(N7,J,K,X,X,Y,Y);
#endif/*
********************************************
* Module 8: Procedure calls
********************************************
*/X = 1.0;Y = 1.0;Z = 1.0;for (I = 1; I <= N8; I++){P3(X,Y,&Z);}
#ifdef PRINTOUTIF (JJ==II)POUT(N8,J,K,X,Y,Z,Z);
#endif/*
********************************************
* Module 9: Array references
********************************************
*/J = 1;K = 2;L = 3;E1[1] = 1.0;E1[2] = 2.0;E1[3] = 3.0;for (I = 1; I <= N9; I++){P0();}
#ifdef PRINTOUTIF (JJ==II) POUT(N9,J,K,E1[1],E1[2],E1[3],E1[4]);
#endif/*
********************************************
* Module 10: Integer arithmetic
********************************************
*/J = 2;K = 3;for (I = 1; I <= N10; I++){J = J + K;K = J + K;J = K - J;K = K - J - J;}#ifdef PRINTOUTIF (JJ==II) POUT(N10,J,K,X1,X2,X3,X4);
#endif/*
********************************************
* Module 11: Standard functions
********************************************
*/X = 0.75;for (I = 1; I <= N11; I++){X = DSQRT(DEXP(DLOG(X)/T1));}
#ifdef PRINTOUTIF (JJ==II) POUT(N11,J,K,X,X,X,X);
#endif/*
********************************************
* THIS IS THE END OF THE MAJOR LOOP.
********************************************
*/if (++JJ <= II)goto IILOOP;/*
********************************************
* Stop benchmark timing at this point.
********************************************
*/// finisec = time(0);finisec = get_timer_value();//timer.reset();/*
*--------------------------------------------------------------------
* Performance in Whetstone KIP's per second is given by
*
* (100*LOOP*II)/TIME
*
* where TIME is in seconds.
*--------------------------------------------------------------------
*/double vreme;vreme = time_in_secs(finisec - startsec);if (vreme <= 0){printf("Insufficient duration- Increase the LOOP count \n");finisec = 0; startsec = 0;return 1;}printf("Loops: %ld , \t Iterations: %d, \t Duration: %.3f sec. \n",LOOP, II, vreme);KIPS = (100.0 * LOOP * II) / vreme ;if (KIPS >= 1000.0)printf("C Converted Double Precision Whetstones: %.3f MIPS \n\n", KIPS / 1000);elseprintf("C Converted Double Precision Whetstones: %.3f KIPS \n\n", KIPS);// printf("C Converted Double Precision Whetstones: %.3f MIPS \n\n", KIPS / 1000);if (continuous)goto LCONT;finisec = 0; startsec = 0;return 1;
}void PA(double E[])
{J = 0;L10:E[1] = ( E[1] + E[2] + E[3] - E[4]) * T;E[2] = ( E[1] + E[2] - E[3] + E[4]) * T;E[3] = ( E[1] - E[2] + E[3] + E[4]) * T;E[4] = (-E[1] + E[2] + E[3] + E[4]) / T2;J += 1;if (J < 6)goto L10;
}void P0(void)
{E1[J] = E1[K];E1[K] = E1[L];E1[L] = E1[J];
}void P3(double X, double Y, double *Z)
{double X1, Y1;X1 = X;Y1 = Y;X1 = T * (X1 + Y1);Y1 = T * (X1 + Y1);*Z = (X1 + Y1) / T2;
}// 原本该函数应该是用定时器实现的
double time_in_secs(uint64_t ticks)
{// scale timer down to avoid uint64_t -> double conversion in RV32
// int scale = 256;
// uint32_t delta = ticks / scale;
// uint32_t freq = get_timer_freq() / scale;
// return delta / (double)freq;int scale = 10000;
// double delta = ticks / scale; //修改前double delta = (double)(ticks*1.0) / scale;//修改后return delta;
}// 根据原有的函数接口,使用systick作为计时单元实现计时
uint64_t get_timer_value(void)
{GETMYTIME(&TickValue);return TickValue;
}#ifdef PRINTOUT
void POUT(long N, long J, long K, double X1, double X2, double X3, double X4)
{printf("%7ld %7ld %7ld %12.4e %12.4e %12.4e %12.4e\n",N, J, K, X1, X2, X3, X4);
}
#endif
在main.c添加
#include <stdio.h>printf("\nMy Benchmark example for Whetstones \n");
Whetstone(); //Call of Whetstone banchmark methode
在main.h添加
int Whetstone(void);
4 烧录测试
修改前

修改后

暂时没有具体分析细节问题,只是跑通了
修改记录
2025.2.7——可能有朋友注意到了时间上是正好5s,一般不可能这么规整,检查了一下代码,是time_in_secs()函数在转换时没有考虑到浮点导致。已修改
相关文章:
STM32G474--Whetstone程序移植(双精度)笔记
1 获取Whetstone程序 Whetstone程序,我用github被墙了,所以用了KK的方式。 获取的程序目录如上所示。 2 新建STM32工程 配置如上,生成工程即可。 3 在生成的工程中添加并修改Whetstone程序 3.1 实现串口打印功能 在生成的usart.c文件中…...
【DeepSeek × Postman】请求回复
新建一个集合 在 Postman 中创建一个测试集合 DeepSeek API Test,并创建一个关联的测试环境 DeepSeek API Env,同时定义两个变量 base_url 和 api_key 的步骤如下: 1. 创建测试集合 DeepSeek API Test 打开 Postman。点击左侧导航栏中的 Co…...
开源身份和访问管理方案之keycloak(一)快速入门
文章目录 什么是IAM什么是keycloakKeycloak 的功能 核心概念client管理 OpenID Connect 客户端 Client Scoperealm roleAssigning role mappings分配角色映射Using default roles使用默认角色Role scope mappings角色范围映射 UsersGroupssessionsEventsKeycloak Policy创建策略…...
基于PaddleOCR的图像文字识别与程序打包方法
目录 一、基本介绍 二、程序实现 1)环境配置 2)代码实现 3)程序运行结果 三、程序打包 1)使用pyinstaller打包程序 2)添加依赖和模型数据 四、需要注意的问题 五、总结 一、基本介绍 本文主要介绍利用现有开源…...
单片机上SPI和IIC的区别
SPI(Serial Peripheral Interface)和IC(Inter-Integrated Circuit)是两种常用的嵌入式外设通信协议,它们各有优缺点,适用于不同的场景。以下是它们的详细对比: — 1. 基本概念 SPI࿰…...
Python 字典(一个简单的字典)
在本章中,你将学习能够将相关信息关联起来的Python字典。你将学习如何访问和修改字典中的信息。鉴于字典可存储的信息量几乎不受限制,因此我们会演示如何遍 历字典中的数据。另外,你还将学习存储字典的列表、存储列表的字典和存储字典的字典。…...
一个简单的Windows TCP服务器实现
初始化 WSADATA wsaData; SOCKET serverSocket, clientSocket; struct sockaddr_in serverAddr { 0x00 }; struct sockaddr_in clientAddr { 0x00 }; int clientAddrLen sizeof(clientAddr);if (WSAStartup(MAKEWORD(2, 2), &wsaData) ! 0) {printf("WSAStartup f…...
Node.js笔记入门篇
黑马程序员视频地址: Node.js与Webpack-01.Node.js入门 基本认识 概念 定义:Node.js 是一个免费、开源、跨平台的 JavaScript 运行时环境, 它让开发人员能够创建服务器 Web 应用、命令行工具和脚本 作用:使用Node.js 编写服务器端程序 ✓ …...
EX_25/2/10
epoll实现多路客户端之间的登录注册及消息和文件传输 服务器部分 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include…...
python视频爬虫
文章目录 爬虫的基本步骤一些工具模拟浏览器并监听文件视频爬取易错点一个代码示例参考 爬虫的基本步骤 1.抓包分析,利用浏览器的开发者工具 2.发送请求 3.获取数据 4.解析数据 5.保存数据 一些工具 requests, 用于发送请求,可以通过get,p…...
RbFT:针对RAG中检索缺陷的鲁棒性微调
今天给大家分享一篇最新的RAG论文: 论文题目:Enhancing Retrieval-Augmented Generation: A Study of Best Practices 论文链接:https://arxiv.org/pdf/2501.18365 论文代码:https://github.com/StibiumT16/Robust-Fine-tuning 研…...
证明: 极限的局部有界性
在考研数学中,极限的局部有界性是一个非常重要的概念,尤其是在讨论函数的连续性、可积性和可微性等性质时。局部有界性可以帮助我们理解函数在某些区域内的行为。 定理: 如果 lim x → x 0 f ( x ) L \lim_{x \to x_0} f(x) L limx→x0…...
51单片机俄罗斯方块计分函数
/************************************************************************************************************** * 名称:scoring * 功能:计分 * 参数:NULL * 返回:NULL * 备注:采用非阻塞延时 ****************…...
new 以及 call、apply、bind 关键字解析
1.new关键字 自动创建对象:使用new调用构造函数时,会自动创建一个空对象,并将其赋值给this。你不需要显式地使用{}来创建对象。 绑定this到新对象:构造函数内部的this指向新创建的对象,因此可以在构造函数中为新对象添…...
【用Deepseek搭建免费的个人知识库--综合教程(完整版)】第二篇:Ollama服务器
用Deepseek搭建免费的个人知识库–综合教程(完整版):第二篇:Ollama服务器部署 OLLAMA服务器的配置在很多网上都已经介绍的非常清楚了,我们的重点不在于那些简单的步骤,而是在需要为下一步做准备的地方更加…...
【图片合并转换PDF】如何将每个文件夹下的图片转化成PDF并合并成一个文件?下面基于C++的方式教你实现
医院在为患者进行诊断和治疗过程中,会产生大量的医学影像图片,如 X 光片、CT 扫描图、MRI 图像等。这些图片通常会按照检查时间或者检查项目存放在不同的文件夹中。为了方便医生查阅和患者病历的长期保存,需要将每个患者文件夹下的图片合并成…...
从基础到人脸识别与目标检测
前言 从本文开始,我们将开始学习ROS机器视觉处理,刚开始先学习一部分外围的知识,为后续的人脸识别、目标跟踪和YOLOV5目标检测做准备工作。我采用的笔记本是联想拯救者游戏本,系统采用Ubuntu20.04,ROS采用noetic。 颜…...
Elasticsearch:在 Elastic 中玩转 DeepSeek R1 来实现 RAG 应用
在这个春节,如一声春雷,DeepSeek R1 横空出世。现在人人都在谈论 DeepSeek R1。这个大语言模型无疑在中国及世界的人工智能发展史上留下了重要的里程碑。那么我们改如何结合 DeepSeek R1 及 Elasticsearch 来实现 RAG 呢?在之前的文章 “使用…...
寒假2.6--SQL注入之布尔盲注
知识点 原理:通过发送不同的SQL查询来观察应用程序的响应,进而判断查询的真假,并逐步推断出有用的信息 适用情况:一个界面存在注入,但是没有显示位,没有SQL语句执行错误信息,通常用于在无法直接…...
CTF中特别小的EXE是怎么生成的
我们在打CTF时候,出题的爷爷们给出的exe都很小 就10k左右,有的甚至就5k,那时候我很郁闷啊。现在我也能了啊哈哈 不多bb按如下操作: 我们来看看正常的release生成的代码# Copy #include "windows.h" int main(){ Messa…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
