“没有免费的午餐”定理或预示AGI难产

随风

要问最近AI届什么最出圈,你一定能够脱口而出,没错它就是GPT5。过去了超过两年时间万众期待的GPT5终于亮相,尽管其性能可以称得上领先,但大家普遍的反馈仍然是非常失望,对于企业用户更是没有掀起多少波澜,大家仍然用着各种开源的模型做落地,用着Cluade模型进行AI编程。大家所期待的翻天覆地的变化不再出现。

GPT5模型并非单一架构,其内置的路由模块能够自动决策是否调用深度思考模型。这种设计乍看之下颇具威力,然而现实应用却并非如此理想。用户需求本就纷繁多样,这种看似智能的设定,恰恰因其不确定性成为了使用体验不稳定的根源。例如,当用户询问旅游攻略时,启用深度思考显然是合理的选择。然而,现实中的大部分场景远非如此简单易判。以智能家居垂直应用为例:用户发出“我回家了”的指令,模型究竟应该深度思考生成复杂响应,还是进行快速直觉性反应?事实上,这两种处理方式都只符合部分用户的需求。

问题的核心在于,当前的路由机制难以精准捕捉用户意图的微妙差异以及场景的复杂性。一刀切的“智能”决策,在需求边界模糊的日常场景中显得力不从心。用户可能希望“我回家了”触发一系列预设的快捷操作(如开灯、调温),此时深度思考反而显得冗余且迟缓;而在另一情境下,用户或许期待模型能基于当前环境(如天气、时间、家庭成员状态)进行更深层次的推断与个性化响应(比如询问“是否要播放放松音乐?”或“晚餐有什么建议?”)。这种“应该深度思考还是快速响应”的模糊地带,恰恰是路由模块最易出错之处。

这种不稳定性不仅可能导致响应延迟(深度思考耗时),更会带来预期之外的交互结果,破坏用户体验的连贯性和可预测性。用户无法建立稳定的心智模型去理解GPT5在不同时刻的行为逻辑,每一次交互都可能是一次“开盲盒”。在强调效率与确定性的垂直领域(如智能家居、客服、生产力工具),这种不确定性尤为致命。它削弱了用户对模型的信任感,也阻碍了其在关键场景的深度集成。

因此,仅仅依赖模型内部“黑盒”式的路由决策是远远不够的。未来的优化方向可能需要引入更精细化的用户意图识别技术、结合显性的用户偏好设置(允许用户预设特定场景的处理倾向),或者发展更强大的上下文感知能力,使模型能动态理解当前对话的“深度需求临界点”。否则,路由模块的“智能”设计,反而可能成为制约GPT5真正理解并高效服务用户的瓶颈。更要命的是GPT5一旦路由模块出现故障还可能引起智商大规模降低,本应智能分配问题至快速响应或深度思考模式的系统失灵,使 GPT-5 在简单任务中表现迟滞。

事实上我们并非反对GPT5的实时路由设计,恰恰是我们是实时路由系统的较早拥抱者,我们很早提出了实时语义路由系统,进行智能家居场景的智能体加速方案,但在长期实践中我们遇到了各种问题,本以为能够显著降低成本和延时,然而实际上并未如同我们想像一般强大,反而遇到了许多问题,那么如何使得实时语义路由系统发挥出其本应显现的威力呢,我想答案就藏在我们的标题里面——“没有免费的午餐”,即不存在一种强大的单一的智能模型解决所有问题,因此个性化和用户偏好设置在AI时代仍需存在,不能指望AI系统能理解我们所有的请求,事实上即使是人本身也不可能做到,你无法百分百的满足你父母和身边人的期望,我们只能通过沟通与交流进行尽可能的做到完美,也不存在一个全知全能的人,这不正是 “没有免费的午餐” 定理的生动写照嘛。

