当前位置: 首页 > 文档资料 > YoC 编程基础 >

操作系统接口

优质
小牛编辑
120浏览
2023-12-01

概述

YoC 支持多种 RTOS 内核,已集成原生的 Rhino 内核,同时也支持 FreeRTOS 等多种开源RTOS内核。采用统一的 AOS 操作系统API 实现操作系统接口的定义,用户可以根据项目要求,选择不同的 RTOS 内核,YoC 默认并推荐使用原生的 Rhino 内核,目前 已支持平头哥全系统 CPU 架构。Rhino 内核具备更快的中断处理响应,更快的优先级抢占调度,它具有体积小、功耗低、实时性强和调试方便等特点。供了丰富多元的内核原语,包括缓冲队列,环形缓冲区、定时器、信号量、互斥量、先入先出队列、事件等。在最小的配置下(只运行一个 IDLE 任务),仅需要1.9KB 的 ROM,1KB 的 RAM 空间。

YoC 中定义了 RTOS 的基本操作,包括:任务管理、内存管理、信号量、消息队列、软件定时器等,即可以满足小系统的需要,也具备良好的可扩展性。

  • 体积小

    为大多数内核对象提供静态和动态分配。为小内存块设计的内存分配器既支持固定块又支持可变块,它还可以支持多个内存区域。大部分的内核特性,如work queue,和内存分配器,都可以通过修改k_config.h文件进行配置和裁剪。

  • 功耗低

    提供了CPU的tickless idle 模式来帮助系统节约电能和延长使用时间。

    通常情况下,当CPU没有执行操作时,它将执行一个处理器指令(对于ARM来说的WFI,对于IA32位处理器来说的HLT),进入低功耗状态。此时,CPU寄存器的信息被保存,系统的 tick clock interrupts 会在每个tick时刻唤醒CPU。

    为了比正常模式节省更多的电量,Rhino 为 CPU 提供了 tickless idle 模式。当操作系统检测到有一个固定时间(多个ticks或更长时间)的空闲后,它将进入tickless idle模式。系统做好中断配置,并把CPU置于C1模式,那时system tick clock中断不再被触发,system tick的计数也将停止。CPU会保持低耗电状态直到tickless idle时间结束。然后,当system tick timer interrupt再次被触发时,唤醒CPU从C1模式回到C0模式,为ticks计算好补偿时间并继续计数。

  • 实时性

    Rhino 提供了两个调度策略,基于优先级的抢占式调度和round-robin循环调度策略。对于两个调度策略而言,具有最高优先级的任务都是被优先处理的。

    基于优先级的抢占式调度器会在遇到比当前运行的任务具有更高优先级任务时抢占CPU。这意味着,如果出现一个任务比当前任务具有更高优先级,内核将立即保存当前任务的context,并切换到高优先级的任务的context。因此,内核保证CPU总是优先处理优先级最高的任务。

    round-robin调度器通过时间片来为各任务分配CPU资源。在一组具有相同优先级的任务中,每个任务都会被安排运行一个固定的时间长度,或者说时间片,之后CPU将处理下一个任务。所以,在一个任务阻塞之前,其他任务不能抢夺到处理器资源。当时间片失效时,系统将运行该优先级就绪队列中的最后一个任务。

  • 方便调试

    Rhino 支持stack溢出、内存泄漏、内存损坏的检测,有助于开发人员找出棘手问题的根源。结合 CDK 的集成开发环境(IDE),Rhino 的追踪功能将实现整个系统运行活动的可视化。

任务

在 RTOS 中,任务(Task)是程序独立运行的最小单位,由操作系统的任务调度系统实现任务的并发执行。每个任务都有独立的栈空间与任务控制块 (TCB)。RTOS 采用优先级抢占调度策略,每个任务都要备注以下基础信息:

  • 任务栈:可采用动态分配与静态分配的方式,确保栈的大小能满足任务运行时不会造成栈溢出
  • 任务主函数:是任务运行的主体程序,该函数的退出,表示任务的结束
  • 任务优先级:高优先级的任务会抢占运行,合理的多任务同步设计可避免低优先级任务得不到运行机会
  • 任务状态:是任务调度器调度决策的基础,合理的任务状态是多任务程序设计的基础

