qnx系统学习

基础知识学习 -- qnx 系统 qnx os车载系统 阅读详情

一 QNX概述

QNX实时操作系统,采用微内核和基于消息的进程间通信。

QNX的系统进程包括:

ProcessManager,FilesystemManager,DeviceManager,NetworkManager

1 进程间通信IPC:

1)消息Message,QNX最基本的IPC,提供进程间同步通信,发送者和接受者有应答

服务器     ChannelId = ChannelCreate(Flags);
客户端    ConnectionId = ConnectAttach(Node, Pid, Chid, Index, Flag);

Node标识机器号,如果客户端与服务器在同一台机器里时,=0,或=ND_LOCAL_NODE;

pid标识该服务的进程号;

chid就是服务器调用 ChannelCreate()后得到的channelId频道号了。

基本上客户端就是同"Node这台机器里的,Pid这个进程的,Chid频道"做一个连接。有了连接以后,就可以进行消息传递了。因为一个进程可能有多个线程,channelID就是为了标识进程中的线程。

连接的终止是ConnectDetach(),channel的结束则是ChannelDestroy()了。不过,一般服务器都是长久存在的,较少需要ChannelDestroy()。

服务器    ReceiveId = MsgReceive(ChannelId, ReceiveBuffer, ReceiveBufLength, &MsgInfo);
(... 检查Buffer里的消息进行处理 ...)
MsgReply(RceeiveId, ReplyStatus, ReplyBuf, ReplyLen);
客户端    MsgSend(ConnectionId, SendBuf, SendLen, ReplyBuf, ReplyLen);
(... 由OS将这个线程挂起 ...)
(... 当服务器MsgReply()后,OS 解除线程的阻塞状态, 客户端可以检查自己的 ReceiveBuf 看看应答结果 ...)

2)代理proxy,消息的一种特殊形式,适合事件通知,发送者不用和接收者交互

函数原型:

qnx_proxy_attach()创建proxy

Trigger()触发事件

3)信号signal,IPC的一种传统形式,通常用于一步IPC

shell环境下产生信号:kill,slay

进程内产生信号的C函数:kill(),raise()

相关函数:signal(),sigaction()

4 )跨网络IPC,通过虚电路机制实现(virtualcircuits),这种机制由QNX网络管理器完成。

相关函数:

qnx_vc_attach(0,qnx_name_locate()等

5 )基于信号灯的IPC

2 数据区与iov

        除了用线性的缓冲区进行消息传递以外,QNX还提供了用iov_t来“汇集”数据,可以一次传送几块数据。如下图:客户端蓝色的Header同红色的databuf是两块不相邻的内存,但传递到服务器端的ReceiveBuffer里,就是连续的。在服务器端,要想得到原来databuf里的数据,只需要(ReceiveBuffer + sizeof(header))就可以了。(要注意数据结构对齐)

客户端      SETIOV(&iov[0], &header, sizeof(header));
SETIOV(&iov[1], databuf, datalen);
MsgSendvs(ConnectionId, iov, 2, Replybf, ReplyLen);                                                                          //"header" "databuf" 是不连续的两块数据
服务器接收后, "header""databuf"被连续地存在ReceiveBuffer里。                    ReceiveId = MsgReceive(ChannelId, ReceiveBuffer, ReceiveBufLength, &MsgInfo);
header = (struct header *)ReceiveBUffer;
databuf = (char *)((char *)header + sizeof(*header));

3 资源管理器

        一个资源管理器基本上来说就是一个服务器。在QNX上,“资源”可以是一个硬件(硬件资源管理器其实就是我们常说的硬件驱动),也可以是一种服务,比如TCPIP网络服务,或者ntfs文件系统服务;“资源”甚至可以是一个文件(或者目录)。

        因为一个资源管理器都是由一个路经名作为入口的,而POSIX又定义了对一个文件可进行的操作,所以QNX预定义了这些操作所需要传递的消息类型和数据格式。QNX提供的资源管理器框架大致可以分成4个部份:

  1)  iofunc (iomsg) 层,提供了所有POSIX对文件可以进行的io操作 (sys/iofuncs.h, sys/iomsg.h)

