resolve conflict of hero.png
This commit is contained in:
commit
2b1ec354af
|
@ -59,9 +59,21 @@ module.exports = {
|
|||
text: '传感器',
|
||||
link: '/doc/sensor/',
|
||||
},
|
||||
{
|
||||
text: '控制器',
|
||||
link: '/doc/controller/',
|
||||
},
|
||||
{
|
||||
text: '开发板',
|
||||
link: '/doc/board/',
|
||||
},
|
||||
{
|
||||
text: '应用开发',
|
||||
link: '/doc/appdev/',
|
||||
},
|
||||
{
|
||||
text: '应用框架',
|
||||
link: '/doc/apparch/'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -117,9 +129,21 @@ module.exports = {
|
|||
title: '传感器',
|
||||
children: getSidebarByCategory('sensor','en')
|
||||
},
|
||||
{
|
||||
title: '控制器',
|
||||
children: getSidebarByCategory('controller','en')
|
||||
},
|
||||
{
|
||||
title: '开发板',
|
||||
children: getSidebarByCategory('board','en')
|
||||
},
|
||||
{
|
||||
title: '应用开发',
|
||||
children: getSidebarByCategory('appdev','en')
|
||||
},
|
||||
{
|
||||
title: '应用架构',
|
||||
children: getSidebarByCategory('apparch','en')
|
||||
}
|
||||
],
|
||||
}
|
||||
|
|
|
@ -3,18 +3,23 @@ const sidebar = {
|
|||
'/doc/intro',
|
||||
],
|
||||
'kernel': [
|
||||
'/doc/kernel/mm',
|
||||
'/doc/kernel/task',
|
||||
'/doc/kernel/mm',
|
||||
'/doc/kernel/synchron',
|
||||
'/doc/kernel/threadcommunication'
|
||||
],
|
||||
'processor': [
|
||||
'/doc/processor/aiit-arm32',
|
||||
'/doc/processor/stm32f407-st-discovery',
|
||||
'/doc/processor/stm32f407zgt6',
|
||||
'/doc/processor/hifive1-rev',
|
||||
'/doc/processor/maxgo',
|
||||
'/doc/processor/kd233'
|
||||
'board': [
|
||||
'/doc/board/aiit-arm32',
|
||||
'/doc/board/stm32f407-st-discovery',
|
||||
'/doc/board/stm32f407zgt6',
|
||||
'/doc/board/hifive1-rev',
|
||||
'/doc/board/maxgo',
|
||||
'/doc/board/kd233'
|
||||
],
|
||||
'controller': [
|
||||
'/doc/controller/ximenzi',
|
||||
'/doc/controller/shinaide',
|
||||
'/doc/controller/sanling'
|
||||
],
|
||||
'communication': [
|
||||
'/doc/communication/4G',
|
||||
|
@ -43,6 +48,17 @@ const sidebar = {
|
|||
'/doc/appdev/env',
|
||||
'/doc/appdev/debug',
|
||||
'/doc/appdev/dev'
|
||||
],
|
||||
'apparch': [
|
||||
'/doc/apparch/gan',
|
||||
'/doc/apparch/lian',
|
||||
'/doc/apparch/zhi',
|
||||
'/doc/apparch/kong'
|
||||
],
|
||||
'processor': [
|
||||
'/doc/processor/riscv',
|
||||
'/doc/processor/riscv_sk',
|
||||
'/doc/processor/riscv_fpga'
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# 应用开发
|
||||
|
||||
---
|
||||
|
||||
* [感](/doc/apparch/gan.md)
|
||||
|
||||
* [联](/doc/apparch/lian.md)
|
||||
|
||||
* [智](/doc/apparch/zhi.md)
|
||||
|
||||
* [控](/doc/apparch/kong.md)
|
|
@ -0,0 +1,194 @@
|
|||
# 感-传感器框架
|
||||
|
||||
多数嵌入式操作系统对传感器的抽象采用以物理传感器设备为中心的方式,在应用开发时无法绕过传感器设备的多样性,进而增加了传感器应用的开发难度和周期。这种抽象带来的缺陷在面对一些可以同时采集多种物理量的传感器(如温湿度传感器)时尤为突出,因为应用开发者不得不考虑每种传感器设备的采集数据的能力。
|
||||
|
||||
XiUOS的传感器框架以用户为中心,采用了以物理量为中心的抽象方式,在开发应用时只需要考虑所需感知的物理量种类,无需把重点放在实际采集物理量的传感器设备。这种抽象方式有效地隐藏了底层传感器设备的硬件细节,对外提供统一的数据采集接口,可以简化传感器应用与驱动的开发。为实现以物理量为中心的抽象,传感器框架对传感器设备进行两层抽象:
|
||||
* 一个物理传感器测量一种物理量的能力(ability)被抽象为一个xs_SensorQuantity结构
|
||||
* 一个物理传感器本身被抽象为一个xs_SensorDevice结构
|
||||
|
||||
其中xs_SensorQuantity被设计为可以采用类似面向对象的方法、针对不同物理量扩展其数据成员与接口,从而为众多不同性质的物理量实现统一的管理架构。在应用开发的过程中只需要使用对应物理量的xs_SensorQuantity实例,无需关心传感器的硬件细节,从而实现数据采样功能与底层硬件的解耦。
|
||||
|
||||
从关联关系上来看,一个xs_SensorQuantity对应一个xs_SensorDevice,一个xs_SensorDevice对应一个或多个xs_SensorQuantity。例如,对于一个可以测量温度与湿度的传感器设备,该设备唯一对应一个xs_SensorDevice结构,而该设备测量温度与湿度的能力分别对应一个xs_SensorQuantity结构。两种数据结构的具体定义如下。
|
||||
|
||||
## struct xs_SensorQuantity结构
|
||||
```c
|
||||
struct xs_SensorQuantity {
|
||||
const char name[XS_NAME_MAX]; /* name of the sensor quantity instance */
|
||||
enum xs_SensorQuantityType type; /* type of data the sensor collects, such as CO2 concentration */
|
||||
struct xs_SensorDevice *sdev; /* corresponding sensor device */
|
||||
struct XS_DOUBLE_LINKLIST_NODE link; /* link list node */
|
||||
};
|
||||
```
|
||||
name成员是一个可读的名字,用于唯一标识一个xs_SensorQuantity结构。
|
||||
|
||||
type成员表示该xs_SensorQuantity可测量的物理量,用一个枚举变量表示:
|
||||
```c
|
||||
enum xs_SensorQuantityType {
|
||||
XS_SENSOR_QUANTITY_CO2 = 0, /* CO2 concentration */
|
||||
XS_SENSOR_QUANTITY_TEMP, /* temperature */
|
||||
XS_SENSOR_QUANTITY_HUMI, /* humidity */
|
||||
/* ...... */
|
||||
XS_SENSOR_QUANTITY_END,
|
||||
};
|
||||
```
|
||||
|
||||
sdev成员表示该xs_SensorQuantity所属的xs_SensorDevice结构,其具体定义在下文给出。
|
||||
|
||||
最后,在系统中每种物理量的xs_SensorQuantity被分别组织成不同双链表,如二氧化碳浓度xs_SensorQuantity链表、温度xs_SensorQuantity链表等,使用的链表节点即为link成员。
|
||||
|
||||
## struct xs_SensorDevice结构
|
||||
```c
|
||||
struct xs_SensorDevice {
|
||||
const char name[XS_NAME_MAX]; /* name of the sensor device */
|
||||
struct xs_SensorProductInfo info; /* sensor model info, such as vendor name and model name */
|
||||
struct xs_SensorOps ops; /* filesystem-like APIs for data transferring */
|
||||
struct xs_SensorInterface interface; /* physical interface for transferring data */
|
||||
struct XS_DOUBLE_LINKLIST_NODE link; /* link list node */
|
||||
};
|
||||
```
|
||||
name成员记录传感器设备在系统中的名字,用于唯一标识一个xs_SensorDevice结构
|
||||
|
||||
info成员记录传感器设备的一些属性信息,包括传感器的能力ability、厂家名vendor与型号product_model,其中ability用一个位图表示该传感器设备可以测量的物理量:
|
||||
```c
|
||||
#define XS_SENSOR_ABILITY_CO2 ((uint32_t)(1 << XS_SENSOR_QUANTITY_CO2))
|
||||
#define XS_SENSOR_ABILITY_TEMP ((uint32_t)(1 << XS_SENSOR_QUANTITY_TEMP))
|
||||
#define XS_SENSOR_ABILITY_HUMI ((uint32_t)(1 << XS_SENSOR_QUANTITY_HUMI))
|
||||
/* ...... */
|
||||
|
||||
struct xs_SensorProductInfo {
|
||||
uint32_t ability; /* bitwise OR of XS_SENSOR_ABILITY_XXX */
|
||||
const char *vendor;
|
||||
const char *product_model;
|
||||
};
|
||||
```
|
||||
|
||||
ops成员包含统一的、类似文件系统的API,用于对传感器进行实际的数据读写。在使用一个传感器前后需要打开(open)/关闭(close)该传感器,read、write分别用与从传感器接收数据与向传感器发送数据,ioctl用于配置传感器属性(如波特率):
|
||||
```c
|
||||
struct xs_SensorOps {
|
||||
int (*open)(struct xs_SensorDevice *sdev);
|
||||
void (*close)(struct xs_SensorDevice *sdev);
|
||||
int (*read)(struct xs_SensorDevice *sdev, void *buf, size_t len);
|
||||
int (*write)(struct xs_SensorDevice *sdev, const void *buf, size_t len);
|
||||
int (*ioctl)(struct xs_SensorDevice *sdev, int cmd, void *arg);
|
||||
};
|
||||
```
|
||||
|
||||
interface成员表示用于与传感器进行通信的总线设备:
|
||||
```c
|
||||
struct xs_SensorInterface {
|
||||
xs_device_t bus_device;
|
||||
};
|
||||
```
|
||||
|
||||
最后,系统中所有注册过的传感器设备被组织成一个双链表,即link成员。
|
||||
|
||||
## 传感器框架驱动开发
|
||||
|
||||
以二氧化碳传感器为例。传感器框架针对每个具体的物理量将xs_SensorQuantity进行扩充,采用类似面向对象的手段添加其他必要成员,如:
|
||||
```c
|
||||
struct xs_SensorQuantityCo2 {
|
||||
struct xs_SensorQuantity parent; /* inherit from xs_SensorQuantity */
|
||||
|
||||
uint32_t (*read_concentration)(struct xs_SensorQuantityCo2 *quant);
|
||||
|
||||
uint32_t value_last; /* last measured value */
|
||||
uint32_t value_min; /* minimum measured value */
|
||||
uint32_t value_max; /* maximum measured value */
|
||||
uint32_t std_min; /* national standard: minimum */
|
||||
uint32_t std_max; /* national standard: maximum */
|
||||
};
|
||||
```
|
||||
|
||||
实现xs_SensorOps中的数据通信API,具体实现细节取决于传感器型号,无法实现的API可以置为NULL:
|
||||
```c
|
||||
struct xs_SensorOps co2_example_ops = {
|
||||
.open = co2_example_open;
|
||||
.close = co2_example_close;
|
||||
.read = co2_example_read;
|
||||
.write = NULL;
|
||||
.ioctl = co2_example_ioctl;
|
||||
};
|
||||
```
|
||||
|
||||
实现xs_SensorQuantityCo2中的read_concentration接口,该接口用于读取当前空气中的二氧化碳浓度。在实现过程中可以使用xs_SensorOps中的接口与传感器进行通信。
|
||||
|
||||
最后,将传感器设备添加到传感器框架。分别填充xs_SensorDevice与对应物理量的xs_SensorQuantity结构(二氧化碳即为xs_SensorQuantityCo2),并依次使用xs_SensorDeviceRegister和xs_SensorQuantityRegister函数将其注册到传感器框架:
|
||||
```c
|
||||
int xs_SensorDeviceRegister(struct xs_SensorDevice *sdev);
|
||||
int xs_SensorQuantityRegister(struct xs_SensorQuantity *quant);
|
||||
|
||||
extern struct xs_SensorOps co2_example_ops;
|
||||
extern uint32_t co2_example_read_concentration(struct xs_SensorQuantityCo2 *quant);
|
||||
|
||||
/* declare xs_SensorDevice and xs_SensorQuantityCo2 objects */
|
||||
struct xs_SensorDevice co2_example_sdev;
|
||||
struct xs_SensorQuantityCo2 co2_example_quant;
|
||||
|
||||
void register_co2_sensor()
|
||||
{
|
||||
/* initialize and register the xs_SensorDevice object */
|
||||
memset(&co2_example_sdev, 0, sizeof(xs_SensorDevice));
|
||||
|
||||
co2_example_sdev.name = "sensor1";
|
||||
co2_example_sdev.info.ability |= XS_SENSOR_ABILITY_CO2;
|
||||
co2_example_sdev.info.vendor = "xxx";
|
||||
co2_example_sdev.info.product_model = "yyy";
|
||||
co2_example_sdev.ops = &co2_example_ops;
|
||||
co2_example_sdev.interface.bus_device = xs_DeviceFind("uart1");
|
||||
|
||||
xs_SensorDeviceRegister(&co2_example_sdev);
|
||||
|
||||
|
||||
/* initialize and register the xs_SensorQuantity object */
|
||||
memset(&co2_example_quant, 0, sizeof(xs_SensorQuantityCo2));
|
||||
|
||||
co2_example_quant.parent.name = "co2_1";
|
||||
co2_example_quant.parent.type = XS_XS_SENSOR_QUANTITY_CO2;
|
||||
co2_example_quant.parent.sdev = &co2_example_sdev;
|
||||
co2_example_quant.read_concentration = co2_example_read_concentration;
|
||||
|
||||
xs_SensorQuantityRegister((struct xs_SensorQuantity *)&co2_example_quant);
|
||||
}
|
||||
```
|
||||
|
||||
## 传感器框架的使用
|
||||
|
||||
传感器应用开发者使用传感器框架提供的API操作传感器,传感器API可以分为通用API与物理量特有API。通用API用于传感器的获取、打开与关闭,物理量特有API用于传感器的数据采样。以二氧化碳传感器为例:
|
||||
```c
|
||||
/* generic API: find a sensor quantity instance by its name */
|
||||
struct xs_SensorQuantity *xs_SensorQuantityFind(const char *name);
|
||||
|
||||
/* generic API: open/close a sensor quantity instance */
|
||||
int xs_SensorQuantityOpen(struct xs_SensorQuantity *quant);
|
||||
void xs_SensorQuantityClose(struct xs_SensorQuantity *quant);
|
||||
|
||||
/* CO2 API: get current CO2 concentration reading (in ppm unit) */
|
||||
uint32_t xs_SensorCo2Read(struct xs_SensorQuantityCo2 *quant);
|
||||
```
|
||||
|
||||
在获取数据前,需要先获取并打开要使用的传感器;传感器打开后可以随时对传感器数据进行读取;使用完毕后,须关闭传感器。完整的使用过程示例如下:
|
||||
```c
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
struct xs_SensorQuantity *quant;
|
||||
struct xs_SensorQuantityCo2 *co2_quant;
|
||||
|
||||
/* get the CO2 sensor quantity instance */
|
||||
quant = xs_SensorQuantityFind("co2_1");
|
||||
XS_ASSERT(quant->type == XS_SENSOR_QUANTITY_CO2);
|
||||
|
||||
/* open the CO2 sensor quantity instance */
|
||||
co2_quant = (struct xs_SensorQuantityCo2 *)quant;
|
||||
ret = xs_SensorQuantityOpen(quant);
|
||||
XS_ASSERT(ret == XS_EOK);
|
||||
|
||||
/* read CO2 concentration for 5 times, just for demonstration */
|
||||
for (int i = 0; i < 5; i++)
|
||||
xs_kprintf("Current CO2 concentration is %u ppm\n", xs_SensorCo2Read(co2_quant));
|
||||
|
||||
xs_SensorQuantityClose(quant);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
|
@ -0,0 +1 @@
|
|||
# 控
|
|
@ -0,0 +1 @@
|
|||
# 联
|
|
@ -0,0 +1 @@
|
|||
# 智
|
|
@ -0,0 +1,19 @@
|
|||
# 硬件支持
|
||||
|
||||
---
|
||||
|
||||
## ARM
|
||||
|
||||
* [aiit-arm32](/doc/board/aiit-arm32.md)
|
||||
|
||||
* [stm32f407-st-discovery](/doc/board/stm32f407-st-discovery.md)
|
||||
|
||||
* [stm32f407zgt6](/doc/board/stm32f407zgt6.md)
|
||||
|
||||
## RISC-V
|
||||
|
||||
* [hifive1-re](/doc/board/hifive1-rev.md)
|
||||
|
||||
* [maxgo](/doc/board/maxg.md)
|
||||
|
||||
* [kd233](/doc/board/kd233.md)
|
|
@ -0,0 +1,10 @@
|
|||
# 控制器
|
||||
|
||||
---
|
||||
|
||||
- [西门子](/doc/controller/ximenzi.md)
|
||||
|
||||
- [线程管理](/doc/controller/shinaide.md)
|
||||
|
||||
- [资源管理](/doc/controller/sanling.md)
|
||||
|
|
@ -0,0 +1 @@
|
|||
# 三菱
|
|
@ -0,0 +1 @@
|
|||
# 施耐德
|
|
@ -0,0 +1 @@
|
|||
# 西门子
|
|
@ -30,12 +30,22 @@ XiUOS是一种工业物联网操作系统, 目标是通过工业物联网的部
|
|||
|
||||
答案是因为定位不同, 所以特色不同。XiUOS和现有大多数的物联网OS关注点并不相同。
|
||||
|
||||
- 现有OS多关注单个物联网节点设备, XiUOS更关注由多节点设备组成的网络化集群;
|
||||
- 现有OS多关注OS的基础功能, 如基本网络连接, 传感器接入等; XiUOS更关注基础功能之上的高级业务功能, 如将智能化下沉到节点端的智能化感知功能, 智能无线自助网络功能等;
|
||||
- 现有OS力图做多领域通用OS, XiUOS更关注工业物联领域, 对复杂工业环境的"感联知控"支持更为专精;
|
||||
- 现有OS对大规模部署和管理运维的支持有限, XiUOS强调对大规模部署和管理运维的支持;
|
||||
- 现有OS多关注单个物联网节点设备, XiUOS更关注由多节点设备组成的网络化集群;
|
||||
- 现有OS多关注OS的基础功能, 如基本网络连接, 传感器接入等; XiUOS更关注基础功能之上的高级业务功能, 如将智能化下沉到节点端的智能化感知功能, 智能无线自助网络功能等;
|
||||
- 现有OS力图做多领域通用OS, XiUOS更关注工业物联领域, 对复杂工业环境的"感联知控"支持更为专精;
|
||||
- 现有OS对大规模部署和管理运维的支持有限, XiUOS强调对大规模部署和管理运维的支持;
|
||||
- 现有OS的生态是封闭、碎片化和彼此割裂的, XiUOS更关注开放的生态, 强调对标准规范的支持, 依托现有的各开源生态体系, 而非再建另一个封闭的生态体系。
|
||||
|
||||
目前市场上的物联网的硬件呈现严重的碎片化状态,提高了应用的复杂度和技术壁垒。现有的物联网硬件生态特征在于:(1) ARM在物联网领域占市场统治地位,但随着其被英伟达收购程序的推进,存在的知识产权问题和价格垄断问题越来越突出。此外,ARM指令集还存在单一固定、不可定制等问题;(2) 工业物联网对“联”的需求呈现多样化、层次化、立体化的特点,工业生产的物理环境也是极其复杂多变,但现有的硬件系统在物理介质上仅仅支持一到两种“联”;(3) 工业物联网应用本身对外设种类的要求也是丰富多变,但现有的硬件系统挂载多种外设的能力有限;(4) 现有的物联网操作系统支持的硬件系统多以开发板评估板的形态出现,这种硬件系统由于承载强度、温湿度限制,外壳保护等原因很难直接应用于实际工业生产环境,仅适用于实验室评估的验证系统。
|
||||
|
||||
XiUOS是软硬件协同的物联网解决方案,其自研硬件系统的优势在于:
|
||||
- XiUOS的硬件系统支持RISC-V和ARM两种体系结构,强调RISC-V和ARM在工业应用中的共生共赢,又注重突出各自特点;
|
||||
- XiUOS的硬件系统在同一物理实体终端上同时支持 4G、NB-IoT、WiFi、ZigBee、LoRA、BlueTooth、Ethernet,在硬件上天然地使得现有应用能够方便、快捷地“联”结各种网络;
|
||||
- XiUOS的硬件系统在同一物理实体终端上同时支持 SPI、IIC、UART、CAN、RS485、RS232、USB、SDIO等总线接口,在硬件上天然地满足工业物联网对外设多样性的需求;
|
||||
- XiUOS的硬件系统能够直接部署于工业生产环境中,而非验证性的开发板评估板。
|
||||
|
||||
XiUOS硬件系统中的处理器、通信器、传感器、控制器采用解耦的模块化设计,利于XiUOS操作系统方便地通过软件定义的方式屏蔽各种硬件外设的差异,使得工业物联网用户不必关心底层硬件的实施细节,从而更加专注于应用逻辑本身的效能。
|
||||
|
||||
简而言之, 现有物联网OS主要关注的是做优秀的单节点OS, XiUOS是在现有单节点OS的基础上构建面向多节点的网络化智能物联软件栈, 为工业物联网领域应用开发、系统部署、管理运维提供友好方案, 因此现有物联网OS和XiUOS一个在下层一个在上层, 功能是互补的而非竞争的, 如Linux之于Android。
|
||||
|
||||
|
||||
|
|
|
@ -1,134 +1,5 @@
|
|||
# 线程间通信
|
||||
XiUOS 的线程间通信使用邮箱、消息队列和信号三种方式。下面将分别介绍。
|
||||
|
||||
## 邮箱
|
||||
### 邮箱的工作机制
|
||||
XiUOS 的每一封邮件大小为4字节,也就是一个指针的大小。典型的邮箱应用是,线程或中断服务发送一封4字节长度的邮件到邮箱中,其他的线程可以从邮箱中接收邮件并进行处理。</br></br>
|
||||
当一个线程向邮箱发送邮件时,如果邮箱没满,就将邮件复制到邮箱中。如果邮箱满了并且超时时间设置为0,则返回`-XS_EFULL`;如果超时时间不为0,先将该发送线程挂起,当邮箱中的邮件被取出空出空间后,等待挂起的发送线程被唤醒继续发送。但是如果到达超时时间仍没有空间,则返回`-XS_EFULL`。</br></br>
|
||||
当一个线程从邮箱中接收邮件时,如果邮箱中有邮件,就读出该邮件的内容,并返回XS_EOK。如果邮箱中没有邮件并且超时设置为0,则返回`-XS_ETIMEOUT`;如果超时时间不为0,则将该线程挂在邮箱的等待线程中,有邮件时唤醒。但是如果到达超时时间仍没有邮件,返回`-XS_ETIMEOUT`。
|
||||
### 结构体定义和函数接口
|
||||
|
||||
#### 邮箱控制块
|
||||
```C
|
||||
struct xs_Mailbox
|
||||
{
|
||||
char name[XS_NAME_MAX];
|
||||
xs_uint8 style;
|
||||
|
||||
xs_uint8 sign;
|
||||
|
||||
xs_list_t link;
|
||||
|
||||
xs_list_t pend_list;
|
||||
|
||||
xs_ubase *msg_buf;
|
||||
xs_uint16 size;
|
||||
xs_uint16 index;
|
||||
xs_uint16 in_offset;
|
||||
xs_uint16 out_offset;
|
||||
|
||||
xs_list_t pend_sender_list;
|
||||
};
|
||||
|
||||
typedef struct xs_Mailbox *xs_mailbox_t;
|
||||
```
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| name | 邮箱名称 |
|
||||
| style | 线程等待的方式,可以取FIFO或PRIO |
|
||||
| sign | 标记邮箱的创建方式,静态创建或动态创建 |
|
||||
| link | 邮箱存放的列表 |
|
||||
| pend_list | 线程等待队列 |
|
||||
| msg_buf | 邮箱缓冲区开始地址 |
|
||||
| size | 邮箱最大容纳的邮件数 |
|
||||
| index | 邮箱中邮件的索引 |
|
||||
| in_offset | 邮箱缓冲的进指针 |
|
||||
| out_offset | 邮箱缓冲的出指针 |
|
||||
| pend_sender_list | 发送线程的挂起等待队列 |
|
||||
|
||||
#### 函数接口
|
||||
|
||||
```C
|
||||
xs_err_t xs_InitMailbox(xs_mailbox_t mb,
|
||||
const char* name,
|
||||
void* msgpool,
|
||||
xs_size_t size,
|
||||
xs_uint8 flag);
|
||||
```
|
||||
该函数用于创建一个静态邮箱对象,并将它加入邮箱管理列表中,创建成功返回`XS_OK`。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
| name | 邮箱名称 |
|
||||
| msgpool | 缓冲区指针 |
|
||||
| size | 邮箱容量 |
|
||||
| flag | 线程等待的方式,可以取FIFO或PRIO |
|
||||
</br>
|
||||
|
||||
```C
|
||||
xs_err_t xs_DetachMailbox(xs_mailbox_t mb);
|
||||
```
|
||||
该函数用于脱离静态初始化的邮箱对象。该函数唤醒所有挂在该邮箱上的线程,然后将该邮箱从邮箱存放的列表中脱离,返回`XS_OK`。
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
|
||||
```C
|
||||
xs_mailbox_t xs_CreateMailbox(const char *name, xs_size_t size, xs_uint8 flag);
|
||||
```
|
||||
该函数用于创建一个动态邮箱对象,并将它加入邮箱管理列表中。创建成功则返回`XS_OK`,创建失败返回`XS_NULL`。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| name | 邮箱名称 |
|
||||
| size | 邮箱容量 |
|
||||
| flag | 线程等待的方式,可以取FIFO或PRIO |
|
||||
</br>
|
||||
|
||||
```C
|
||||
xs_err_t xs_DeleteMailbox(xs_mailbox_t mb);
|
||||
```
|
||||
该函数用于删除动态邮箱对象。先唤醒挂在邮箱对象上的所有线程,然后释放该邮箱的使用内存,最后删除邮箱对象。返回`XS_OK`。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
xs_err_t xs_MailboxSendWait(xs_mailbox_t mb, xs_ubase value, xs_int32 timeout);
|
||||
```
|
||||
该函数用于发送邮件。如果邮箱满了并且过了timeout时间仍然没有空位,则返回`-XS_FULL`;否则将邮件存放入邮箱。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
| value | 邮件内容 |
|
||||
| timeout | 超时时间 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
xs_err_t xs_MailboxSend(xs_mailbox_t mb, xs_ubase value);
|
||||
```
|
||||
该函数用于发送邮件。与`xs_MailboxSendWait`唯一不同的地方是,该函数的`timeout == 0`。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
| value | 邮件内容 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
xs_err_t xs_MailboxRecv(xs_mailbox_t mb, xs_ubase *value, xs_int32 timeout);
|
||||
```
|
||||
该函数用于接受邮件。
|
||||
|
||||
```C
|
||||
xs_err_t xs_CmdControlMailbox(xs_mailbox_t mb, int cmd, void *arg);
|
||||
```
|
||||
该函数用于获取或设置邮箱的其他属性。目前当`cmd == XS_LINKLIST_CMD_RESET`时,重新初始化邮箱。</br>
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| mb | 邮箱对象 |
|
||||
| cmd | 需要执行的命令 |
|
||||
| arg | 命令的参数 |
|
||||
</br>
|
||||
XiUOS 的线程间通信使用管道和消息队列进行通信。下面将分别介绍。
|
||||
|
||||
## 消息队列
|
||||
### 消息队列的工作机制
|
||||
|
@ -305,74 +176,4 @@ xs_err_t xs_CmdControlMessageQueue(xs_messagequeue_t mq, int cmd, void *arg)
|
|||
| arg | 命令的参数 |
|
||||
</br>
|
||||
|
||||
|
||||
## 信号
|
||||
### 信号的工作机制
|
||||
信号是在软件层次对中断机制的一种模拟。XiUOS中提供了信号用作异步通信的方式。</br></br>
|
||||
收到信号的线程对各种信号有不同的处理方法,处理方法可以分为三类:</br></br>
|
||||
第一种是类似中断的处理程序,对于需要处理的信号,线程可以指定处理函数,由该函数来处理。</br></br>
|
||||
第二种方法是,忽略某个信号,对该信号不做任何处理。</br></br>
|
||||
第三种方法是,对该信号的处理保留系统的默认值。</br></br>
|
||||
具体来说,假设其他线程要向线程1通信,则在线程1中安装一个信号并解除阻塞,在安装的同时,规定对该信号的异常处理方式。其他线程给线程1发送信号,触发线程1对该信号的处理。
|
||||
### 函数接口
|
||||
```C
|
||||
xs_sighandler_t xs_InstallSignal(int signo, xs_sighandler_t handler)
|
||||
```
|
||||
该函数用于给当前线程安装一个新的信号。</br>
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| signo | 信号值 |
|
||||
| handler | 设置对信号值的处理方式,可以是用户自定义的函数,`SIG_IGN`或`SIG_DFL` |
|
||||
</br>
|
||||
|
||||
handler的值为`SIG_IGN`时,忽略该信号;</br>
|
||||
handler的值为`SIG_DFL`时,执行信号默认处理函数`_SignalDefaultHandler`;</br>
|
||||
handler为函数句柄时,执行用户函数。 </br>
|
||||
|
||||
```C
|
||||
void xs_MaskSignal(int signo)
|
||||
```
|
||||
该函数用于屏蔽一个信号。</br>
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| signo | 信号值 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
void xs_UnmaskSignal(int signo)
|
||||
```
|
||||
该函数用于解除对一个信号的屏蔽。</br>
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| signo | 信号值 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
int xs_WaitSignal(const xs_sigset_t *set, xs_siginfo_t *si, xs_int32 timeout)
|
||||
```
|
||||
等待`set`信号到来。如果没等到这个信号,则将该线程挂起直到等到信号或超过超时时间。如果等到信号,则将`set`信号指针存入`si`。</br>
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| set | 指定等待的信号 |
|
||||
| set | 指向存储等到信号信息的指针 |
|
||||
| set | 超时时间 |
|
||||
</br>
|
||||
|
||||
```C
|
||||
int xs_KThreadKill(TaskDescriptorPointer tid, int sig)
|
||||
```
|
||||
该函数用于给线程`tid`发送信号`sig`。</br>
|
||||
|
||||
| 参数 | 描述 |
|
||||
| ------ | ------ |
|
||||
| tid | 线程 |
|
||||
| sig | 信号值 |
|
||||
|
||||
```C
|
||||
int xs_SysInitSignal(void)
|
||||
```
|
||||
该函数用于在内存池中给信号分配一片内存区。
|
||||
## 管道
|
|
@ -1,19 +1,10 @@
|
|||
# 硬件支持
|
||||
# 控制器
|
||||
|
||||
---
|
||||
|
||||
## ARM
|
||||
- [西门子](/doc/processor/riscv.md)
|
||||
|
||||
* [aiit-arm32](/doc/processor/aiit-arm32.md)
|
||||
- [线程管理](/doc/processor/riscv_sk.md)
|
||||
|
||||
* [stm32f407-st-discovery](/doc/processor/stm32f407-st-discovery.md)
|
||||
- [资源管理](/doc/processor/riscv_fpga.md)
|
||||
|
||||
* [stm32f407zgt6](/doc/processor/stm32f407zgt6.md)
|
||||
|
||||
## RISC-V
|
||||
|
||||
* [hifive1-re](/doc/processor/hifive1-rev.md)
|
||||
|
||||
* [maxgo](/doc/processor/maxg.md)
|
||||
|
||||
* [kd233](/doc/processor/kd233.md)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
# 三菱
|
|
@ -0,0 +1 @@
|
|||
# 西门子
|
|
@ -0,0 +1 @@
|
|||
# 施耐德
|
Loading…
Reference in New Issue