因此所谓的AGI即通用人工智能很可能永远无法实现,通用人工智能满足了全知全能的特性,这不就是赛博上帝吗?AGI之路注定不可能是一帆风顺的,也许会彻底失败,就像永动机一样被证伪,也可能像室温超导一样陷入“罗生门”,最好的结果就是人类取得了突破,但无论结果如何GPT5表现不佳恐怕已经是板上钉钉,那么接下来的GPT6会不会取得新的突破呢?那我们就拭目以待吧。

社区开源AI智能体项目链接 :https://github.com/ruanrongman/IntelliConnect

MCP协议正成为Aiot的新宠儿

随风

随着大模型的飞速发展,大模型对于现实世界的交互也有了长足的进步,Langchain成为打响这一战役的第一枪,其使用提示词的方式率先使得大模型得以与现实世界交互,随后OpenAi推出了具有代表意义的Function Calling技术,这项技术使得模型可以“调用”外部函数,它成为了模型与外界交互的新选择,随后智能体技术得到了巨大的发展,Agently和Promptulate等智能体框架飞速发展,使其成为2024年AI应用的宠儿。随后Dify和Coze等智能体应用也应运而生,它们的特点都是针对AI的不稳定性质,对其使用人工编排的WorkFlow即工作流替代,使其成为企业落地的首选。按照这个发展趋势,统一的智能体或者框架类似web世界的各种框架应当得到巨大发展,极大减少人们开发AI应用的成本。

然而故事却在2025年发生了巨大的变化,智能体框架不再成为大家落地AI应用讨论最多的点,业界开始着眼于工具调用统一协议这个问题,于是mcp协议开始走向大众视野,一时间各种营销号开始疯狂鼓吹mcp能够实现的各种强大功能。然而很多人却没有理解mcp的本质。MCP 是一个开放协议,它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样,MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口。

MCP协议的飞速发展,衍生出了各种MCP服务提供者,其后形成了MCP市场生态,这极大的丰富了AI应用的能力边界。而后MCP协议开始进军传统的物联网行业,开始成为控制万物的新协议,著名的开源项目小智AI就全面拥抱了MCP协议,使得其可以轻松扩展各种丰富有趣的功能。然而MCP协议获得巨大成功的同时却又由于自身设计的局限,对其进一步发展产生了限制,比如MCP协议的服务端,其设计初期MCP服务器运行多在本地,用于给克劳德客户端使用,然而对于云服务提供的开发者来讲却出现了一些困难。SSE协议的不稳定,随后虽然有stremable http的替代但是至今未形成强大的生态。小智不得不破坏了一些MCP规范来获得远程服务端的支持,小智AI具体方案是将MCP服务端视为客户端,创造了一个新的管道链路层,这种办法虽然能够解决当下的问题,然而属实是不够优雅,需要开发者重新适配,造成了当今大家都是MCP协议却无法互通的尴尬局面,多少与Type C有些类似了。

MCP协议作为通用的协议,其始终也未能解决工具编写依赖精巧提示词设计的问题,这也不是MCP协议该解决的问题,更让人头疼的是MCP混乱的服务器命名和工具设计,导致其稳定性堪忧,在生产环境上无法有效运用的问题,在AIOT领域虽然其动态发现,动态注册的优势十分明显,但其却无法较好解决跨设备控制,以及更复杂的设备控制场景,究其原因还是因为其设计之初并没有考虑AIOT的应用场景,因此我觉得MCP协议作为智能体能力扩展本身意义非凡,但应用于AIOT领域则需要等待时间的验证。

很久没有写过这么长的随笔了,感谢大家看到这里,欢迎关注我们社区公众号,我们下期不见不散。

想不想拥有一个本地的DeepSeek,快跟我一起来部署一个本地版本吧

随风

使用硅基流动+chatbox的方式可以解决当前官网卡顿的问题,但是有些时候我们出外做项目或者是在需要保密的场景,我们可能无法使用联网的大模型,那怎么办呢?别急,本地部署大模型是你的最后选择,使用Lmstduio部署本地大模型是当前最简单的本地大模型部署方法,可以让你轻松尝试到不用联网也能畅快玩耍Ai的快感。

首先我们下载LM Studio – Discover, download, and run local LLMs软件。

