在使用STM32CubeMx创建FreeRTOS应用程序项目时,有两种方法可以用来引入延迟,即osDelay和HAL_Delay.
它们之间有什么区别,应该首选哪一个?
osDelay代码:
/*********************** Generic Wait Functions *******************************/
/**
* @brief Wait for Timeout (Time Delay)
* @param millisec time delay value
* @retval status code that indicates the execution status of the function.
*/
osStatus osDelay (uint32_t millisec)
{
#if INCLUDE_vTaskDelay
TickType_t ticks = millisec / portTICK_PERIOD_MS;
vTaskDelay(ticks ? ticks : 1); /* Minimum delay = 1 tick */
return osOK;
#else
(void) millisec;
return osErrorResource;
#endif
}
Run Code Online (Sandbox Code Playgroud)
HAL_Delay代码: …
我无法将USART_1与蓝牙hc-05连接.微控制器是STM32F103RB.这是代码(我没有使用任何库)
#define APB2_FREQ 72000000
void USART1_Send(char* data)
{
unsigned int length = 0;
while(data[length] != '\0')
++length;
int i = 0;
while(i < length)
{
while((USART1_SR & 0x00000080) == 0); // wait if transmit data register is not empty
USART1_DR = data[i];
++i;
}
}
char USART1_Receive()
{
while((USART1_SR & 0x00000020) == 0); //wait for data to arrive
return USART1_DR;
}
void USART1_Init(int baudrate, short parity, short stop)
{
RCC_APB2ENR |= 0x00004004; // enable Port A, enable usart1 clock
GPIOA_CRH …Run Code Online (Sandbox Code Playgroud) 我在STM32F107VC上使用FreeRTOS V6.1.1并且经常出现malloc错误.堆区域在链接器脚本中定义,但在几次分配后它仍然卡在pvPortMalloc()的这个循环中:
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
pxBlock: 0x20002300
pxPreviousBlock: 0x20002300
pxNewBlockLink: 0x00
xHeapHasBeenInitialised: 0x01
Run Code Online (Sandbox Code Playgroud)
链接器脚本:
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20010000; /* end of 64K RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = …Run Code Online (Sandbox Code Playgroud) 我在PC(mingw32,32bit arch)上模拟来自嵌入式系统(stm32,KeilμVision5,MDK-ARM)的代码.ARM编译器的对齐方式与我的桌面mingw构建不匹配:
// ARM Code (ARM compiler uses __packed)
typedef __packed struct _file
{
uint8_t var1;
uint16_t var2;
} FILE;
// PC mingw gcc code trying to emulate layout above.
typedef struct __attribute__((packed, aligned(1))) _file
{
uint8_t var1;
uint16_t var2;
} FILE;
Run Code Online (Sandbox Code Playgroud)
在源代码中,我执行以下操作:file.var1 = 0x22; file.var2 = 0xAA55;然后将其写入内存.当我读取它显示的嵌入式系统上的内存时0x22, 0x55, 0xAA.在Windows机器上读取0x22, 0xFF, 0x55, 0xAA,与在2填充第二个字节.我该如何纠正这种行为?
临时解决方法
我使用微小的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) 我想实现一个GPIO中断,但我不知道如何,我也没有找到真正的样本或解释.
我已经知道如何写Pins,但不多,请考虑我真的没有任何关于c或编程微控制器的知识.
一个简单的例子或解释将帮助我很多.以下代码是我已经拥有的,但我不确定这是否正确.
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_2;
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
Run Code Online (Sandbox Code Playgroud) 我试图在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系列中没有?有没有更好的方法呢?
我想从我的用户代码写入 STM32F407VGT 的闪存扇区 11 以存储一些数据。我用过stm32f4xx_hal_flash.c图书馆。我首先使用以下代码擦除扇区:
void Flash_Init(void)
{
FLASH_EraseInitTypeDef pEraseInit;
pEraseInit.Banks = FLASH_BANK_1;
pEraseInit.NbSectors = 1;
pEraseInit.Sector = FLASH_SECTOR_10;
pEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
if(HAL_FLASH_Unlock() == HAL_OK)
{
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
HAL_FLASHEx_Erase(&pEraseInit,0);
HAL_FLASH_Lock();
}
}
Run Code Online (Sandbox Code Playgroud)
程序在到达HAL_FLASHEx_Erase(&pEraseInit,0);函数时挂起。我的分散文件如下所示:
LR_IROM1 0x08000000 0x01000000 { ; load region size_region
ER_IROM1 0x08000000 0x01000000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00020000 { ; RW data …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 STM32F042 微控制器上读取 VDDA。我在 VDD 为 3.29V 时得到了意想不到的结果。我一定缺少一些基本的东西。
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1885; VREFINT_CAL=1524; VDDA=2668 mV
VREFINT=1913; VREFINT_CAL=1524; VDDA=2628 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
Run Code Online (Sandbox Code Playgroud)
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1885; VREFINT_CAL=1524; VDDA=2668 mV
VREFINT=1913; VREFINT_CAL=1524; VDDA=2628 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
VREFINT=1917; VREFINT_CAL=1524; VDDA=2623 mV
Run Code Online (Sandbox Code Playgroud)
我已经使用 C++ 编写了一个在 ARM Cortex-M (STM32F0) 上运行的项目,但是我在将定义的缓冲区作为类成员访问时遇到了一些问题,尽管我通过将它们定义为全局变量来解决这个问题。
但是现在我完全被这个新问题困住了,我不知道该怎么办。
我有一个代码可以解锁闪存并向其中写入内容并关闭它。如果我在 C 文件中实现它并通过 C 自然运行它(从 main.c 调用)它工作完美。但是通过 C++ 文件(无论是写在 C 还是 C++ 源文件中)调用它会抛出一个 HardFault 异常。
static uint32_t waitForLastOperation(uint32_t msDelay)
{
while (READ_BIT(FLASH->SR, FLASH_SR_BSY) && msDelay)
{
LL_mDelay(1);
msDelay--;
}
/* Check FLASH End of Operation flag */
if (READ_BIT((FLASH->SR), (FLASH_SR_EOP)))
{
/* Clear FLASH End of Operation pending bit */
(FLASH->SR) = (FLASH_SR_EOP);
}
if (READ_BIT((FLASH->SR),
(FLASH_SR_WRPERR)) || READ_BIT((FLASH->SR), (FLASH_SR_PGERR)))
{
FLASH->SR = 0U;
return 0;
}
/* There is no error …Run Code Online (Sandbox Code Playgroud)