任务的基本操作:

  • 创建:aos_task_new; aos_task_new_ext
  • 让出处理器资源:void aos_task_yield();
  • 获取当前任务:aos_task_t aos_task_self();
  • 任务退出:void aos_task_exit(int *code*);

更多操作见 : 任务

内存管理

RTOS 提供多种内存管理方案,满足不同应用的需要。动态内存管理是最常见的一种方式。常见的操作有:

分配内存:void *aos_malloc(unsigned int size); void *aos_calloc(unsigned int size, int num); 重新分配内存: void *aos_realloc(void *mem, unsigned int size); 内存释放:void aos_free(void *mem);

更多操作见 : 内存管理

互斥锁

在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。互斥锁的基本四个操作:

  • 创建 Create int aos_mutex_new(aos_mutex_t *mutex);
  • 加锁 Lock int aos_mutex_lock(aos_mutex_t *mutex, unsigned int timeout);
  • 解锁 Unlock int aos_mutex_unlock(aos_mutex_t *mutex);
  • 销毁 Destroy void aos_mutex_free(aos_mutex_t *mutex);

更多操作见 : 互斥锁

信号量

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。信号量的基本四个操作:

  • 创建 Create int aos_sem_new(aos_sem_t *sem, int count);
  • 等待信号 Wait int aos_sem_wait(aos_sem_t *sem, unsigned int timeout);
  • 释放信号 Signal void aos_sem_signal(aos_sem_t *sem);
  • 销毁 Destroy void aos_sem_free(aos_sem_t *sem);

更多操作见 : 信号量

消息队列

消息队列提供了一种从一个任务向另一个任务发送数据的方法。 每个数据都被认为含有一个类型,接收的任务可以独立地接收含有不同类型的数据结构。消息队列的特点:

  1. 消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识
  2. 消息队列允许一个或多个任务向它写入与读取消息
  3. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势

消息队列的基本操作:

  • 创建 Create:int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg);
  • 发送消息 Send: int aos_queue_send(aos_queue_t *queue, void *msg, unsigned int size);
  • 接收消息 Recv: int aos_queue_recv(aos_queue_t *queue, unsigned int ms, void *msg, unsigned int *size);
  • 销毁 Destroy: void aos_queue_free(aos_queue_t *queue);

更多操作见 : 消息队列

事件标志组

事件标志组是一种实现任务间通信的机制,可用于实现任务间的同步。事件标志组采用位来表示一个事件,通常采用支持32位的变量,其中每一位表示一种事件类型(0表示该事件类型未发生、1表示该事件类型已经发生)。事件标志组具备以下特点:

  • 可以是任意一个事件发生时唤醒任务进行事件处理,也可以是几个事件都发生后才唤醒任务进行事件处理
  • 多次向任务发送同一事件类型,等效于只发送一次
  • 允许多个任务对同一事件进行读写操作
  • 事件仅用于任务间的同步,不提供数据传输功能

事件标志组支持的基本操作:

创建 Create:int aos_event_new(aos_event_t *event, unsigned int flags);

事件设置 Set: int aos_event_set(aos_event_t *event, unsigned int flags, unsigned char *opt*);

事件获取 Get: int aos_event_get(aos_event_t *event, unsigned int flags, unsigned char opt,unsigned int *actl_flags, unsigned int timeout);

销毁 Destroy: void aos_event_free(aos_event_t *event);

更多操作见 : 事件标志组

定时器

定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受数目限制的定时器服务。

定时器支持的基本操作:

创建 Create:int aos_timer_new(aos_timer_t *timer, void (*fn)(void *, void *), void *arg, int ms, int repeat);

启动 Start:int aos_timer_start(aos_timer_t *timer);

停止 Stop:int aos_timer_stop(aos_timer_t *timer);

销毁 Destory:void aos_timer_free(aos_timer_t *timer);

改变 Change:int aos_timer_change(aos_timer_t *timer, int ms);

更多操作见 : 定时器