B_QuRT_User_Guide(2)
2.4 Objects
一个QuRT用户程序通过定义对象并对其进行操作来访问大多数QuRT服务。例如:
qurt_mutex_t my_mutex; /* mutex object */
...
qurt_mutex_init(&my_mutex); /* init mutex object */
...
qurt_mutex_lock(&my_mutex); /* lock mutex */
...
qurt_mutex_destroy(&my_mutex); /* destroy mutex object */
QuRT对象支持两组管理对象的操作。
- 对于完全存储的对象,使用初始化和销毁操作(如前面的例子所示)。
- 在用户程序分配的内存中。
- 对于部分存储在由RTOS内核自动分配的内存中的对象,使用创建和删除操作。
管道对象支持这两种操作对:当管道缓冲区是用户分配的时候使用初始化和销毁,当内核自动分配管道作为初始化管道对象的一部分的时候使用创建和删除。
计时器对象只支持对象管理的创建和删除。所有其他的QuRT对象只支持初始化和销毁来管理对象。
除了对象管理,大多数对象定义了额外的操作,执行与该对象相关的服务(前面例子中的qurt_mutex_lock)。
注意:当不再使用时,对象必须被销毁(用destroy或delete操作)。如果不这样做,会导致QuRT内核的资源泄漏。
将QuRT对象视为具有不透明的类型,只通过QuRT函数访问。
2.5 Nonblocking and Cancellable Operations
QuRT定义的操作是其他QuRT操作(锁定、关闭、等待、发送、接收)的非阻塞或可取消的版本。比如说:
- qurt_mutex_try_lock
- qurt_sem_try_down
- qurt_signal_wait_cancellable - qurt_pipe_send_cancellable
操作名称中的前缀 “try_“表示非阻塞操作,可取消的操作使用后缀”_cancellable”。
非阻塞操作使线程能够尝试执行一个操作,而不会有线程被暂停的风险–如果操作失败,它会立即返回一个错误结果。
如果一个系统级的事件打断了调用线程,可取消的操作会自动返回:特别是如果线程的用户进程被杀死,或者线程必须完成其当前的QDI调用并返回到用户空间。
当一个操作被取消时,调用线程必须假设该操作从未完成:调用者必须停止等待指定的资源或事件,并假设该事件从未发生或该资源从未可用。
注意:取消与进程关闭不同,不应以此来处理。
如果驱动程序检测到一个被取消的操作,它必须尽可能直接地将错误结果传回给
它的调用者。驱动程序还必须确保使其内部数据结构处于有效和可预测的状态。
2.6 64-bit Operations
QuRT内存管理服务同时定义了某些操作的32位和64位版本。提供32位操作是为了向后兼容早期版本的QuRT。64位的
操作在功能上等同于相应的32位操作,但能够访问4GB以上的内存地址。
操作名称中的后缀"_64 "用于识别64位操作。
3 Threads
多任务允许一个用户程序中的多个指令序列并行执行。运行中的用户程序中的每个指令序列被称为线程。一旦启动,线程就以表3-1中所列的四种状态之一存在。
内核负责在这些状态之间切换线程。它使用一个调度器来决定哪些线程要运行–调度器总是选择优先级最高的就绪线程。
当一个线程的状态从 "运行 "变为 "就绪 "或 "等待 "时,它就被暂停,而当它从 "等待 "变为 "就绪 "时,它就被唤醒。所有线程都被初始化为就绪状态。在系统启动期间,调度器选择优先级最高的线程来执行,并将其线程状态改为运行。
图3-1显示了可以导致内核执行上下文切换的事件,即暂停一个线程并恢复另一个线程。
QuRT是抢占式的–当内核操作暂停当前线程或唤醒一个更高优先级的线程时,就会发生上下文切换。下列内核操作可以导致上下文切换。
- 创建或退出一个线程
- 改变一个线程的优先级
- 等待或释放一个互斥体或信号体
- 等待或恢复一个信号、障碍或条件变量 - 从一个管道读写
- 中断
一个线程的优先级决定了该线程相对于系统中其他线程的执行频率:如果两个准备就绪的线程有不同的优先级,但只有一个硬件线程可用,内核会执行优先级较高的线程,直到它被中止。
线程在首次创建时就被分配了优先级;然而,在某些情况下,用户程序系统必须在线程创建后调整线程的优先级。例如,为了防止优先级倒置,一个线程可能需要提高自己的优先级或另一个线程的优先级。
优先级被指定为数值,范围从0到255,数值越小代表优先级越高。0代表最高的线程优先级。
注意:QuRT可以被配置为具有不同的优先级范围(第2.2节)。
线程具有以下属性。 - 线程名称和timetest字符串标识符在调试或剖析期间识别线程。这些属性与内核生成的线程标识符不同,后者用于在API线程操作中指定线程。
- TCB分区 - 用于分配线程控制块(TCB)的内存。线程TCB分区指定在TCM/LPM而不是普通内存中分配线程控制块的最大线程数。
- 线程亲和性指定了线程可以在哪些Hexagon处理器硬件线程上执行。
- 线程优先级决定了线程的执行优先级。
- 总线优先级是内部总线优先级状态。
- Timetest ID是硬件调试时使用的数字跟踪标识符。
- 堆栈大小是用于线程调用堆栈的内存区域的大小(字节数)。
- 线程堆栈地址和大小指定作为线程调用堆栈的内存区域。用户
负责分配用于堆栈的内存区域。 - 线程入口点是线程启动时执行的函数。该函数是在用户程序中定义的,并且必须接受一个单一的void指针作为函数参数。
- 线程参数是线程启动时传递给线程函数的一个指针。它允许编写一个单一的函数供多个线程执行。
- 线程信号是一个信号对象,QuRT为每个线程创建。
- 线程缓存分区为当前线程分配内存,用于L1 I缓存、L1 D缓存和
L2高速缓存。
注意:由线程创建操作返回的线程标识符指定了线程。这个标识符与线程名称或时间测试ID不同。
设置线程属性
线程有两种属性。 - 静态属性在线程被创建后不能被改变
- 动态属性在线程创建后可以被改变
唯一的动态线程属性是优先级、时间测试ID和缓存分区 - 所有其他线程都是静态的。
静态属性可以在线程创建之前通过qurt_thread_attr_init和qurt_thread_attr_set函数来设置,也可以在创建线程时直接将属性作为参数传递给qurt_thread_create()。
动态属性是在使用qurt_thread_set函数创建一个线程后设置的。
注意:两个线程属性–线程标识符和线程信号–是由内核设置的只读属性。
时间测试ID属性存储在一个Hexagon处理器寄存器中。
线程在QuRT中被表示为共享对象。线程对象支持以下操作。- qurt_thread_attr_get() - qurt_thread_attr_init()
- qurt_thread_attr_set_bus_priority()
- qurt_thread_attr_set_name()
- qurt_thread_attr_set_priority()
- qurt_thread_attr_set_stack_addr()
- qurt_thread_attr_set_stack_size()
- qurt_thread_attr_set_stack_size2() - qurt_thread_attr_set_tcb_partition() - qurt_thread_attr_set_timetest_id()
- qurt_thread_create()
- qurt_thread_exit()
- qurt_thread_get_anysignal()
- qurt_thread_get_id()
- qurt_thread_get_l2cache_partition() - qurt_thread_get_name()
- qurt_thread_get_priority()
- qurt_thread_get_timetest_id()
- qurt_thread_join()
- qurt_thread_resume()
- qurt_thread_set_cache_partition()
- qurt_thread_set_priority()
- qurt_thread_attr_set_detachstate()
- qurt_thread_set_timetest_id()
- qurt_thread_stid_set()
- qurt_sleep()
- qurt_thread_get_tls_base()
- qurt_busywait()
- Data Types
- Constants and Macros
3.1 qurt_thread_attr_get()
3.1.1 Function Documentation
3.1.1.1 int qurt_thread_attr_get ( qurt_thread_t thread_id, qurt_thread_attr_t ∗
获取指定线程的属性。
Dependencies
无
3.2 qurt_thread_attr_init()
3.2.1 Function Documentation
3.2.1.1 static void qurt_thread_attr_init ( qurt_thread_attr_t ∗ attr )
当一个线程被创建时,初始化用于设置线程属性的结构。在属性结构
被初始化后,Explicity使用线程属性操作设置该结构中的各个属性。初始化操作设置了以下默认属性值。
- 名称 - NULL字符串
- TCB分区 - QURT_THREAD_ATTR_TCB_PARTITION_DEFAULT - 亲密度 - QURT_THREAD_ATTR_AFFINITY_DEFAULT
- 优先级 - QURT_THREAD_ATTR_PRIORITY_DEFAULT
- asid - qurt_thread_attr_asid_default
- 总线优先级 - QURT_THREAD_ATTR_BUS_PRIO_DEFAULT
- Timetest ID - QURT_THREAD_ATTR_TIMETEST_ID_DEFAULT
- stack_size - 0
- stack_addr - 0
- detach状态 - QURT_THREAD_ATTR_CREATE_DETACHED
- stid - qurt_thread_attr_stid_default