QNX总结了34个对文件操作,基本上POSIX对文件的处理,都可以通过这34个操作进行。iofunc层的每一个回调函数,都有一个对应的数据结构供客户端和服务器端进行消息传递,在sys/iomsg.h里
Connect Functions回调IO Functions回调

open

unlink

rename

mknod

readlink

link

read
write
close_ocb
stat
notify
devctl
unblock
unblock
mount
pathconf
lseek
chmod
chown
utime
openfd
fdinfo
lock
space
shutdown
mmap
msg
umount
dup
close_dup
lock_ocb
unlock_ocb
sync
power

比如 io_stat,

    typedef union {
        struct _io_stat    i;
        struct  stat       o;
    } io_stat_t;

可以看到,io_stat是从客户端向服务器端发送一个 stauct _io_stat; 而服务器端返回的,直接就是一个 struct stat o; 这个struct stat, 就是 POSIX 的 stat() 函数取到的返回值。
 

   2) resmgr层,提供了登记路径名,接收数据并分发给iofunc执行具体操作。iofunc 和 resmgr,是写一个资源管理器的基础。

        如果 iofunc 层提供了各种回调函数的话,resmgr层就是那个“循环按收信息并调用iofunc”的那一层。例如:

    resmgr_attach(….)
    ctp = resmgr_context_alloc()
    for (;;) {
        ctp = resmgr_block(ctp);
        resmgr_handler(ctp)
    }

resmgr层和iofunc层给合,就可以搭建一个资源管理器。
 

static int now_read(resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{
    iofunc_ocb_t *o = (iofunc_ocb_t *)ocb;
    char nowstr[128];
    time_t t;
    int n;
 
    /* 判断是不是文件 open 后第一次 read(),不是的话,回复0,这样客户端的 read()就会返回0,
     * 以示读到了文件尾    
     */
    if (o->offset != 0) {
        return 0;
    }
 
    /* 取当前时间,写入字符串 */
    t = time(NULL);
    n = strftime(nowstr, 128, "%Y-%m-%d %H:%M:%Sn", localtime(&t));
 
    o->offset += n;
 
    /* 把字符串返回给客户端 */
    MsgReply(ctp->rcvid, n, nowstr, n);
 
    /* 告诉 resmgr 层,我们已经做过Reply了,不要再reply客户端了 */
    return _RESMGR_NOREPLY;
}

void main()
{
/* 建一个 dispatcher,这个可以想像就是一个接收数据的频道 */
dispatch = dispatch_create();
 
/* 资源管理器本身的一些参数,下面这个就是指定了资源管理器最多一次可以处理10个 iov_t */
memset( &res_attr, 0, sizeof( res_attr ) );
res_attr.nparts_max = 10;
res_attr.msg_max_size = 0;
 
/* io_attr 其实可以想像成一个文件相关的参数,比如读写权限等等 */
iofunc_attr_init(&io_attr, 0666 | S_IFCHR, 0, 0);
 
 
/* 初始化iofunc层回调 */
iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &connect_funcs, 
_RESMGR_IO_NFUNCS, &io_funcs );

io_funcs.read = now_read;
 
/* 建立起资源管理层,同时注册路径 */
rmgid = resmgr_attach(dispatch, &res_attr, "/dev/now", _FTYPE_ANY, 0, &connect_funcs, 
                      &io_funcs,&io_attr);
 
/* 准备一个资源管理层的 context 以备使用 */
ctp = resmgr_context_alloc(dispatch);
 
while (1)
{
    /* resmgr_block() 相当于做了一个 MsgReceive() */
    ctp = resmgr_block(ctp);
 
    /* 根据收到的信息,调用相应的回调程序 */
    resmgr_handler(ctp);
}
}

//执行后会生产一个/dev/now 的文件

   3) dispatch层,在一些复杂的资源管理器里,“外来的消息传递”并不是唯一需要处理的。也有可能需要处理“脉冲”,或者有时候一个“信号”。dispatch层会主动识别不同的输入信息,然后转给不同的处理函数进行处理。

         虽然大多数情况下,用iofunc层+resmgr层已经可以构建一个完整的资源管理器了,但是有时候资源管理器需要同时处理别的消息,这时就需要 dispatch 层了。dispatch可以处理其他形态的信息,除了可以用 resmgr_attch() 来挂接resmgr 和 iofunc以外,还可以做这些 (sys/dispatch.h):

   int message_attach(dispatch_t *dpp, message_attr_t *attr, int low, int high,
    int (*func)(message_context_t *ctp, int code, unsigned flags, void *handle),
    void *handle);

有时候资源管理器在使用标准的 iomsg 以外,还想要定义自己的消息类型,那就会用到这个message_attach(). 这个函数意思是说,如果收到一个消息,它的消息类型在 low 和 high 之间的话,那就回调 func 来处理。

当然,要保证 low/high 不会与 iomsg 重叠,不然就会有歧义。在 iomsg.h 里已经定义了所有的 iomsg 在 _IO_BASE 和 _IO_MAX 之间,所以只要保证 low > _IO_MAX 就可以了。

pulse_attach()

    int pulse_attach(dispatch_t *dpp, int flags, int code,
    int (*func)(message_context_t *ctp, int code, unsigned flags, void *handle),
    void *handle);

有许多管理硬件资源的管理器(驱动程序),除了提供iomsg消息,来对应客户端的io请求以外,也会很常见需要接收“脉冲”来处理中断 (InterruptAttachEvent)。这时,用 pulse_attach() 就可以把指定的脉冲号(code),绑定到回调函数 func 上。

select_attach()

    int select_attach(void *dpp, select_attr_t *attr, int fd, unsigned flags,
    int (*func)(select_context_t *ctp, int fd, unsigned flags, void *handle),
    void *handle);

很多资源管理器,在处理客户端请求时,还需要向别的资源管理器发送一些请求。而很多时候这些请求可能不能立即返回结果,通常情况下,可以用 select() 来处理,但第一我们无法使用会阻塞的select(),因为我们是一个资源管理器的服务函数,如果被阻塞无法返回,就意味着我们无法处理客户端请求了;第二我们也无法用 select() 轮询,因为我们一旦返回,就会进入 等待客户端消息的阻塞状态,没有新消息来时,不会退出阻塞状态,也就没有机会再去轮询 select()了。

在使用 dispatch时,进行特殊的 *_attach() 挂接以后,只要把resmgr层的几个函数替换成dispath层的几个函数 就可以了,比如这样:

    ctp = dispatch_context_alloc(dispatch);
    while (1)
    {
        ctp = dispatch_block(ctp);
        dispatch_handler(ctp);
    }

dispath_block() 相当于阻塞并等待,而 dispatch_handle() 则根据不同的挂接,调用不同的回调函数进行处理。

另一个比较常用的dispatch函数是dispatch_create_channel()。有时候,你希望自己用 ChannelCreate()创建频道,而不是让dispatch_create()自动为你创建频道,就可以用这个函数。之所以需要自己创建频道,是因为有时候希望在频道上设一些特殊的标志(ChannelCreate() 的 flags)。

    4)thread pool层,提供了一个线程池管理,可以配置实现多个线程进行资源管理。

          上面这些用 while (1) 来循环处理消息的资源管理器,明显都是“单线程”资源管理器,一共只有一个线程来处理客户端请求。对于一些需要频繁处理客户请求的资源管理器,自然会想到用“多线程”资源管理器。基本就是用几个线程来执行上面的 while(1)循环。

         线程池(Thread Pool)就是用来实现这个的。使用起来也比较简单,先配置 poot_attr,然后创建并启动线程池。
 

    memset(&pool_attr, 0x00, sizeof pool_attr);
    if(!(pool_attr.handle = dpp = dispatch_create())) {
        perror("dispatch_create");
        return EXIT_FAILURE;
    }
    pool_attr.context_alloc = dispatch_context_alloc;
    pool_attr.block_func    = dispatch_block;
    pool_attr.handler_func  = dispatch_handler;
    pool_attr.context_free  = dispatch_context_free;
    pool_attr.lo_water      = 2;     //至少应该有多少线程需要在等待任务
    pool_attr.hi_water      = 5;     //最多这些线程可以等待任务
    pool_attr.increment     = 2;     //一次递增的线程数
    pool_attr.maximum       = 10;    //线程池里最多可以建多少线程
    tpp = thread_pool_create( &pool_attr, POOL_FLAG_EXIT_SELF)
    thread_pool_start( tpp );

说明:线程池一旦启动,首先会创建5个线程,都在 dispatch_block()上等待接受任务。

当有一个请求来时,1号线程为其服务,假设这个服务线程在服务过程中,还需要向别的线程请求数据,一时回不来,那就还剩下4个线程等待任务。

如些再来两个请求,我们会变成3个线程在进行服务,2个线程等待任务的情形。

这时,当第4个请求来时,又一个线程去进行服务,这时只有1个线程在等待任务了,比lo_water少,所以线程池会自动再新建 2 个(increment) 线程,把他们放在等待任务队列中。所以这时我们有4个线程在服务,3个线程在等待。

如果服务线程无法回收,而新的请求又进来,导致等待线程数又低于lo_water的话,那么,线层池还会继续增加线程以保证有足够线程在等待服务,但是服务线程数与等待线程数的和,不会超过10(maximum).

假如在4个线程服务,3个线程等待的状态下,有2个服务线程结束了服务,它们会被还回线程池,线程池就会把这2个线程继续放入等待队列。也就是变有还有2个服务线程,5个等待线程的状态。

现在,如果又有1个线程结束服务,回归线程池了。如果把这个线程再放入等待队列,那就会有6 个线程等待服务,这个超过了 hi_water,所以线程池会结束这个线程。这样,我们就会有1个线程在服务,5个线程在等待的情形,线程总数下降到了6。

4 HAM

HAM(High Availability Manager)是一个“智能看门狗”——一个高弹性的管理进程,它可以在系统服务或进程失败或不再响应时监视您的系统并执行多级恢复。作为一个自我监控的管理者,HAM对内部故障具有弹性。不管出于什么原因,如果HAM本身被异常地停止,它可以通过移交给一个称为“监护人”的镜像进程,立即并完全地重建自己的状态。简单说,可以用守护机制做进程保活的。HAM机制是QNX原生机制,通过监控进程状态做到进程的重启。

entry    实体,可理解为进程
condition    条件,类似进程死亡这种时候
action    动作,类似重新启动等具体行为
  • QNX启动HAM进程,HAM管理需要监控的进程。
  • 可以直接执行ham以启动ham进程。
  • 不需要使用ham时可通过hamctrl -stop 停止ham,也可以调用ham_stop()
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <process.h>
#ifdef QNX
#include <ha/ham.h>
#endid

int main(int argc, char** argv)
{
#ifdef QNX
    printf("HAM Prepar~\n");
    int status;
    char* inetdpath;
    ham_entity_t* ehdl;
    ham_condition_t* chdl;
    ham_action_t* ahdl;
    int inetdpid;
	// 新启一个进程
    inetdpath = strdup("/usr/bin/picherdemo/helloworld -D");
	// 连接HAM
    ham_connect(0);
	// 将进程交给HAM监控
    ehdl = ham_attach("inetd", ND_LOCAL_NODE, inetdpid, inetdpath, 0);
    if (ehdl != NULL)
    {
		//添加条件,当进程“death”时
        chdl = ham_condition(ehdl, CONDDEATH, "death", HREARMAFTERRESTART);
        if (chdl != NULL) {
			//添加动作,重启进程
            ahdl = ham_action_restart(chdl, "restart", inetdpath,
                HREARMAFTERRESTART);
            if (ahdl == NULL)
                printf("add action failed\n");
        }
        else
            printf("add condition failed\n");
    }
    else
        printf("add entity failed\n");
	//关闭与HAM的连接
    ham_disconnect(0);
#endif // QNX
    while (true) {
        printf("Process id: %d\n ", getpid());
        std::cout << "Thread id:\n"<< std::this_thread::get_id();
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }

	return 0;
}


5 SLM

系统启动和监控:启动由许多必须按特定顺序启动的进程组成的复杂应用程序,下图是可以看到SLM在整个QNX BOOT的运行位置。
在这里插入图片描述

通常使用xml配置的方式来确定进程的启动顺序

//根节点
<SLM:system>
	//组件,可以有多个组件
    <SLM:component name="io-pkt"> 
		//指令--执行/sbin/io-pkt-v6-hc
        <SLM:command>/sbin/io-pkt-v6-hc</SLM:command> 
		//执行指令需要的参数--ptcpip stacksize=8192
        <SLM:args>-ptcpip stacksize=8192</ SLM:args> 
		//启动后等待--等待/dev/socket起来
        <SLM:waitfor wait="pathname">/dev/socket</SLM:waitfor> 
    </SLM:component> 
    <SLM:component name="ifconfig"> 
		//依赖项--需要依赖io-pkt起来后才能启动
        <SLM:depend>io-pkt</ SLM:depend> 
        <SLM:command>/sbin/ifconfig</SLM:command> 
        <SLM:args>en0 192.168.1.5 up</SLM:args> 
        <SLM:waitfor wait="exits"></SLM:waitfor > 
    </SLM:component> 
	
	//由组件组成
    <SLM:module name="net-setup"> 
		//执行io-pkt
        <SLM:member>io-pkt</SLM:member> 
		//执行ifconfig
        <SLM:member>ifconfig</SLM:member> 
    </SLM:module> 
</SLM:system>

SLM主要负责systemd中调节进程间启动依赖的任务。同时为了能够在当前component的依赖项异常退出时对整个依赖树做恢复,它有一些基本的崩溃检测和基本的恢复动作。比如:a进程依赖b进程,b进程依赖c进程。那么如果c进程异常退出,SLM会先stop b进程和a进程,然后依次重新启动c→b→a三个进程。但是它无法知道像b进程中有某个线程阻塞这样的情况。

而HAM则强调对某个或某几个进程的详细行为监控。比如通过心跳机制对具体的某几个线程进行精准监控,同时通过代码对恢复过程进行精细的控制。比如:你可以监控一个线程是否在按照一定频率发送心跳,如果它没有,你可以先尝试重启这个线程,比如调用pthread_cancel或者触发这个线程的退出条件等,如果这个动作失败了,你再尝试重启整个进程。这种细粒度的检测和恢复操作,SLM是做不到的。

二 命令用法

打印所有的日志信息:slog2info    (程序中的日志都是用slog2info写入的)
打印特定的日志信息:slog2info -m 12334   (12334是程序中用sloginfo写的时候,自己定义的),这样就可以进显示12334的日志信息;
清除日志: slog2info -c    (有时候日志信息太多,会先使用该命令将之前的日志信息清除,然后再使用sloginfo ,显示当前的日志信息)


实时显示日志信息:slog2info -w


slay  进程名  :结束进程  (注意是进程名,不是进程号)


pindin :显示当前运行的所有进程名及进程号
pidin |grep 进程名     :筛选我们想要的进程名


shutdown  :重启QNX系统
注意:当有守护程序时,倘若我们将守护去掉,shutdown后仍能重启守护的程序,但仅会启动这一次,关闭终端就不会再守护程序了,程序就不会再被重启了。
当我们测试程序时,不想让程序自动启动,方法:
修改守护程序配置文件,将进程名赋值为0  -----》mytest=0;  (ps: mytest=1;则是守护该进程)
或者将进程通过cp的方式重命名,然后将原可执行程序删除(因为不支持mv命令)


pfm  :打开资源管理器(文件系统)


ped   :打开文本编辑器


passwd 用户名           --->创建新用户,没有useradd命令, 键入passwd  用户名后,会让输入密码。

参考文章:

QNX基础教程

qnx 设备驱动开发_QNX资源管理器_weixin_39603327的博客-CSDN博客

qnx log 系统 和linux 中查看 kernel log 信息的 dmesg 命令一样, qnx 里面也有一个查看 log 信息的命令,那就是slog2info命令, 如下图所示是qnx 官网对其的介绍slog2info 打印的是 slogger2 所记录的 log 信息,所以在执行 slog2info 命令之前,slogger2 必须已经在系统中处于运行状态;qnx 里面也可以使用 printf() 进行打印 log, 只是它不被系统 log(slogger2。 阅读详情

相关推荐

平台之上还是平台之下?QNX学习的分水岭。

学习QNX有一段时间了,应该回过头总结一下学习过程,理一理思路,为下一步学习理清方向,同时也可以给各位共同学习的朋友(我心中“同学”的概念)提供参考。   看一看自己的文章和目前学习的内容,发现QNX学习涉及了两个大的方面,一方面是QNX平台的使用以及QNX平台上的开发工作,

keyboardOTA的专栏 1万+

QNX是什么系统,零基础如何学习QNX

在完成了基础学习和入门实践后,可以从以下高级领域深入研究 QNX 的特性和应用,涉及更复杂的系统设计与优化。在完成了基础学习和入门实践后,可以从以下高级领域深入研究 QNX 的特性和应用,涉及更复杂的系统设计与优化。通过深入学习 QNX 的微内核架构、资源管理器、实时通信和高级图形技术,你可以掌握 QNX 的核心开发技能,并将其应用到专业领域。通过深入学习 QNX 的微内核架构、资源管理器、实时通信和高级图形技术,你可以掌握 QNX 的核心开发技能,并将其应用到专业领域。

小宝哥Code的专栏 1万+

[实践篇]13.14 如何在QNX侧,打印日志到slog2info缓冲区

有些时候我们需要对Q侧的服务进行调试,尤其是对平台或QNX原生服务进行开发调试的时候,会遇到日志信息严重不足, 尤其是在QNX作为闭源操作系统的情况下,很多的基础能力或者核心服务都只是一个库文件或者二进制交付的Binary,那么就需要我们在优先的flow中尽可能地埋点,来把服务的逻辑串联起来。

从0到1,突破自己 3628

QNX命令-持续更新

use [ 指令 ]如i2ctool用法。

weixin_43824344的博客 3234

QNX软件-用于学习QNX系统指令

QNX软件-用于学习QNX系统指令 去发现同类优质开源项目:https://gitcode.com/ 欢迎来到QNX软件资源下载仓库!此仓库提供了QNX系统指令学习的资源文件,旨在帮助用户更好地理解和使用QNX操作系统。 文件描述 此资源文件是一份关于学习QNX系统指令的教程,内容涵盖了QNX操作系统的基本指令及其用法。通过阅读本教程,您可以快速掌握QNX系统的常用指令,为后续的系统使用和维护打下...

gitblog_06730的博客 346

QNX系统学习资料整理

QNX系统学习资料整理 【下载地址】QNX系统学习资料整理 QNX系统学习资料整理本仓库提供了一份详尽的QNX系统学习资料,涵盖了QNX 6.5版本的内容 项目地址: https://gitcode.com/open-source...

gitblog_09812的博客 462

【亲测免费】 探索QNX系统的奥秘:一份详尽的学习资料

探索QNX系统的奥秘:一份详尽的学习资料 【下载地址】QNX系统学习资料整理 QNX系统学习资料整理本仓库提供了一份详尽的QNX系统学习资料,涵盖了QNX 6.5版本的内容 项目地址: https://gitcode.com/op...

gitblog_09734的博客 1003

嵌入式操作系统QNX学习资源

嵌入式操作系统QNX学习资源 去发现同类优质开源项目:https://gitcode.com/ 资源介绍 此仓库提供了《分布式嵌入式操作系统 QNX》一书的电子版资源,这是一本面向嵌入式系统开发者和学习者的入门级图书。书中详细介绍了嵌入式操作系统QNX的基本概念、原理以及应用。该书由候业勤和张菁翻译,宇航出版社出版于1999年1月。 本书内容全面,涵盖了QNX操作系统的核心特性,包括进程管理、内存...

gitblog_06705的博客 273

嵌入式操作系统QNX学习资源:开启嵌入式系统学习新篇章

嵌入式操作系统QNX学习资源:开启嵌入式系统学习新篇章 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在嵌入式系统领域,QNX以其高效、稳定和强大的特性,一直以来都是开发者关注的焦点。本项目致力于为广大嵌入式系统开发者和学习者提供一份权威、全面的QNX学习资源——《分布式嵌入式操作系统 QNX》电子版。这本书由候业勤和张菁翻译,宇航出版社出版,深入浅出地介绍了QNX操...

gitblog_06735的博客 673

低版本QNX源码-专供分析学习:探索操作系统奥秘的钥匙

低版本QNX源码-专供分析学习:探索操作系统奥秘的钥匙 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 低版本QNX源码,是专为那些渴望深入理解操作系统内部机制的学者和工程师们准备的学习资源。QNX系统以其高效、稳定、安全的特性著称,在嵌入式系统领域有着广泛应用。然而,自QNX6版本之后,源码不再开源,使得对系统内部结构的研究变得极为困难。本项目正是填补这一空白,提供了...

gitblog_06754的博客 315

阅读QNX《System Architecture》中

这几天一直在读《System Architecture》一书。 总的来讲,QNX 《System Architecture》是一本对于学习QNX极为重要的书,通过这本书,我对QNX系统架构有了进一步的理解。另外,对于其他QNX学习人员的建议是其中的很多细节可以跳过,包括IPC的

keyboardOTA的专栏 4524

QNX操作系统学习-基础入门篇一

是一个操作系统,其核心特点是。它像一个“大超市”,什么都有。是一个实时操作系统,其核心特点是。它像一个“精密的瑞士军刀”,专为特定关键任务而设计。

qq_25461777的博客 389

qnx学习笔记-QNX系统下载graphic镜像

e-mail 174176320@qq.comTQE9开发板下载带有图形界面的qnx-ifs系统镜像后总是无法启动,卡在Load QNX image from SDMMC...分析问题之前,先分析一下sabreARD-graphics.build的启动脚本,镜像文件说明如下:[html] view plain copy[image=0x10800000]  # For u-boot, IFS im...

xjhhjx的专栏 2389

QNX 学习笔记一:导入BSP.

今天开始整 qnx系统。在此介绍学习使用的一些步骤,关于QNX系统的介绍网上有不少资料。 使用BSP的方式有2种:unzip或者import。 import使用较为方便,我们来简单看一下help的介绍: Select File-->Import. Expand the QNX folder. Select QNX Board Support Package from the list.

GaryLiu1104的专栏 3274

QNX实时操作系统学习笔记之嵌入式系统(二)

QNX实时操作系统学习笔记之嵌入式系统(二) BSP 一个BSP一般包括:IPL,startup,默认的buildfile,网络支持,具体开发板设备驱动,系统管理器,公用工程等。一般情况下BSP是以源代码的形式给出的,除非对源代码有限制的,只会以二进制形式给出。 一般把安装BSP的路径成为bsp_working_dir,包含以下子路径:src,prebuit,install,images

CyberLabs的专栏 5007

QNX的英文资料

搜了一轮QNX中文资料,感觉都不是很全面,咬咬牙,去QNX官网看了一下(www.qnx.com). 不愧是80年代成长到现在的公司,资料写的很完整。(对我们而言唯一的问题是英文。。。。) 在一下链接中可以看到关于QNX各方面的PDF文档: http://www.qnx.co

keyboardOTA的专栏 2669

嵌入式系统学习笔记之QNX

QNX是一种商用的遵从POSIX规范的类Unix实时操作系统,目标市场主要是面向嵌入式系统。它可能是最成功的微内核操作系统之一。 遵从POSⅨ规范,目标市场主要是嵌入式系统QNX成立于1980年,是加拿大一家知名的嵌入式系统开发商。  QNX是一个分布式、嵌入式、可规模扩展的硬实时操作系统。它遵循POSⅨ.1 (程序接口)和POSⅨ.2 (Shell和工具)、部分遵循POSⅨ.1b(实时扩展)。...

david175的专栏 788
上一篇: 编解码版税royalty和授权费license fee
下一篇: android播放器:MediaPlayer ExoPlayer ijkplayer
步基
博客等级 码龄18年 1万+粉丝 137原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

步基

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值