L4 F9 kernel微内核初探

F9 Kernel是一个实验性质的微内核实现,它受著名的L4微内核的启发,用来构建灵活的嵌入式系统。F9微内核开发的动机是运用最新的内核设计思想,在ARM Cortex-M系列微处理器上运行实时和分时应用程序(例如无线通信应用等),同时兼顾效率(性能+功耗)和安全性(内存保护+隔离执行)。它具备以下特点

  • F9遵循了微内核的基本原则,它只在处理器特权模式中实现地址空间、线程管理和IPC通信机制.
  • 为ARM Cortex-M系列设计和定制,支持NVIC(嵌套矢量中断控制器),位带,MPU(内存保护单元)。
  • 高效的调度和tickless机制,允许ARM Cortex-M仅在需要时唤醒,无论是在预定的时间或中断事件。因此,它比使用系统计时器SysTick的常用方法产生更好的节能效果,后者需要一个不断运行的高频时钟。
  • 支持KProbes机制,KProbes是一种受Linux内核启发的动态检测系统,它允许开发人员收集关于内核操作的额外信息,而无需重新编译或重新启动内核。它允许用代码插入内核中的位置,当ARM核心遇到探测点时,插入代码就会运行。一旦插装代码完成执行,内核将继续正常执行。
  • 每个线程都有自己的TCB(线程控制块),并由其全局id寻址。dispatcher负责切换上下文。具有相同优先级的线程以循环方式执行。
  • 内存管理方式有三种
    1. 内存池(Memory pool),它代表具有特定属性的物理地址空间区域。
    2. 灵活页( Flexible page),它描述了地址空间的一个总是大小对齐的区域。与其他L4实现不同,F9中的灵活页面代替了MPU区域。
    3. 地址空间(Address space),由这些灵活的页面组成。
  • 提供系统调用用来管理地址空间
    1. Grant:将内存页授予给新用户,不能再被前用户使用.
    2. Map:这实现了共享内存——内存页被传递给另一个任务,但两个任务都可以使用.
    3. Flush:已映射给其他用户的内存页将从其地址空间中Flush.
  • 关于用户线程和微内核之间的交互,正在采用UTCB(用户级线程控制块)的概念。UTCB是线程虚拟地址空间中的一个特定于线程的小区域,它总是被映射的。因此,对UTCB的访问永远不会引发页面错误,这使得内核能够很好地访问系统调用参数,特别是从/复制到用户线程的IPC有效负载。
  • 内核提供了同步IPC(进程间通信),短IPC仅在CPU寄存器中携带有效负载,而完整的IPC通过通信双方的UTCBs复制消息有效负载。
  • 支持内核调试和分析机制:
    1. 可配置调试控制台
    2. 内存转储
    3. 线程分析:名称、正常运行时间、已分配/当前/已使用的堆栈
    4. 内存分析:内核表,池空闲/已分配大小,碎片

开发板:

本环境使用的开发平台是STM32F407G-DISC1,它是stm32f4-discovery系列,主控为Cortex-M4F核,支持板载st-link调试器,开发板资源如下所述:

  • STM32F407VGT6 in LQFP100 package
  • ARM® 32-bit Cortex® -M4 CPU with FPU
  • 168 MHz max CPU frequency
  • 1 MB Flash
  • 192+4 KB SRAM including 64-Kbyte of core coupled memory
  • GPIO with external interrupt capability
  • 3x12-bit ADC with 24 channels
  • 2x12-bit D/A converters
  • USART/UART (6)
  • ......

STM32F4DISCOVERY Discovery有6个UARTs. 默认配置是115200 8N1.  需要留意的是 ST-Link Virtual Com Port is not wired to chip serial port. In order to enable console output you should use a serial cable and connect it to UART pins.

烧录说明,STM32F4DISCOVERY Discovery板载一个ST-LINK/V2调试器,它可以配合OPENOCD实现裸机烧录。

获取内核:

 f9 kernel按照BSD开源协议托管在github上,内核不大,通过简单git clone命令即可完成下载.

git clone https://github.com/f9micro/f9-kernel.git

配置内核:

f9 kernel的构建环境依赖和linux相同,都是mconf,如果PC机之前有搭建linux的开发环境,则可以直接开发,否则,按照linux的开发标准安装依赖.

执行make config呼出类似于linux的menuconfig配置界面:

平台选择STM32F4,使用默认的串口(usart4),也就是板载的PA0和PA1 PIN脚,串口和pin脚的映射关系是:

编译内核:

配置完成后,退出配置菜单前点击保存配置.退出后,在控制台下直接执行make命令,即可编译内核:

执行make clean,清除编译中间文件和编译结果

如果想探查每个文件的编译细节,可以执行make V=1

根据上图的输出细节,可以看出,输出目标包括f9.elf,f9.elf.bin和f9.bin,其中f9.bin和f9.elf.bin是完全相同的,都是f9.elf对应的二进制文件.

烧录内核:

开发板支持USB模拟磁盘烧录方式,系统启动后,平台会在PC端模拟出一个磁盘,这时候可以将编译结果文件f9.bin拷贝到虚拟磁盘中,磁盘本身是虚拟的,拷贝过程其实就是烧录过程,拷贝结束后,重启,则启动烧录固件.除此之外,zephyr的west环境有对应的烧录工具,应该也支持烧录f9 kernel,后面可以一试,这里首先使用第一种磁盘烧录方式:

copy内核到虚拟磁盘完成烧录:

连接USB2TTL串口线到USART4(PA0,PA1),使用minicom观察启动时内核输出.

使用st-flash 烧录内核:

烧录:

st-flash write f9.bin 0x8000000

读取:

st-flash read firmware.bin 0x8000000 0x1000

擦除:

st-flash erase


基于zephyr环境的烧录和调试:

我们想利用zephyr的环境来烧录和调试f9 kernel,就先看一下zephyr是如何玩儿这块开发板的:

第一步:按照zephyr官方文档安装好zephyr开发环境,包括安装west,cmake,sdk tools,requirements.txt依赖以及下载代码.

第二步:需要安装elftools,否则编译DISCO1开发板工程会报错,不知道为什么requirements.txt没有列出安装,执行pip3 install pyelftools.

第三步:编译:

首先执行west  build -t clean 清除上次编译结果文件

然后执行west build -b stm32f4_disco samples/basic/blinky,编译blinky项目,如下图:

第四步:烧录

zephyr烧录不依赖上面用到的虚拟磁盘机制,而是基于ocd和stlink.

连接好USB口,执行west flash

 ga

观察打印信息,注意,zephyr使用的串口和f9 kernel有所不同,zephyr使用串口usart2,也就是PA2/PA3.

第四步:调试

west build -b stm32f4_disco samples/hello_world

west flash

串口信息,固件已经烧录进去:

之后,执行west debug,调试helloworld程序


结束!

猜你喜欢

转载自blog.csdn.net/tugouxp/article/details/113819431