安装完成后就会出现以下界面

我们点击左侧放大镜图标,根据自己电脑的性能,选择一款自己想下载的模型(我的电脑是Rtx4060,可以流畅运行7B的DeepSeek模型)其它配置的电脑可以点击尝试,如果可以运行的话LmStudio会出现绿色图标,表示可以运行。

下载完成后,回到主页面,设置好参数,可以按照我的配置进行设置(一般默认即可),点击加载模型(load model)。

然后就可以愉快玩耍了。

不得不说AI的进步真的是一日千里,DeepSeek将R1蒸馏成多个尺寸的版本使得总有一款模型适合你的电脑,开源模型将加速端侧AI时代的到来,也使得个人开发者和用户也能参与到AI的滚滚洪流之中,最后想说一句——开源力量是很难阻挡的。

DeepSeek官网访问不稳定,如何使用硅基流动配合chatbox实现稳定输出

随风

当前DeepSeek模型可谓是当红炸子鸡,其强大的性能,低廉的训练成本,使得其在AI界迅速走红,创万联在年初就已经基于其开发Ai原生应用 ruanrongman/IntelliConnect: A Powerful AI agent IoT platform core. 在开发中其强劲的模型能力带来了愉悦的开发体验,但最近由于用户激增,网络攻击等原因,官网使用经常出现访问不稳定,问一个问题很容易出现服务器限流,这严重影响了用户体验,但幸运的是 DeepSeek 是开源模型,因此许多第三方平台,或者是自己本地部署均可以实现 DeepSeek模型自由。

首先打开硅基流动官方,这里可以使用我的邀请链接,双方均可以获得更多免费额度。https://cloud.siliconflow.cn/i/dlfqbBUr,注册之后进入界面,点击左侧API密钥,进入到API密钥栏目,点击新建API密钥复制备用。

然后下载chatbox,这是一个第三方的界面友好的对话引擎,官网为Chatbox AI官网:办公学习的AI好助手,全平台AI客户端,官方免费下载,安装之后点击设置,输入自己的API密钥,选择v3或者思考模型R1即可流畅使用。

希望以上教程可以帮助到各位朋友流畅的使用DeepSeek模型。下期还会给大家介绍如何本地部署自己的DeepSeek模型,实现桌面AI时代。

关于启英泰伦芯片开发有感

研发部

随着chatgpt的发布,人工智能开始进入了大模型时代,2024年时毫无争议的AI应用元年,各种AI应用如雨后春笋般的产生。其中智能体技术堪称是开发的革命性技术,我们也由此推出了可能是首个专为智能体应用设计的物联网平台ruanrongman/IntelliConnect: A Powerful AI agent IoT platform core. 。但这物联网平台的落地远不是开发出来就结束,没有实际的落地应用就像设计精美但无人使用的操作系统一样没有任何价值。为此我们坚持与兴趣相投的各种组织开展各种合作活动,其中我们非常看重AI陪伴的未来价值,因此加入到了潦草小狗的开发计划中。详细可以观看:潦草小狗驱动开发入门教程 —— 发送外部音频数据至 CI1303 例程

潦草小狗是陪伴型的桌面宠物,配合ic平台的功能,将有望能实现流畅的对话和各种控制和思考能力。ic平台和潦草小狗基本已经完成大半,目前最为困难的就是如何实现语音的双向传输,以及本地识别和云端能力的有机结合。为此我们选用了启英泰伦这款语音芯片,我们花了很多时间对其sdk进行仔细观看,按照如下方案启英泰伦 CI1303 算法 SDK 开发入门教程,对其进行配置,但播放功能一直出现芯片反复重启的问题,使用内部时钟源的时候, 开启播放外部音频宏, 自动校准波特率和开始两个中断会导致 flash 分配问题 芯片随即重启,我们对此非常困惑,最后rymcu的hugh大佬提出按如下修改了部分源码,该问题才得到一些改善,能够正常运行。

