当前位置:首页 > 技术文章 > 正文内容

从裸机到微内核:JxOS 让你看懂 RTOS 是怎么“长出来”的!

zonemu2个月前 (08-26)技术文章21

“学 RTOS,光看 FreeRTOS 不够;自己写一个小 OS,才是真的懂。”

在 STM32、RISC-V 等 MCU 项目的开发中,许多初学者面临着从裸机到操作系统的转变难题。FreeRTOS 功能齐全,却结构复杂,直接上手容易迷失。

今天我们来介绍一个极具教学价值的开源项目 —— JxOS,一个面向学习者与轻量开发的 精简型实时操作系统内核,用几十个 C 文件,构建出一个“麻雀虽小五脏俱全”的 RTOS!

JxOS 是什么?

JxOS 是由 Jeremy Cheng 维护的开源微型操作系统内核,使用纯 C 语言实现,适用于裸机 MCU(如 STM32)开发者学习 RTOS 原理。它具备如下特性:

  • 多任务调度(基于时间片轮转和优先级)
  • 简单的信号量、消息队列
  • 软件定时器机制
  • 模块化设计,适合移植
  • 支持 Keil / IAR / GCC 编译器

这不是另一个“简化版 FreeRTOS”,而是一个让你“从零构建内核”的教学式框架!

内核核心模块解析

1. 任务控制结构(JxTask)

JxOS 的每个任务由一个结构体管理:

typedef struct {
    uint32_t *stackPtr;      // 当前堆栈指针
    uint32_t priority;       // 优先级
    uint32_t delayTicks;     // 延时计数
    uint8_t  state;          // 任务状态
} JxTask;

系统会将任务调度信息统一维护在一个任务列表中。

2. 任务创建(jx_task_create)

你可以通过如下方式创建任务并注册到系统调度器:

void Task1Entry(void *param) {
    while (1) {
        // 任务循环
    }
}

jx_task_create(&task1, Task1Entry, NULL, &task1Stack[1024], 10);
  • 第一个参数:任务控制块
  • 第二个参数:任务入口函数
  • 第四个参数:堆栈顶地址
  • 第五个参数:任务优先级

这类手动建栈、注册任务的方式,虽然比 FreeRTOS 繁琐,但更贴近裸系统设计原理,非常适合教学与自定义扩展。

任务调度机制

核心调度器 jx_task_schedule()

在主循环或系统 tick 中断中,JxOS 会周期性调用调度器:

void jx_task_schedule(void) {
    // 遍历任务表,根据优先级和状态找到最高优先级就绪任务
    // 切换上下文
}

上下文切换是通过手动保存/恢复堆栈指针实现的,支持 ARM Cortex-M 架构的 PendSV 中断实现。

void PendSV_Handler(void) {
    jx_task_switch();  // 汇编级别切换上下文
}

这一步是大多数学习者第一次真正接触“任务上下文切换”的关键点!


软件定时器机制

类似 soft_timer 的思路,JxOS 也内置了简单的软件定时器模块:

typedef struct {
    uint32_t delayTicks;
    void (*callback)(void *);
    void *arg;
    uint8_t active;
} JxTimer;

使用方法:

void Blink(void *arg) {
    ToggleLED();
}

JxTimer blinkTimer;
jx_timer_create(&blinkTimer, Blink, NULL, 500);
jx_timer_start(&blinkTimer);

在 SysTick_Handler 中调用 jx_timer_tick() 即可完成倒计时处理与回调触发。


信号量机制:轻量同步工具

JxOS 实现了基础信号量接口:

typedef struct {
    uint32_t count;
    JxTask *waitQueue[MAX_TASK_NUM];
} JxSemaphore;

使用示例:

JxSemaphore sem;
jx_sem_init(&sem, 1);  // 初始化为1,类似二值信号量
jx_sem_wait(&sem);     // 等待(阻塞任务)
jx_sem_post(&sem);     // 释放(唤醒任务)

适用于按键防抖、串口接收完成信号等场景。虽然不如 FreeRTOS 那样支持复杂队列和嵌套调度,但对于入门已经绰绰有余。


模块化结构与扩展性

项目目录结构清晰:

JxOS/
├── core/         // 内核核心模块
├── hal/          // 硬件抽象层
├── timer/        // 软件定时器
├── sync/         // 信号量与消息机制
├── example/      // 应用示例
└── port/         // 平台移植代码(如 Keil、GCC、IAR)

移植到其他平台只需实现几组函数,如上下文保存/恢复、定时中断驱动等,非常适合初学者练手。


总结:不是给你用的,是给你学的!

相比那些复杂笨重的大型 RTOS,JxOS 更像是一位耐心的老师,带你一步一步从裸机走向系统开发的世界。

无论你是嵌入式入门者、大学生做课程设计,还是想精进 RTOS 基础的工程师,这都是一个不可多得的学习资源。

开源地址:
https://gitee.com/jeremyceng/JxOS

推荐 Star 收藏,用代码精读学习 RTOS,从此不再是“黑盒”!

相关文章

2020年最漂亮的7个Linux发行版(最受欢迎的linux发行版)

请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习1. 前言对于想学习Linux的朋友们,心中一定有疑问,哪个Linux版本比较好入门,Li...

Vue3开发极简入门(15.1):emits补完-结合v-model

之前代码是通过按钮触发emit,如果希望输入框里的内容在输入之后也能同步到父组件,就可以结合v-model的update事件来操作,具体如下。Son2.vue:<template>...

Vue 2 和 Vue 3的区别(vue2和vue3的区别有哪些)

1.双向数据绑定原理不同Vue2 的双向数据绑定是利用ES5的一个APIObject.definePropert() 对数据进行劫持,结合发布订阅模式的方式来实现的。Vue3 中使用ES6的Proxy...

Gitlab 的使用和代码审查流程介绍

1、先简洁介绍下项目常用的信息-面板统计页面2、用户信息面板3、服务器信息4、项目信息5、重点介绍代码提交审核机制和授权合并机制开发人员推送代码的时候不能直接推送到master,否则就会报错。此时开发...

程序员效率提升!使用自动化工具gitx,每周节约半小时

你是否经历过这样的折磨?一个 JIRA 需求要同时修复 dev、qa、staging 三个分支每个版本涉及 A、B、C 三个项目手动执行以下操作:从 dev 切临时分支cherry-pick 提交推送...

基于Docker构建安装Git/GitLab,以及制作springboot工程镜像

今天给大家分享的是《领先的开源自动化服务器Jenkins的应用实战》之基于Docker安装构建Git/GitLab版本控制与代码云存储的场所;使用Git管理项目,springboot工程制作镜像知识体...