标签: stm32

在STM32闪存中运行多个应用程序

我想在我的STM32闪存中有两个应用程序,一个基本上是启动,另一个是'主'应用程序.我已经想出如何将它们中的每一个加载到闪存的不同区域,并且在获取内存转储后,所有内容看起来都在正确的位置.

因此,当我进行重置时,它会加载引导,此时所有引导都会跳转到应用程序.调试启动,这一切似乎都正常工作.但是,在我跳转到应用程序之后问题到了,它只执行一条指令(汇编),然后跳回到启动.它应该无限期地留在应用程序中.

我的问题是,我应该在应用程序中"跳转"到哪里?

似乎有一些潜在的点,例如中断向量,重置处理程序,应用程序的主要功能.其实我已经尝试了所有这些没有成功的人.

希望这是有道理的,如果没有,我会更新问题.

谢谢你的帮助!理查德

更新:

  • 我在调试器中玩了一个游戏并手动将程序计数器更改为应用程序的主要部分,这很有效,所以它让我觉得我的跳转有问题,为什么程序计数器不能继续运行跳后?
  • 实际上它似乎是PSR,'T'在跳转时被重置,如果我在跳转之后再次设置它继续使用app我想要的
  • 好的找到了一个解决方案,似乎你需要在执行分支时将PC LSB设置为1或者它处于'ARM'模式(32位指令而不是像'拇指'模式中的16位指令.相当一个模糊的小问题,谢谢你让我和你分享!

embedded stm32

5
推荐指数
1
解决办法
5974
查看次数

如何使用STM32 MCU生成REAL随机数?

我正在使用keil microvision IDE中的STM32F103E arm cortex-m3 MCU开展一个项目.
我需要为某些目的生成随机数,但我不想使用标准c ++库生成的伪随机数,所以我需要一种使用硬件功能生成REAL随机数的方法,但我不知道如何我能做到.
任何的想法?(我是一名软件工程师而非电子专业人员,所以请说明一下:P)

c++ random embedded microcontroller stm32

5
推荐指数
2
解决办法
1万
查看次数

格式化打印到循环缓冲区

我正在为STM32F3 mc(STM32F3-Discovery)编写嵌入式代码.我需要输出一些数据,UART和我的使用DMA此,因为这可以让我专注于传感器读取和数据处理,而不是等待字节传输完成.然而问题是我必须结合:

  1. 格式化输出(即来自printf的一些)
  2. 连续多次打印(在上一次打印完成之前发生)

所以我在想循环缓冲区.但我不认为我知道如何使sprintf尊重缓冲区的结束并继续写入缓冲区的开头.我当然可以创建另一个临时缓冲区,在那里打印,并逐字节复制,但它对我来说并不优雅.

c printf stm32 circular-buffer

5
推荐指数
1
解决办法
1672
查看次数

STM32 USB OTG:如何正确刷新Tx FIFO?

F4xx系列芯片的STM32手册表示应用程序将TXFFLSH寄存器中的位写入OTG_FS_GRSTCTL以刷新TxFIFO.作为注释,它提到......应用程序必须在检查核心既不写入TxFIFO也不读取TxFIFO之后写入该位.作为一种方法,它建议确保NAK有效中断被设置(我认为这意味着寄存器中的GINAKEFFOTG_FS_GINTSTS)以确保内核不读取FIFO,并检查AHBIDL(AHB空闲)位OTG_FS_GRSTCTL被设置为保证FIFO中没有任何内容.STM提供的(糟糕的)USB OTG库忽略了这两种检查,而免费libopencm3库只检查AHB空闲位.我的问题如下:

  1. 在执行上述检查和写入TXFFLSH位之前,本手册未建议禁用USB OTG内核.这是否可以让核心可能在执行检查和写入TXFFLSH?之间开始使用FIFO .

  2. "NAK有效"位仅保证不会从非周期性端点的TxFIFO读取数据.除非核心被禁用,否则核心是否仍然可以将FIFO用于等时端点?

我知道这些都是"挑剔"类型的问题,但我正在研究的项目应该会产生一个非常可靠的硬件,客户多年来无法检查设备,因此这些微妙之处很重要(是的,我们启用了看门狗)等等,但我们需要核心在大多数时间没有重置的情况下工作.

usb arm stm32 usb-otg libopencm3

5
推荐指数
0
解决办法
1886
查看次数

为I2C配置STM32输出端口

我目前正在尝试使用一对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).

stm32 i2c stm32l152

5
推荐指数
1
解决办法
1万
查看次数

尝试打印大于等于10的数字时出现STM32硬故障

临时解决方法

我使用微小的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)

printf arm cortex-m3 stm32 newlib

5
推荐指数
1
解决办法
4041
查看次数

STM32 STM32CubeF4 USB CDC操作

我为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获取和发送角色.

c embedded usb cdc stm32

5
推荐指数
1
解决办法
5620
查看次数

即使没有使用STM32 gcc(arm-none-eabi-gcc)也链接printf

我似乎无法弄清楚为什么有些printf库函数会从libc_nano.a链接到我的代码中,即使我从不使用任何函数printf.它窃取了至少2K宝贵的闪存空间.我能看到的部分_printf_i,_vfprintf_r,_vfiprintf_r在我的链接器映射文件等.

我试过了

  • Wl, - exclude-libs选项
  • 链接描述文件中的EXCLUDE_FILE(..)

这些都不会使符号从地图文件中消失.

我的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.这是免费的软件; 查看复制条件的来源.没有保修; 甚至不适用于适销性或特定用途的适用性.

首先,他们为什么要联系起来?有没有办法排除它们?

linker printf gcc arm stm32

5
推荐指数
1
解决办法
1339
查看次数

更改运行中断处理程序的优先级?

我试图在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系列中没有?有没有更好的方法呢?

embedded arm cortex-m3 stm32

5
推荐指数
1
解决办法
565
查看次数

为n个cpu周期添加延迟/什么都不做的最佳方法

我需要在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)

c embedded arm stm32 stm32f0

5
推荐指数
1
解决办法
1091
查看次数