然而随即也开始面临芯片MP3解码的挑战,由于其仅支持16kbps,单声道串口传输。这种低码率的声音很少TTS模型能够支持,因而需要自行编写转换代码,测试了多种方案,目前仅如下方案,能够正常运作。使用pydub进行转码。

audio_segment = audio_segment.set_channels(1)
audio_segment = audio_segment.set_frame_rate(16000)  # 设置采样率为16 kHz
audio_segment = audio_segment.set_sample_width(1)  # 设置样本深度为8位(1字节)

但是较长语音问题仍旧非常困扰我们,猜测是解码器存在一些问题,我们将持续研究,期望能有所推进。

上述内容仅为本人实践日志,不涉及芯片本身的质量以及相关产品能力。

纪念社区成立的7周年-梦与实

随风

转眼间创万联社区已经陪伴大家7年了,不知道朋友们是否还记得那个艳阳高照的下午,我们意气风发的在新会一中的操场上讨论着对未来科技的畅想。也许时间早就将一切抹平了,但我依旧清晰记得当时的愿景,希望做一个智能电梯系统或者是远程的煤气中毒报警系统。我和孙,李三人组成了最初的小组,我们奔走于化学实验室和简陋的杂物间,靠着市面上的物联网模块我们终于做出了能够检测和远程手机报警的模块,在孙的邀请下梁充当海报设计,随后余和进也加入到小组中,rslly小组正式形成,这就是我们域名rslly的来源。我们的产品虽然不是很新颖,但凭借着实用和高技术含量(高中生而言)我们顺利进入了区的比赛。成功晋级区的比赛后,我感到了自研的必要性,必须设计出一个属于我们自己的物联网平台和电路板。随后的故事大家也知道了我们凭借着自研的平台和微信交互电气的廉价理念我们拿到了省二的奖项,奠定了社区的基础。

高考之后大家相继进入了各大高校,我们原始的小组齐聚在一起的机会变得非常少了。但疫情阶段的新工具腾讯会议成为了我们新的交流方式,我们社区的性质也开始由比赛团队转变为开源社区,致力于构建Aiot的平台和解决方案。社区得到了比较大的发展,大约在我大三上学期阶段社区规模达到最大,社区设计出来的衍生产物和大量文章得到了比较好的应用和传播。这阶段虽然整体比较好,但却也逐渐显现出了内部团队的管理问题,人数的增多以及缺乏有效的组织,目标逐渐迷失,过大的目标和空的梦想逐渐使得人心离散。到了大三下学期的时候就业压力的逐渐增大,社区逐渐进入了休眠时期,物联网的普及化使得社区的技术已经显得不再先进,我们尝试过植物工厂,鱼菜共生等方案,甚至是数字孪生的激进方案,但团队本身的吸引力明显不如从前,也没有真正产生非常有价值的东西,社区事实上走到了迷茫时期。

随着大模型的横空出世,Zeeland等人的积极探索使得社区空前活跃,虽然由于就业影响,人数不如从前,但是Agent框架以及Ic平台等项目的出现,社区从事实上进入了全新的阶段,以开源项目为主导的阶段。Agent+Iot的构想使得通用Aiot平台成为了从梦想到现实的一大步。我们仍旧在迷雾中探索,但在探索中我们又认识了Rymcu的ronger等人,他们的言行给了我们极大的鼓励,也许我们未必能成为一个真正的开源社区,但这些探索亦足以使得我们感受到了作为一个程序员的浪漫,感谢大家的支持和鼓励,欢迎有同样爱好的朋友加入,我们期待你的加入。ruanrongman/IntelliConnect: A Powerful iot platform core.

智能体重塑Aiot新时代

随风

Aiot并不是一个很新的概念,物联网本身连接了大量的物理设备,而连接本身并不能带来真正的价值,真正有价值的是其收集的海量数据以及远程控制能力,因此当物联网与AI结合,AI所带来的巨大数据处理能力和规划能力,能够使得物联网应用的优点得到更大的发挥,因此Aiot成了物联网未来发展的重要赛道。

