努力安放这颗好强而骄傲的心

    今天,2016年的5月22日,正式开通自己的博客了,mark一下。

    入职工作已经近10个月有余了,对自己的工作却总是不满意,想做得更多做得更好,不满足于现在的工作状况和自身的能力,而且我坚信自己可以做得更多,做得更好。

    爬行过程中,慢慢看清了前方,认定了方向,我想有更好的前途,我想把选择权掌握在自己手里,我想的明天不只这些,我还有很多未知的美好可能,所以我想努力改变。   既然认准了方向,就竭尽全力地努力,疯狂成长吧。一个聪明、智慧又勤奋的花儿,肯定会绽放的很美,好强、自尊而骄傲的心也不会再受伤害。


内容概要:本文针对国内加密货币市场预测研究较少的现状,采用BP神经网络构建了CCi30指数预测模型。研究选取2018年3月1日至2019年3月26日共391天的数据作为样本,通过“试凑法”确定最优隐结点数目,建立三层BP神经网络模型对CCi30指数收盘价进行预测。论文详细介绍了数据预处理、模型构建、训练及评估过程,包括数据归一化、特征工程、模型架构设计(如输入层、隐藏层、输出层)、模型编译与训练、模型评估(如RMSE、MAE计算)以及结果可视化。研究表明,该模型在短期内能较准确地预测指数变化趋势。此外,文章还讨论了隐层节点数的优化方法及其对预测性能的影响,并提出了若干改进建议,如引入更多技术指标、优化模型架构、尝试其他时序模型等。 适合人群:对加密货币市场预测感兴趣的研究人员、投资者及具备一定编程基础的数据分析师。 使用场景及目标:①为加密货币市场投资者提供一种新的预测工具和方法;②帮助研究人员理解BP神经网络在时间序列预测中的应用;③为后续研究提供改进方向,如数据增强、模型优化、特征工程等。 其他说明:尽管该模型在短期内表现出良好的预测性能,但仍存在一定局限性,如样本量较小、未考虑外部因素影响等。因此,在实际应用中需谨慎对待模型预测结果,并结合其他分析工具共同决策。
<think>我们正在处理的是嵌入式系统中的输入重定向问题,具体是通过ITM(InstrumentationTraceMacrocell)机制来实现scanf和fgetc函数的重定向。根据用户提供的信息,我们需要明确如何安放包含ITM_ReceiveChar和__wrap_scanf的代码片段,以及具体的步骤。###关键点分析:1.**代码放置位置**:这些重定向函数应当放在一个单独的源文件中,而不是主程序(main.c)中。这样做的好处是便于管理,并确保在链接时能够正确覆盖标准库函数。2.**函数命名约定**:使用`__wrap_`前缀来重写标准库函数(如scanf和fgetc)。在链接时,链接器会将标准库中对`fgetc`和`scanf`的调用重定向到我们实现的`__wrap_fgetc`和`__wrap_scanf`函数。3.**编译器支持**:不同编译器(如GCC、ARMCC、IAR)对重定向的实现方式有所不同,需要注意条件编译。4.**ITM函数的依赖**:`ITM_ReceiveChar`和`ITM_SendChar`通常由CMSIS提供,在core_cm3.h或core_cm4.h等头文件中声明。因此,我们的代码需要包含相应的头文件。###具体安放步骤:####步骤1:创建独立的源文件建议创建一个单独的文件,例如`io_redirect.c`,并将重定向代码放入其中。####步骤2:编写重定向代码根据编译器不同,需要采用不同的重定向方法。以下是针对GCC(例如STM32CubeIDE中使用的arm-none-eabi-gcc)的实现示例:```c/*io_redirect.c*/#include<stdio.h>#include<stdarg.h>#include"core_cm4.h"//根据实际使用的内核选择,比如CM3、CM4等//重定向fgetc(用于字符输入)char__wrap_fgetc(FILE*f){//轮询直到有字符可读while(ITM_CheckChar()!=1){//可以加入适当的等待机制,如__NOP()或空循环}returnITM_ReceiveChar();}//重定向scanf(用于格式化输入)int__wrap_scanf(constchar*format,...){va_listargs;va_start(args,format);intret=vfscanf(stdin,format,args);//注意:这里使用vfscanfva_end(args);returnret;}```####步骤3:重定向输出的补充(可选)如果同时需要重定向输出(如printf),可以采用类似方式。参考引用[4]和引用[2]中的例子:```c//重定向fputc(用于字符输出)int__wrap_putc(intch,FILE*f){ITM_SendChar(ch);returnch;}```或者,根据编译器的不同,重定向底层写函数(如`_write`):```c//针对GCC的重定向输出int_write(intfile,char*ptr,intlen){for(inti=0;i< len;i++){ITM_SendChar(ptr[i]);}returnlen;}```####步骤4:修改链接器参数在项目的链接器参数中添加wrap选项,告诉链接器将标准库中的`fgetc`和`scanf`替换为我们实现的`__wrap_fgetc`和`__wrap_scanf`。对于GCC,在编译选项中加入:```-Wl,--wrap=fgetc-Wl,--wrap=scanf```对于Keil(ARMCC),可以在项目设置中添加:```--wrap=scanf--wrap=fgetc```####步骤5:包含必要的头文件确保包含了CMSIS的相关头文件(如`core_cm4.h`),这些文件通常已经包含在标准启动文件中。如果没有,需要根据具体的微控制器型号包含正确的头文件。####步骤6:启用ITM调试1.**硬件连接**:确保调试器支持ITM(如ST-Link、J-Link),并且SWO引脚已连接。2.**IDE配置**:在IDE中配置ITM端口:-在STM32CubeIDE中,打开Debug配置,在“Debugger”标签页中启用ITM。-在Keil中,配置“Trace”选项卡,使能ITM并设置正确的时钟频率和端口。###验证步骤:1.编译并烧录程序到目标板。2.打开调试会话,并启动ITM控制台(在STM32CubeIDE中是“SWVITMDataConsole”)。3.在程序中调用scanf时,在ITM控制台中输入数据,观察程序是否能够接收。###注意事项:-输入重定向只能工作在调试器连接状态下,因为ITM机制依赖于调试器。-在使用scanf之前,可能需要使用fflush(stdout)来确保输出缓冲区被清空(尤其是在没有换行符的输出后)。-如果使用半主机(semihosting),需要确保完全禁用它,以避免冲突。###总结:通过以上步骤,我们可以将重定向函数正确放置在独立的源文件中,并配置好编译和调试环境。这样,程序在调试时就可以通过ITM通道进行输入操作了。§§相关问题§§1.ITM_CheckChar()函数的具体实现是什么?它如何检查是否有字符可读?2.在没有ITM支持的情况下,是否可以通过其他方式实现类似的重定向?3.重定向后的scanf函数在处理不同类型的数据(如整数、浮点数)时是否会有问题?4.如何确保在中断服务程序中安全使用重定向的输入输出函数?</think> ### 正确安放 ITM 重定向代码的操作指南 #### 🔧 放置位置与关键操作 ```mermaid flowchart TD A[创建新文件] --> B[保存为retarget_itm.c] B --> C[添加核重定向函数] C --> D[配置链接器参数] D --> E[启用ITM调试通道] ``` 1. **文件位置** 将包含 `__wrap_fgetc` 和 `__wrap_scanf` 的代码片段**创建独立文件** (如 `retarget_itm.c`),放置在工程源文件目录中: ```c /* retarget_itm.c */ #include <stdio.h> #include <rt_misc.h> char __wrap_fgetc(FILE *f) { while(ITM_CheckChar() != 1) __NOP(); // 等待数据到达 return ITM_ReceiveChar(); // 通过ITM接收 } int __wrap_scanf(const char *format, ...) { va_list args; va_start(args, format); int ret = __vfscanf(stdin, format, args); va_end(args); return ret; } ``` 2. **链接器配置** (必须步骤) 在工程编译设置中添加链接器参数: ``` -Xlinker --wrap=fgetc -Xlinker --wrap=scanf ``` *Keil 中在 Target Options > Linker > Misc controls 添加* 3. **硬件层配置** - 在调试器配置中启用 ITM 通道 - 将开发板的 **SWO引脚** (通常PA10) 连接至调试器 - 设置正确的 ITM 时钟频率(需与实际系统时钟匹配)[^2] #### 🛠 完整使用流程 1. **创建重定向文件** ```c // 添加必要的 STDOUT 定义(部分工具链需要) struct __FILE { int handle; }; FILE __stdout; FILE __stdin; ``` 2. **工程集成步骤** | 步骤 | 操作 | 验证方法 | |---|---|----| | 1 | 添加 `retarget_itm.c` 到工程 | 编译无报错 | | 2 | 配置链接器 wrap 参数 | 查看 map 文件中的函数替换 | | 3 | 开启调试会话 | 调试器识别 ITM 端口 | | 4 | 启动 ITM console | 能接收 printf 输出 | 3. **主程序示例** ```c // main.c #include <stdio.h> int main(void) { int val; printf("输入整数: "); scanf("%d", &val); // 实际调用 __wrap_scanf printf("收到: %d\n", val); while(1); } ``` #### ⚠ 关键注意事项 1. **ITM函数依赖** `ITM_ReceiveChar()` 在 CMSIS 核文件中实现: ```c // core_cm4.h (以M4内核为例) __STATIC_INLINE uint32_t ITM_ReceiveChar(void) { if(ITM_RxBuffer == ITM_RXBUFFER_EMPTY) return 0; return ITM_RxBuffer; } ``` 2. **输入缓冲特性** - 输入数据需在调试控制台完成整行输入后提交 - 使用 `ITM_CheckChar()` 避免忙等待阻塞系统 - 实测传输速率约 1KB/s (SWO时钟为系统时钟1/4时) 3. **跨平台兼容方案** 参考引用[2]建议的编译器兼容写法: ```c #if defined(__GNUC__) int _read(int file, char *ptr, int len) { for(int i=0; i<len; i++) ptr[i] = __wrap_fgetc(stdin); return len; } #elif defined(__CC_ARM) int fgetc(FILE *f) { return __wrap_fgetc(f); } #endif ``` #### 🔍 效果验证方法 1. 在调试器中打开 ITM 控制台(Keil: View > Serial Windows > ITM Console) 2. 输入测试数据后观察程序响应 3. 检查 `__vfscanf` 的返回值(成功解析的参数个数) > 完整实现参考 ARM Keil 安装目录下的 `ARM/Startup/Retarget.c`[^1],但需移除不必要的半主机依赖代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值