我想在我的STM32闪存中有两个应用程序,一个基本上是启动,另一个是'主'应用程序.我已经想出如何将它们中的每一个加载到闪存的不同区域,并且在获取内存转储后,所有内容看起来都在正确的位置.
因此,当我进行重置时,它会加载引导,此时所有引导都会跳转到应用程序.调试启动,这一切似乎都正常工作.但是,在我跳转到应用程序之后问题到了,它只执行一条指令(汇编),然后跳回到启动.它应该无限期地留在应用程序中.
我的问题是,我应该在应用程序中"跳转"到哪里?
似乎有一些潜在的点,例如中断向量,重置处理程序,应用程序的主要功能.其实我已经尝试了所有这些没有成功的人.
希望这是有道理的,如果没有,我会更新问题.
谢谢你的帮助!理查德
我正在使用keil microvision IDE中的STM32F103E arm cortex-m3 MCU开展一个项目.
我需要为某些目的生成随机数,但我不想使用标准c ++库生成的伪随机数,所以我需要一种使用硬件功能生成REAL随机数的方法,但我不知道如何我能做到.
任何的想法?(我是一名软件工程师而非电子专业人员,所以请说明一下:P)
我正在为STM32F3 mc(STM32F3-Discovery)编写嵌入式代码.我需要输出一些数据,UART和我的使用DMA此,因为这可以让我专注于传感器读取和数据处理,而不是等待字节传输完成.然而问题是我必须结合:
所以我在想循环缓冲区.但我不认为我知道如何使sprintf尊重缓冲区的结束并继续写入缓冲区的开头.我当然可以创建另一个临时缓冲区,在那里打印,并逐字节复制,但它对我来说并不优雅.
F4xx系列芯片的STM32手册表示应用程序将TXFFLSH寄存器中的位写入OTG_FS_GRSTCTL以刷新TxFIFO.作为注释,它提到......应用程序必须在检查核心既不写入TxFIFO也不读取TxFIFO之后写入该位.作为一种方法,它建议确保NAK有效中断被设置(我认为这意味着寄存器中的GINAKEFF位OTG_FS_GINTSTS)以确保内核不读取FIFO,并检查AHBIDL(AHB空闲)位OTG_FS_GRSTCTL被设置为保证FIFO中没有任何内容.STM提供的(糟糕的)USB OTG库忽略了这两种检查,而免费libopencm3库只检查AHB空闲位.我的问题如下:
在执行上述检查和写入TXFFLSH位之前,本手册未建议禁用USB OTG内核.这是否可以让核心可能在执行检查和写入TXFFLSH?之间开始使用FIFO .
"NAK有效"位仅保证不会从非周期性端点的TxFIFO读取数据.除非核心被禁用,否则核心是否仍然可以将FIFO用于等时端点?
我知道这些都是"挑剔"类型的问题,但我正在研究的项目应该会产生一个非常可靠的硬件,客户多年来无法检查设备,因此这些微妙之处很重要(是的,我们启用了看门狗)等等,但我们需要核心在大多数时间没有重置的情况下工作.
我目前正在尝试使用一对stm32l152(发现工具包)通过I2C进行通信.(我没有使用STM提供的标准外设库,因为我想尝试自己实现i2c ..)
我的配置如下:
7位寻址模式(无双地址,仅OAR1)
100khz的速度
启用ACK(在从站上)
ACK被禁用(在主设备上,因为在任何时候主设备/从设备之间只传输1个字节)
在主/从上,使用GPIOB(PB10)作为SCL,GPIOB(PB11)作为SDA
这是奇怪的部分:当我将2个GPIOB引脚配置为推挽式(无上拉/下拉)时,我能够看到我的主机在示波器上发送起始位,地址字节..
但我的奴隶并没有发回确认.我肯定知道这一点,因为主机没有在SR1中断言ADDR位,我看到示波器上没有确认,并且从机没有进入中断(我在从机上启用了I2C事件中断).
仔细观察示波器上的波形,我意识到信号(SCL,SDA)没有完全达到0Volts的逻辑低电平,而是处于1伏特.我猜这可能是为什么奴隶无法从主机读取地址字节,因此没有发回ack.
所以我将2个GPIO引脚配置为漏极开路(无上拉/下拉)..但现在我的主机无法发出起始位..我单步执行代码,看到SR1中主机的SB位置1时设置START位..但我没有看到示波器上的SDA和SCL信号有任何响应(两者都高达3V).
(我在每条线上使用10kohms将SCL和SDA拉到3v).
临时解决方法
我使用微小的printf解决了这个问题:
可能newlib printf占用了太多内存。此后,PC会更改一些奇怪的东西,从理论上讲,这应该是数组的结尾char[100]。
cp = buf + BUF
Run Code Online (Sandbox Code Playgroud)
稍后它尝试执行
*--cp = something
Run Code Online (Sandbox Code Playgroud)
它崩溃了。内存错误?有很多我不理解的事情。例如,我不确定链接描述文件是否正确,或者syscall函数是否正确。在获得进一步的了解之前,我必须坚持使用小巧的printf。
原版的
我有一个STM32F103RB板(Nucleo),而USART1才可以工作。另外,我测试了Newlib函数,并按puts()预期工作。但是,当我尝试printf()用于整数时,如下所示:
printf("ADC: %d\r\n", test);
Run Code Online (Sandbox Code Playgroud)
如果test < 10程序正常运行,但是test >= 10产生了严重故障。经过一些GDB调试后,我发现它是从vfprintf生成的:
#0 HardFault_Handler () at main.c:136
#1 <signal handler called>
#2 0x08005af4 in _vfprintf_r (data=<optimized out>, fp=0x20000384 <impure_data+852>, fmt0=fmt0@entry=0x20004f57 " \254\264", ap=...,
ap@entry=...) at ../../../../../../newlib/libc/stdio/vfprintf.c:1601
#3 0x08004fd0 in printf (fmt=0x800b4ac "ADC: %d\n\r") at ../../../../../../newlib/libc/stdio/printf.c:52
#4 0x080004e8 in main () at main.c:168
Run Code Online (Sandbox Code Playgroud)
我想不出任何解决方案。这是我的_sbrk():
caddr_t …Run Code Online (Sandbox Code Playgroud) 我为STM32CubeF4构建了用于USB CDC示例的代码.我在usbd_cdc_if.c中添加了缺少的CDC_Receive_FS()接收代码.我将它加载到我的STM32F4 Discovery中,它可以工作.在Tera Term上键入的字符将返回并显示在Tera Term上.
我希望有人能够给我一些关于USB CDC固件如何工作的知识,具体来说,这是由USB -D和+ D引脚电压电平转换时产生的中断驱动的,或者是否有一个在某处启动的无限while循环,它只是轮询等待一些数据出现?提示我的问题的是,我看到可以通过在main.c中的无限循环内切换GPIO引脚的状态来使该板上的LED闪烁.但是,在main.c中,这个while循环中没有任何东西用于USB.那么这个USB CDC固件如何从/向Tera Term获取和发送角色.
我似乎无法弄清楚为什么有些printf库函数会从libc_nano.a链接到我的代码中,即使我从不使用任何函数printf.它窃取了至少2K宝贵的闪存空间.我能看到的部分_printf_i,_vfprintf_r,_vfiprintf_r在我的链接器映射文件等.
我试过了
这些都不会使符号从地图文件中消失.
我的gcc选项:
CFLAGS = -Og -Wall -g3 -Wdouble-promotion -mcpu=cortex-m0 -mthumb -fmessage-length=0 -ffunction-sections -mfloat-abi=soft -DUSE_HAL_DRIVER
LFLAGS = -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -specs=nosys.specs -specs=nano.specs -Wl,--gc-sections
Run Code Online (Sandbox Code Playgroud)
arm-none-eabi-gcc.exe(适用于ARM嵌入式处理器的GNU工具)5.2.1 20151202(re lease)[ARM/embedded-5-branch revision 231848] Copyright(C)2015 Free Software Foundation,Inc.这是免费的软件; 查看复制条件的来源.没有保修; 甚至不适用于适销性或特定用途的适用性.
首先,他们为什么要联系起来?有没有办法排除它们?
我试图在cortex-m3控制器上实现以下伪代码,(特别是STM32L151)
void SysTick_Handler() {
do_high_priority_periodic_tasks(); // not to be interrupted
lower_interrupt_priority();
do_low_priority_periodic_tasks(); // these may be interrupted
}
Run Code Online (Sandbox Code Playgroud)
换句话说,运行优先级为0的第一部分,然后以某种方式将当前中断优先级降低到15,以便其余部分可以被其他硬件中断抢占.
一个想法是do_low_priority_periodic_tasks();进入一个单独的中断处理程序,并调用此处理程序,通过该处理程序NVIC_SetPendingIRQ()设置NVIC->ISPR[]寄存器中的挂起位.这样,其他中断将紧随其后SysTick,除非有任何优先级在0和14之间的待处理.
#define LOWPRIO_IRQn 55
void IRQ55_Handler() {
do_low_priority_periodic_tasks(); // these may be interrupted
}
void SysTick_Handler() {
do_high_priority_periodic_tasks(); // not to be interrupted
NVIC_SetPendingIRQ(LOWPRIO_IRQ);
}
void main() {
HAL_Init();
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
HAL_NVIC_SetPriority(LOWPRIO_IRQn, 15, 0);
HAL_NVIC_EnableIRQ(LOWPRIO_IRQn);
while(1) {
/* main loop */
}
}
Run Code Online (Sandbox Code Playgroud)
我已经选择了IRQ 55因为它没有占用我的控制器,它将是STM32L162上的AES中断处理程序,但我有点担心.我应该选择不同的IRQ,也许是未使用的DMA通道中断?使用Cortex-M3内核定义的中断57-67是否安全,而STM32L系列中没有?有没有更好的方法呢?
我需要在n个CPU周期的代码中添加一个延迟(~30).我目前的解决方案是下面的解决方案,但有效但不是很优雅.
此外,必须在编译时知道延迟.我可以使用它,但如果我可以在运行时更改延迟,那将是理想的.(如果有一些开销可以,但我需要1个周期的分辨率.)
我没有任何外围定时器,我可以使用,所以它需要是一个软件解决方案.
do_something();
#define NUMBER_OF_NOPS (SOME_DELAY + 3)
#include "nops.h"
#undef NUMBER_OF_NOPS
do_the_next_thing();
Run Code Online (Sandbox Code Playgroud)
nops.h:
#if NUMBER_OF_NOPS > 0
__ASM volatile ("nop");
#endif
#if NUMBER_OF_NOPS > 1
__ASM volatile ("nop");
#endif
#if NUMBER_OF_NOPS > 2
__ASM volatile ("nop");
#endif
...
Run Code Online (Sandbox Code Playgroud)