创万联社区很早就关注Aiot的发展,但是前期的Ai通用性不足,模型能力破碎,必须要将针对不同的场景开发不同的模型和算法,这将导致通用物联网平台与AI的结合变得困难,这将极大的约束Aiot的发展,但是大模型和agent技术极大的解决了这一困境,这是因为agent技术具有一定的自主规划能力和通用性,因此可以给场景各异的iot应用赋予通用的AI能力。

然而当前agent框架仍在发展,比较著名的如国外的langchain,国产的agently和promptulate,这些框架主要是给予互联网从业者和通用能力构建的,并不是针对iot的场景进行开发的,因此需要自行开发相应的tools,tools的开发其实看似简单,但实际上开发合适的tools也是一个颇具挑战的工作。

因此创万联根据实际需求,开发出了一款agent+iot的平台inteliconnect,这款平台能够支持常见的物联网协议,支持使用时序数据库influxdb进行时序数据存储以提升存储效率。还搭载有脚本引擎,支持后续的自主脚本开发。关键的是这款平台可以全面支持agent能力引入,开箱即用,下面是其能力展示,后续我们将在github进行开源,我们还将提供了一个开源社区技术交流群,欢迎你来分享知识,交流技术。

欢迎关注我们的社区公众号

谷歌iot core停止运行,chatGPT大火,我们如何看待

wonder

2023年注定是不平凡的一年,年初我们经历了疫情政策的开放,过了一个史上最长寒假。然而科技却并没有停下它的脚步,反而迎来了人工智能的iphone时刻,chatgpt和gpt4以及国内的文心一言,通义千问,这些AI大模型引爆了人们对于人工智能的关注和对人类社会未来的思考。

作为一个人工智能和物联网社区,我们很早就开始关注gpt的发展,chatgpt没有推出前,我们就观察到了gpt系列产品。但令人遗憾的是我们一直觉得ai语言模型不具备很强的推理能力,主要是依赖于语料库进行回答。虽然我们很早就觉得采用语言模型可能是实现AGI以及物联网平台接口的最佳选择,实际我们也是这么做的。我们开发出了家庭安全卫士,它的主要交互方式就是基于语言交互的。但是我们从来就没有想象过语言模型能发展到如此高度,其中的智能涌现令人细思极恐。

人工智能的大火的时候,物联网却遭到了诸多不利消息。谷歌iot core平台将于今年8月正式停止服务。物联网似乎已经成了时代的弃子。iot服务的领域主要是制造业,农业等一些领域。而现有的物联网平台主要是互联网大厂制作,对于行业的垂直理解不够丰富,使得云平台成了中看不中用的东西。并没有发挥出预想的生产力。因此iot的未来必须是结合人工智能,而不是继续像互联网一样的扩张思维。

然而chatgpt诞生之后,小社区和个人已经宣告无力参与Ai的研发。大模型所需要的资金和计算资源都是难以想象的。而我们能做的只能是参与应用开发。将大模型作为AI时代的操作系统,去发挥它的价值,因此我们无需悲观。有了大模型,物联网会得到更好的发展,我们将真正迎来数据时代。

物联网操作系统的任务调度初步认识

随风

任务调度是操作系统的基本功能。任务调度使得用户程序感觉自己在独占cpu。但是cpu是有限的,任务又那么多,操作系统是如何做到合理分配cpu时间的呢。其实rtos基本上是根据优先级抢占式调度,然后如果任务优先级相同就按照时间轮转片调度。

时间轮转片算法并不难,然而我阅读了大量的时间轮转片介绍的博客始终没有具体的硬件实现介绍。大部分博客都是仿真实现,这其实和真实的内核实现有着很大的差距。因为仿真切换你根本没法实现硬件中断机制,而真实的内核是利用中断机制来实现任务调度的。

为什么内核要使用中断机制而不是直接像普通程序那样编写。这其实非常显然,内核调度肯定占用的资源越低越好,实时性越高越好。而中断机制就能提供这样的属性。中断机制可以说是计算机最具革命性的一个设计,它大大提高了计算机系统的响应速度。

