无法将嵌入式c中的sleep()用于stm32
我尝试为stm32微控制器学习嵌入式c。我尝试编写一个简单的眨眼程序,使用sleep()函数 代码:无法将嵌入式c中的sleep()用于stm32,c,sleep,stm32,C,Sleep,Stm32,我尝试为stm32微控制器学习嵌入式c。我尝试编写一个简单的眨眼程序,使用sleep()函数 代码: /*包括------------------------------------------------------------------*/ #包括 #包括“main.h” 内部主(空) { HAL_Init(); 而(1) { HAL_GPIO_开关引脚(LD2_GPIO_端口,LD2_引脚); sleep(1);//编译时,此行抛出错误 } } 编译器给了我以下错误: /usr/li
/*包括------------------------------------------------------------------*/
#包括
#包括“main.h”
内部主(空)
{
HAL_Init();
而(1)
{
HAL_GPIO_开关引脚(LD2_GPIO_端口,LD2_引脚);
sleep(1);//编译时,此行抛出错误
}
}
编译器给了我以下错误:
/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 for arm gcc中安装了所有内容
OS:Fedora 30
IDE:CLion
工具链:Arm-gcc-none-eabi您不能在带有Arm-none-eabi-gcc编译器的裸机目标上使用POSIX函数。没有操作系统。没有
sleep()
,gettimeofday()
,clock\u gettime()
,getpid()
,fork()
,stat()
,pthread\u create()
,以及许多其他C、posix和*unix特有的函数。这些函数的声明可以在标准头中找到,但是链接器将放弃未定义的引用
错误。你必须自己实现它们
默认情况下,编译器arm ONE eabi gcc使用C标准库的实现。它附带了最基本的、不支持操作系统的功能,如snprintf
和mktime
。对于printf
或putc
等函数,应实现回调\u write()
或\u write\r()
,以使其正常工作。要使malloc()
正常工作,您必须提供sbrk()
。对于大多数其他功能,您必须自己实现它们
常用的-specs=nosys.specs
编译器选项只指定使用一些函数的“默认”无系统实现,如fseek()
或write()
或sbrk()
。大多数函数只返回-1
并将errno设置为ENOSYS
,但它们都在那里,这样您就可以编译程序了。可以找到实现
如果您碰巧使用stm32 hal库,您可以将systick中断初始化1毫秒,并使用stm32 worldhal\u Delay()
函数中的标准,并提供自己的sleep()
实现:
另一种方法是在设备上使用提供这些功能实现的操作系统。例如,有一个旨在提供POSIX兼容性并已经提供了许多调用的函数库。Micro controller可能没有包含标准库,因此在这种情况下,您必须滚动自己缺少的函数。例如,睡眠可以这样实现:
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);
}
void my_sleep(整数秒){
#按照65000000秒定义步骤
无符号整数i,s;
对于(s=0;s
顺便说一句,常数
STEPS_PER__SEC
应根据您的控制器CPU规格和编译模式(优化开/关等)进行经验调整。ld使用了哪些标志?已经有HAL_Delay()
函数,您可以使用它代替sleep()
这不是解决问题的方法,只是另一种方法。。。另外,您应该为GPIO
和GPIO
本身初始化CLK
。GPIO和CLK已初始化,但我忽略了它,bc不相关sleep
不是标准的,而是特定于Linux的。您的STM32不是Linux PC。此外,与您的问题无关,您需要在某处设置数据方向寄存器和端口映射。这不适用于优化。请参阅我的编辑-我添加了asm(“nop”)编译器优化未分解循环的代码>。如果STM32微控制器中也考虑了NOP,则可能会添加其他内容,而不是NOP,具体取决于平台/cpu。
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);
}