配置并自动生成代码之后,我们就可以根据自己的需要完成相关的功能开发了。然而传统的单片机开发的方式通常是使用一个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
#include
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号