当看到利用中断机制的介绍时候我脑海里已经浮现了一种内核调度的实现方法。利用systick中断,systick中断实现流水灯相信大家都曾经编写过,因此想到利用systick来进行任务切换是一种非常自然的想法,只要设置好中断的时间间隔,那么就实现了时间片的设计。事实上tos系统同样利用了systick中断。下面是tos系统时基的入口。

void SysTick_Handler(void)
{
	if (tos_knl_is_running())
  {
    tos_knl_irq_enter();
    tos_tick_handler();
    tos_knl_irq_leave();
  }
}

但是仅仅利用systick中断肯定是要出问题的。因为单片机还要处理其它中断,在Cortex-M3中,如果OS在某个中断活跃时,抢占了该中断,而且又发生了任务调度,并执行了任务,切换到了线程运行模式,将直接触发Fault异常。这肯定是不行的,但你肯定会说不如直接把systick设置为最低优先级不就行了吗?当然可以,异常确实不会发生了,然而你仔细想想会发生什么?

仔细想好像也没问题啊。的确很难想到,但是我们处理中断的流程是怎么样的?第一步是关中断,然后保存现场再开中断,执行程序,最后再关中断,恢复现场然后开中断。这样做就是为了现场不被破坏同时保证更高优先级的中断能够正常被响应。一般OS在调度任务时,也是要关闭中断,也就是进入临界区,而OS任务调度是要耗时的,这就会出现一种情况:
在任务调度期间,如果新的外部中断发生,CPU将不能够快速响应处理。这对于智能驾驶这样的场景你能忍受吗?

到了这里你似乎走到了穷途末路。的确只利用systick在软件层面已经没有更好的办法了。但是狡猾的内核大佬利用了一个叫做pendsv的中断,这个中断很奇怪,它能够像普通外设中断一样悬起。它是系统级别的异常,但它又天生支持缓期执行。有了它我们就能轻松避免了不能快速处理的问题,pendsv会自动等待所有的中断处理完毕再进行任务切换的操作。

到了这里我们已经得到了一种较为成熟的os调度方案。

  1. 滴答定时器中断,制作业务调度前的判断工作,不做任务切换。
  2. 触发PendSV,PendSV并不会立即执行,因为PendSV的优先级最低,如果此时正好有中断请求,那么先响应中断,最后等到所有优先级高于PendSV的中断都执行完毕,再执行PendSV,进行任务调度。

那么tos系统也是这样实现的吗?我们看看源码。那么我们要启动tos系统,入口肯定要调用启动的api,源代码api头文件注释是get the kernel start to run, which means start the multitask scheduling.中文意思就是启动内核,意味着启动多任务调度。

__API__ k_err_t tos_knl_start(void)
{
    if (tos_knl_is_running()) {
        return K_ERR_KNL_RUNNING;
    }

    k_next_task = readyqueue_highest_ready_task_get();
    k_curr_task = k_next_task;
    k_knl_state = KNL_STATE_RUNNING;
    cpu_sched_start();

    return K_ERR_NONE;
}

可以看到前几行都是检测和获取任务的一些信息,重点在于 cpu_sched_start() ,这个是用来启动cpu任务调度的。刚才那个加了宏_api_表明它还是属于用户api,下面正式进入内核世界。

可奇怪的是它的实现c文件很短,就又调用了一个函数 port_sched_start 。

__KERNEL__ void cpu_sched_start(void)
{
    port_sched_start();
}

继续前进已经没有c文件了,迎面而来的是汇编语言。我熟悉8051汇编,但是对于arm的汇编,我并不是很熟悉,但是又不是考试,还是可以查手册的。粗略看了看,大概知道这是一段很重要的代码。

NVIC_INT_CTRL   EQU     0xE000ED04                              ; Interrupt control state register.
NVIC_SYSPRI14   EQU     0xE000ED20                              ; System priority register (priority 14).
NVIC_PENDSV_PRI EQU     0x00FF0000                              ; PendSV priority value (lowest).
NVIC_PENDSVSET  EQU     0x10000000                              ; Value to trigger PendSV exception.

