繁体   English   中英

无法在stm32的嵌入式c中使用sleep()

[英]cant use sleep() in embedded c for stm32

我尝试为stm32-microcontorller学习嵌入式c。 我尝试编写一个简单的眨眼程序,在该程序中使用sleep()函数。

码:

/* Includes ------------------------------------------------------------------*/
#include <unistd.h>
#include "main.h"

int main(void)
{
  HAL_Init();

  while (1)
  { 
    HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);
    sleep(1);  // this line throws a error, when compiling
  }
}

编译器给我以下错误:

/usr/lib/gcc/arm-none-eabi/7.4.0/../../../../arm-none-eabi/bin/ld: CMakeFiles/untitled2.elf.dir/Src/main.c.obj: in function `main':
/home/heinrich/CLionProjects/untitled2/Src/main.c:106: undefined reference to `sleep'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/untitled2.elf.dir/build.make:391: untitled2.elf] Fehler 1
make[2]: *** [CMakeFiles/Makefile2:73: CMakeFiles/untitled2.elf.dir/all] Fehler 2
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/untitled2.elf.dir/rule] Fehler 2
make: *** [Makefile:118: untitled2.elf] Fehler 2

我认为,问题是未安装的库,但我在fedora-repos中为arm-gcc安装了所有程序

操作系统:Fedora 30 IDE:CLion工具链:Arm-gcc-none-eabi

您不能通过arm-none-eabi-gcc编译器在裸机目标上使用POSIX函数。 没有操作系统。 没有sleep()gettimeofday()clock_gettime()getpid()fork()stat()open()pthread_create()以及许多很多其他C和posix和* unix专用函数。 这些函数的声明可以在标准头文件中找到,但是链接器只会放弃undefined reference错误。 您必须自己实现它们。

默认情况下,编译器arm-none-eabi-gcc使用C标准库的newlib实现。 它带有大多数基本的但不是操作系统已知功能的实现,例如snprintfmktime 对于诸如printfputc之类的printf应实现_write()_write_r()回调,以使其正常工作。 为了使malloc()工作,您必须提供sbrk() 对于大多数其他功能,您必须自己实现。

常用的-specs=nosys.specs编译器选项仅指定使用fseek()write()sbrk()类的某些功能的“默认”无系统实现。 这些函数大多数ENOSYS返回-1并将errno设置为ENOSYS ,但是在那里,因此您可以编译程序。 可以在这里找到实现。

如果碰巧使用了stm32 hal库,则可以将systick中断初始化1毫秒,并使用stm32世界中的HAL_Delay()函数中的标准并提供您自己的sleep()

unsigned int sleep(unsigned int seconds) {
   HAL_Delay(seconds * 1000);
   return 0;
}

另一种方法是在设备上使用提供这些功能实现的操作系统。 例如,有一个RIOT OS旨在提供POSIX兼容性,并且已经提供了许多调用。

微控制器可能不包含标准库,因此在这种情况下,您必须滚动自己缺少的函数。 例如,睡眠可以这样实现:

void my_sleep(int secs) {
  #define STEPS_PER_SEC 650000000
  unsigned int i,s;
  for (s=0; s < secs; s++) {
    for (i=0; i < STEPS_PER_SEC; i++) {
       // skip CPU cycle or any other statement(s) for making loop 
       // untouched by C compiler code optimizations
       asm("nop");
    }
  }
}

int main() {
   my_sleep(1);
}

顺便说一下,常数STEPS_PER_SEC应该根据您的控制器CPU规格和编译模式(优化打开/关闭等)进行经验调整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM