自制小四轴

    返回首页    发表留言
本文作者:李德强
          第二节 使用操作系统
 
 

        配置并自动生成代码之后,我们就可以根据自己的需要完成相关的功能开发了。然而传统的单片机开发的方式通常是使用一个main()主函数中的一个while循环(死循环)来完成整个开发过程。就好像我们使用CubeIDE工具生成的源代码中一样,main()主函数中有一个永远不会终止的while(1)循环来使得单片机处理器始终处于运行状态:

 

/**
 * @brief  The application entry point.
 * @retval int
 */
int main(void)
{
	/* USER CODE BEGIN 1 */
	/* USER CODE END 1 */
	/* MCU Configuration--------------------------------------------------------*/
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();
	/* USER CODE BEGIN Init */
	/* USER CODE END Init */
	/* Configure the system clock */
	SystemClock_Config();
	/* USER CODE BEGIN SysInit */
	/* USER CODE END SysInit */
	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	/* USER CODE BEGIN 2 */
	/* USER CODE END 2 */
	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/* USER CODE END WHILE */
		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}

 

        我们可以很清楚的看到while(1)是一个死循环,我们可以将所有需要开发的功能都写入这这个循环当中去。然而与具有多线程的操作系统相比,这样的单任务死循环方式在使用和开发时还是有一些不方便的地方,因此我们需要将我们的工程中加入一个嵌入式操作系统,来完成我们的开发需要。在这里我们选用的操作系统为笔者自行开发的Dolphin-OS,这一款支持多线程、信号量、堆内存资源申请与释放、统一读写接口的操作系统。其功能简约,性能较好,且是实时操作系统,使用起来也比较方便。关于Dolphin-OS相关内容请读者参考《自制嵌入式实时操作系统》。

        这里,我们将直接把操作系统相关的代码加入到我们的工程中,参与整个工程的编译中去,从而完成操作系统的特定功能。我们把Dolphin-OS操作系统(后续简称为OS)源代码下载并解压之后,可以得到一个名为kernel的文件夹,其中包含了OS的全部源代码,如下:

        我们需要把这个文件夹加入到我们在上一节中所生成的工程中去,或直接使用一个新的Makefile工程。我们选择了后者,我们在Linux下使用Makefile来编译一个全新的工程。我们需要把使用CubeIDE工具生成的源代码复制到一个新的目录中,并加入我们的kernel操作系统源代码,如下:

        其中,src文件夹中的main.c、stm32f1xx_hal_msp.c、stm32f1xx_it.c、syscalls.c、sysmem.c、system_stm32f1xx.c、startup_stm32f103c8tx.s、以及ld链接文件都从前面所讲述的CubeIDE所生成的代码中复制过来的。此外还包括Hal库的一些源代码,我们把它们存放到了libs目录里。

        之后,我们需要将OS的启用和配置加入到我们的工程中,首先需要在main.c中加入OS的头文件包含和OS的启动代码:

#include <core.h>
#include <sche.h>
int main(void)
{
	HAL_Init();
	SystemClock_Config();

	//其它代码省略

	kernel_startup();
	_kernel_startup = 1;

	while (1)
	{
	}
}

        之后,我们需要在stm32f1xx_it.c系统时钟中断处理函数中加入我们的OS调度函数,如下:

void SysTick_Handler(void)
{
	HAL_IncTick();

	if (_kernel_startup)
	{
		sche_tick();
	}
}

        这里我们使用的OS调度频率为1000Hz,也就是说OS每经过1MS会尝试进行一次调度。

        最后,我们给出整个工程的Makefile内容,如下:

ROOTPATH	=	../../
#------------------------------------------------------------------------#
# OS Arch
OS_ARCH		=	arm/armv7-m

#------------------------------------------------------------------------#
# Output files
ELF_FILE	=	dolphin-os.elf
BIN_FILE	=	dolphin-os.bin
HEX_FILE	=	dolphin-os.hex
INFO_FILE	=	dolphin-os.info
CODE_FILE	=	dolphin-os.code

#------------------------------------------------------------------------#
# Cross Compiler
CC_PRE		=	/data/app/local/gcc-arm-none-eabi-5_4-2016q3/bin/arm-none-eabi

CC			=	$(CC_PRE)-gcc
OBJCOPY		=	$(CC_PRE)-objcopy
OBJDUMP		=	$(CC_PRE)-objdump
READELF		=	$(CC_PRE)-readelf

#------------------------------------------------------------------------#
# Flags
#CFLAGS		+=	-DDEBUG
CFLAGS		+=	-Os -ffunction-sections -fdata-sections
CFLAGS		+=	-std=gnu11 -DUSE_HAL_DRIVER -DSTM32F103xB
CFLAGS		+=	-mcpu=cortex-m3 --specs=nosys.specs 
CFLAGS		+=	-Wl,--gc-sections -static --specs=nano.specs 
CFLAGS		+=	-mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
CFLAGS		+=	-T"dolphin-os.ld" 

# Libraries
STM32_LIBS	=	libs/STM32F1xx_HAL_Driver
CFLAGS		+=	-I$(STM32_LIBS)/Inc
CFLAGS		+=	-Ilibs/CMSIS/Include
CFLAGS		+=	-Ilibs/CMSIS/Device/ST/STM32F1xx/Include

#------------------------------------------------------------------------#
# Kernel Path
KERNEL_PATH	=	$(ROOTPATH)/kernel
CFLAGS		+=	-I$(KERNEL_PATH)/kernel
CFLAGS		+=	-I$(KERNEL_PATH)/lib
CFLAGS		+=	-I$(KERNEL_PATH)/fs

#------------------------------------------------------------------------#
# Src Path
SRCS		=	./src
CFLAGS		+=	-I$(SRCS)
CFLAGS		+=	-I./inc

#------------------------------------------------------------------------#
# Drivers Path
DRVS		=	$(ROOTPATH)/drivers
CFLAGS		+=	-I$(DRVS)
CFLAGS		+=	-I$(DRVS)/led

#------------------------------------------------------------------------#
# Modules Path
MODULES		=	$(ROOTPATH)/modules
CFLAGS		+=	-I$(MODULES)
CFLAGS		+=	-I$(MODULES)/led

#------------------------------------------------------------------------#
# Libs Path
LIBS		=	$(ROOTPATH)/libs
CFLAGS		+=	-I$(LIBS)

#------------------------------------------------------------------------#
# Main Board
SRC			+=	$(SRCS)/main.c

#------------------------------------------------------------------------#
# Drivers
SRC			+=	$(DRVS)/led/led.c

#------------------------------------------------------------------------#
# Modules
SRC			+=	$(MODULES)/led/led_task.c

#------------------------------------------------------------------------#
# Libs
SRC			+=	$(LIBS)/buff_s.c \
				$(LIBS)/crc.c \
				$(LIBS)/protocol.c \
				$(LIBS)/rand.c

#------------------------------------------------------------------------#
# System
SRC			+=	./src/system_stm32f1xx.c \
				./src/sysmem.c \
				./src/syscalls.c \
				./src/stm32f1xx_it.c \
				./src/stm32f1xx_hal_msp.c

STARTUP		=	./src/startup_stm32f103c8tx.s

#------------------------------------------------------------------------#
# Hal Libraries
SRC			+=	$(STM32_LIBS)/Src/stm32f1xx_hal.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_cortex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_adc.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_adc_ex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_dma.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_exti.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_flash.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_flash_ex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_gpio.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_gpio_ex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_i2c.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_pwr.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_rcc.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_rcc_ex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_spi.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_tim.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_tim_ex.c \
				$(STM32_LIBS)/Src/stm32f1xx_hal_uart.c

#------------------------------------------------------------------------#
# OS Arch
SRC			+=	$(KERNEL_PATH)/arch/$(OS_ARCH)/stack.c \
				$(KERNEL_PATH)/arch/$(OS_ARCH)/switch.S

#------------------------------------------------------------------------#
# OS Kernel
SRC			+=	$(KERNEL_PATH)/kernel/core.c \
				$(KERNEL_PATH)/kernel/pcb.c \
				$(KERNEL_PATH)/kernel/sche.c \
				$(KERNEL_PATH)/kernel/sem.c \
				$(KERNEL_PATH)/kernel/top.c \
				$(KERNEL_PATH)/fs/vfs.c \
				$(KERNEL_PATH)/fs/fs.c \
				$(KERNEL_PATH)/fs/fcntl.c \
				$(KERNEL_PATH)/lib/list.c

STARTUP_OBJ	=	startup_stm32f103c8tx.o

all:$(BIN_FILE) $(HEX_FILE) $(INFO_FILE) $(CODE_FILE)

$(BIN_FILE):$(ELF_FILE)
	$(OBJCOPY) -O binary $^ $@

$(HEX_FILE):$(ELF_FILE)
	$(OBJCOPY) -O ihex $^ $@

$(INFO_FILE):$(ELF_FILE)
	$(READELF) -a $^ > $@

$(CODE_FILE):$(ELF_FILE)
	$(OBJDUMP) -S $^ > $@

$(STARTUP_OBJ):$(STARTUP)
	$(CC) $(CFLAGS) $^ -c $(STARTUP)

$(ELF_FILE):$(SRC) $(STARTUP_OBJ)
	$(CC) $(CFLAGS)	$^ -o $@

install:
	#@st-flash write $(BIN_FILE) 0x8000000
	jlink -NoGui -commanderscript loadbin_cmd.jlink

clean:
	@rm -rvf *.o *.bin *.code *.elf *.hex *.info

        在这里我们使用了一个LED灯闪烁来确认OS是否已经正常工作了,关于LED灯闪烁的内容我们将在下一节中讲述。

 

    返回首页    返回顶部
  看不清?点击刷新

 

  Copyright © 2015-2023 问渠网 辽ICP备15013245号