我们看一下注释,这不就是设置pendsv为设置为最低优先级吗,到这里我们还不清楚它与systick的关系,但至少已经证实它肯定利用了pendsv。幸运的是我滚动一下鼠标就发现的

pendsv的中断处理子程序(汇编我们还是不要叫函数吧)

这段代码很复杂,但是只要有点51单片机的功底,还是猜得出它在干什么,其实就是操作系统最重要的工作,任务堆栈的切换。它借用了寄存器实现的现场的保护。至此我们完全证明tos系统利用pendsv进行上下文切换。

我们还看到这样一段注释

@ set pendsv priority lowest
@ otherwise trigger pendsv in port_irq_context_switch will cause a context swich in irq
@ that would be a disaster

翻译过来跟我们上面描述的完全一致。

我们再去找systick,得到了这个函数

__API__ void tos_tick_handler(void)
{
    if (unlikely(!tos_knl_is_running())) {
        return;
    }

    tick_update((k_tick_t)1u);

#if TOS_CFG_TIMER_EN > 0u && TOS_CFG_TIMER_AS_PROC > 0u
    timer_update();
#endif

#if TOS_CFG_ROUND_ROBIN_EN > 0u
    robin_sched(k_curr_task->prio);
#endif
}

unlikely这是内核的一种优化函数,暂时不用管它,我们全力看 robin_sched ()函数。

__KERNEL__ void robin_sched(k_prio_t prio)
{
    TOS_CPU_CPSR_ALLOC();
    k_task_t *task;

    if (k_robin_state != TOS_ROBIN_STATE_ENABLED) {
        return;
    }

    TOS_CPU_INT_DISABLE();

    task = readyqueue_first_task_get(prio);
    if (!task || knl_is_idle(task)) {
        TOS_CPU_INT_ENABLE();
        return;
    }

    if (readyqueue_is_prio_onlyone(prio)) {
        TOS_CPU_INT_ENABLE();
        return;
    }

    if (knl_is_sched_locked()) {
        TOS_CPU_INT_ENABLE();
        return;
    }

    if (task->timeslice > (k_timeslice_t)0u) {
        --task->timeslice;
    }

    if (task->timeslice > (k_timeslice_t)0u) {
        TOS_CPU_INT_ENABLE();
        return;
    }

    readyqueue_move_head_to_tail(k_curr_task->prio);

    task = readyqueue_first_task_get(prio);
    if (task->timeslice_reload == (k_timeslice_t)0u) {
        task->timeslice = k_robin_default_timeslice;
    } else {
        task->timeslice = task->timeslice_reload;
    }

    TOS_CPU_INT_ENABLE();
    knl_sched();
}

从源码中可以看到,时间片调度算法的实现非常简单,当时钟节拍来临的时候,将就绪列表中第一个任务控制块的时间片值递减,如果递减到0,则移到就绪列表的队尾去,让出此次执行机会,内核发生调度。我们重点看 knl_sched()函数。

__KERNEL__ void knl_sched(void)
{
    TOS_CPU_CPSR_ALLOC();

    if (knl_is_inirq()) {
        return;
    }

    if (knl_is_sched_locked()) {
        return;
    }

    TOS_CPU_INT_DISABLE();
    k_next_task = readyqueue_highest_ready_task_get();
    if (knl_is_self(k_next_task)) {
        TOS_CPU_INT_ENABLE();
        return;
    }

    cpu_context_switch();
    TOS_CPU_INT_ENABLE();
}

这个就是检查一下当前是否有中断发生,还有检查一下锁是否释放,然后调用函数 TOS_CPU_INT_DISABLE()关闭中断,调用 cpu_context_switch() 进行上下文切换。不出意外,终点一定是汇编实现。

果然我们已经离开了c语言世界,进入汇编世界。看代码

port_context_switch
    LDR     R0, =NVIC_INT_CTRL
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR

这是什么?这是什么?触发pendsv异常,到了这里我们已经破解了tos系统的任务调度器的基本原理。这表明tos系统和freertos的实现机制是大差不差的。

内核是非常复杂的东西,我们一定要充满敬畏,不要随意去修改,但是了解内核还是很有必要的,否则应用层的很多东西我们理解可能都是错误的。在此,真的太佩服太佩服内核大佬了,瞬间觉得应用层开发那点困难不算什么了。

最后来个传送门

物联网操作系统的初步探索

随风

近几年物联网飞速发展,市面上也出现了很多物联网操作系统。比较有名的有rt-thread,tencentos-tiny以及鸿蒙等。这些物联网系统各有差异,这符合物联网碎片化的生态现状。下面我将以tencentos-tiny为例子分析一下目前物联网操作系统的一些特点。

打开tencentos-tiny的官网,映入眼帘的是比较熟悉的代码结构。分别是内核,驱动,网络以及一些辅助的工具,这和大多数的嵌入式操作系统是类似的。

我们再来看看下面这张图。

这张图是tos系统官网给出的架构,可以看出它的模块化设计是非常优秀的。内核只包含了最为重要的特性,即任务调度,时间以及内存管理,以及ipc通讯的组件。而物联网的工具箱则被放置于内核之外。我们用vscode阅读一下它的内核源码。

可以看到它的确非常的精简,每个功能的实现代码有些甚至只有几百行。这样精简的实现,使得它可以轻松移植到stm32f1这样的芯片。

但是如果进行全量移植的话,f1这样的芯片内存空间仍然不是很足,但是tos系统可以轻松的裁剪,移植的体验也非常不错,如果你不需要其它的功能的话,你只需要把kernel和arch目录以及tos_config复制到你的工程就行了,当然你还得进行一些微调,比如系统时钟脉冲设置,但我花了一些时间也就顺利移植成功了。

可能到现在你有个疑问,stm32真的有必要使用操作系统吗?的确,裸机编程能满足大多数场景了,但是如果你想实现实时性很强,任务又非常多的话,使用操作系统的确非常便捷。tos系统采用了抢占式的任务调度。高优先级任务就绪的时候会立即打断低优先级的任务。相同优先级的就是使用时间片调度。这样能保证高优先的任务能优先被处理。tos系统还提供了任务之间通讯的机制,互斥锁,消息队列以及事件机制。这使得基于任务编程成为轻松的事情。否则的话你就只能一个循环加中断或者dma等。这样的cpu利用率以及响应速度都并不能让人非常满意。

tos系统如果仅仅有上述任务调度功能,它就不能称为物联网操作系统,而顶多叫做实时操作系统。tos系统提供了非常强大的网络工具,可以兼容esp8266等众多芯片,提供了一个统一的at指令框架以及各种协议栈的支持。都说抽象是软件的灵魂。tos系统实现了at指令的抽象框架到sal层的抽象框架,从而虚拟出socket接口。有人觉得这不是多此一举吗?这当然不是,实际上这个设计和“一切皆文件”是有异曲同工之妙的。不过由于tos系统是腾讯开发的,它当然要给很便捷的api给自家的iot平台,但这些工具的确方便了物联网的开发。下面引用一下腾讯知乎的一张图,它清晰地阐述了sal接口的好处。

不过说了这么多,sal接口对我的吸引力并没有那么大,实际上我们使用的通讯芯片一般都是确定的一种,并不太可能替换另外一种,但是移植这抽象层占用的flash空间又是真实存在的,因此我倒不如直接at指令来的方便。

物联网操作系统的产生屏蔽了纷繁复杂的物联网硬件,提供了一些较为统一的接口,据说鸿蒙还提供了分布式软总线,但我还没有看过。但是我感觉只靠这样的一个操作系统就能一统江湖,估计还是任重道远。不过我发现了一个有趣的现象,人们正打算在物联网操作系统中提供js引擎。我觉得这个技术未来确实有比较好的前途。我们下次再讨论一下js引擎对于物联网的影响。

最后来个传送门,祝大家元旦快乐。