OS 抽象层
OS 抽象层介绍
OS抽象层主要为了适配Armino平台不同的操作系统
对于不同的操作系统,OS抽象层对外提供一套统一的接口
目前Armino平台OS抽象层支持的操作系统为FreeRTOS.
目前Armino平台posix接口仅支持FreeRTOS V10操作系统,默认关闭,若使用,需要打开CONFIG_FREERTOS_POSIX配置开关
备注
在使用FreeRTOS的posix功能的时候,在引用posix相关头文件之前,需要先引用FreeRTOS_POSIX.h头文件;
可以在components/bk_rtos/freertos/posix/freertos_impl/include/portable/bk/FreeRTOS_POSIX_portable.h中自定义相关配置,比如某些功能或者数据结构想使用自定义或者编译器自带的,可以在该文件中屏蔽掉posix相关功能。
在移植posix时,如果遇到与编译器自带的头文件有冲突的情况,请优先检查以上两条。
抽象层API
任务创建:
创建任务:
bk_err_t rtos_create_thread( beken_thread_t* thread, uint8_t priority, const char* name, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg ) 参数说明: -thread: 指向创建任务的句柄 -priority: 任务优先级 需要注意的是:对于freertos操作系统内核,任务对应的优先级数字越大,则实际的优先级越大。 而对于应用层而言则相反,创建任务时配置的优先级数字越大,实际的优先级越小。 这是因为在SDK中,操作系统适配层做了统一的管理。所以用户视角看到的最大优先级为0,最小优先级为9。 建议用户在创建优先级时配置为6到8的范围。 -name :创建的任务名称 -function:指向任务体入口函数 -stack_size:任务堆栈的大小,单位为字节 -arg:传递给任务函数体的参数 返回值: -kNoErr:任务创建成功 -kGeneralErr: 任务创建失败
任务挂起与恢复:
在某个core上挂起某个任务:
void rtos_suspend_thread(beken_thread_t* thread) 参数说明: -thread:任务的句柄,如果传入的参数为NULL,代表是挂起或恢复自身
在某个core上挂起调度器:
void rtos_suspend_all_thread(void)
在某个core上恢复某个任务:
void rtos_resume_thread(beken_thread_t* thread)
在某个core上恢复调度器:
void rtos_resume_all_thread(void)
其他任务相关接口:
除了对底层标准的任务接口进行封装外,适配层还提供了以下和任务相关的接口.
任务删除:
bk_err_t rtos_delete_thread( beken_thread_t* thread )
判断指定的线程是否为当前正在运行的线程:
bool rtos_is_current_thread(beken_thread_t *thread) 参数: -Thread:指定的任务句柄 返回值: -true:是当前任务 -false: 不是当前任务
获取当前正在运行的任务句柄:
beken_thread_t*rtos_get_current_thread(void) 返回值:当前任务句柄
设置指定任务的优先级:
bk_err_t rtos_thread_set_priority( beken_thread_t *thread, int priority)
将一个任务挂起指定的时间,单位为秒:
void rtos_thread_sleep(uint32_t seconds)
将一个任务挂起指定的毫秒时间:
bk_err_t rtos_delay_milliseconds(uint32_t num_ms )
备注
任务延时会触发系统调度
队列:
初始化一个队列:
bk_err_t rtos_init_queue( beken_queue_t* queue, const char* name, uint32_t message_size, uint32_t number_of_messages ) 参数说明: -queue:队列的句柄 -name: 队列的名称 -message_size: 队列中消息的大小 -number_of_messages:消息的总长度(等同于队列的深度) 返回值: -kNoErr:队列操作成功 -kGeneralErr: 队列操作失败往队列尾部发送消息:
bk_err_t rtos_push_to_queue( beken_queue_t* queue, void* message, uint32_t timeout_ms ) 内部会判断当前是处于中断上下文还是任务上下文,从而调用不同的内核接口实现对应的功能 参数说明: -timeout_ms:超时时间,可配置为 0代表不超时 BEKEN_WAIT_FOREVER,代表一直超时阻塞 其他值,代表时间的超时时间往队列头部发送消息:
bk_err_t rtos_push_to_queue_front( beken_queue_t* queue, void* message, uint32_t timeout_ms ) 内部会判断当前是处于中断上下文还是任务上下文,从而调用不同的内核接口实现对应的功能从队列接收消息:
bk_err_t rtos_pop_from_queue( beken_queue_t* queue, void* message, uint32_t timeout_ms ) 内部调用的是xQueueReceive,仅支持在任务上下文使用删除一个队列:
bk_err_t rtos_deinit_queue( beken_queue_t* queue )
判断一个队列是否为空:
bool rtos_is_queue_empty( beken_queue_t* queue ) 仅能在中断上下文中调用
判断一个队列是否已满:
bool rtos_is_queue_full( beken_queue_t* queue ) 仅能在中断上下文中调用
信号量:
创建一个计数信号量,设置初始值为0:
bk_err_t rtos_init_semaphore( beken_semaphore_t* semaphore, int maxCount )
创建一个计数信号量,初始值设置为init_count:
int rtos_get_semaphore_count( beken_semaphore_t* semaphore )
获取当前的信号量计数值:
int rtos_get_semaphore_count( beken_semaphore_t* semaphore )
释放信号量:
int rtos_set_semaphore( beken_semaphore_t* semaphore ) 支持在中断上下文或任务上下文使用
获取信号量:
bk_err_t rtos_get_semaphore( beken_semaphore_t* semaphore, uint32_t timeout_ms ) 仅支持在任务上下文使用 参数说明: -Semaphore: 信号量句柄 -timeout_ms: 超时时间,可配置为 0代表不超时 BEKEN_WAIT_FOREVER,代表一直超时阻塞 其他值,代表时间的超时时间 返回值: -kNoErr:信号量操作成功 -kGeneralErr或kTimeoutErr: 信号量操作失败删除一个已创建的信号量:
bk_err_t rtos_deinit_semaphore( beken_semaphore_t* semaphore )
互斥锁:
初始化一个互斥锁:
bk_err_t rtos_init_mutex( beken_mutex_t* mutex )
尝试获取一个互斥锁,超时时间为0:
bk_err_t rtos_trylock_mutex(beken_mutex_t *mutex)
无限等待获取一个互斥锁:
bk_err_t rtos_lock_mutex( beken_mutex_t* mutex )
释放一个互斥锁:
bk_err_t rtos_unlock_mutex( beken_mutex_t* mutex )
删除一个互斥锁:
bk_err_t rtos_deinit_mutex( beken_mutex_t* mutex )
初始化一个递归互斥锁:
bk_err_t rtos_init_recursive_mutex( beken_mutex_t* mutex )
获取一个递归互斥锁:
bk_err_t rtos_lock_recursive_mutex( beken_mutex_t* mutex )
释放一个递归互斥锁:
bk_err_t rtos_unlock_recursive_mutex( beken_mutex_t* mutex )
删除一个递归互斥锁:
bk_err_t rtos_deinit_recursive_mutex( beken_mutex_t* mutex )
软件定时器:
初始化一个单次软件定时器:
bk_err_t rtos_init_oneshot_timer( beken2_timer_t *timer, uint32_t time_ms, timer_2handler_t function, void* larg, void* rarg )
开启单次软件定时器:
bk_err_t rtos_start_oneshot_timer( beken2_timer_t* timer )
停止单次软件定时器:
bk_err_t rtos_stop_oneshot_timer( beken2_timer_t* timer )
复位单次软件定时器:
bk_err_t rtos_oneshot_reload_timer( beken2_timer_t* timer )
复位单次软件定时器,并重新设置定时时间与回调:
bk_err_t rtos_oneshot_reload_timer_ex(beken2_timer_t *timer, uint32_t time_ms, timer_2handler_t function, void *larg, void *rarg)
判断单次软件定时器是否初始化:
bool rtos_is_oneshot_timer_init( beken2_timer_t* timer )
判断单次软件定时器是否在运行:
bool rtos_is_oneshot_timer_running( beken2_timer_t* timer )
删除单次软件定时器:
bk_err_t rtos_deinit_oneshot_timer( beken2_timer_t* timer )
创建周期软件定时器:
bk_err_t rtos_init_timer( beken_timer_t *timer, uint32_t time_ms, timer_handler_t function, void* arg )
开启周期软件定时器:
bk_err_t rtos_start_timer( beken_timer_t* timer )
停止周期软件定时器:
bk_err_t rtos_stop_timer( beken_timer_t* timer )
复位周期软件定时器:
bk_err_t rtos_reload_timer( beken_timer_t* timer )
修改周期软件定时器定时时间:
bk_err_t rtos_change_period( beken_timer_t* timer, uint32_t time_ms)
删除周期软件定时器:
bk_err_t rtos_deinit_timer( beken_timer_t* timer )
获取周期软件定时器到期时间:
uint32_t rtos_get_timer_expiry_time( beken_timer_t* timer )
判断周期软件定时器是否初始化:
bool rtos_is_timer_init( beken_timer_t* timer )
判断周期软件定时器是否在运行:
bool rtos_is_timer_running( beken_timer_t* timer )
备注
软件定时器的精度与系统时钟节拍周期有关,如果配置的系统节拍数为1000,也就是节拍时钟为1ms。
软件定时器的回调函数中应快进快出,不允许使用任何可能引起软件定时器任务挂起或者阻塞的API接口,在回调函数中不能出现死循环。
事件:
创建事件:
bk_err_t rtos_init_event_flags( beken_event_t* event_flags )
等待事件标志:
beken_event_flags_t rtos_wait_for_event_flags( beken_event_t* event_flags, uint32_t flags_to_wait_for, beken_bool_t clear_set_flags, beken_event_flags_wait_option_t wait_option, uint32_t timeout_ms ) 参数说明: -event_flags:事件句柄 -flags_to_wait_for:一个按位或的值,指定需要等待事件组中的哪些位置1 -clear_set_flags:设置为pdTRUE时,当xEventGroupWaitBits()等待到满足任务唤醒的事件时,系统将清除由形参uxBitsToWaitFor 指定的事件标志位。 -wait_option:pdTRUE : flags_to_wait_for 指定的位都置位的时候,“逻辑与”等待事件,并且在没有超时的情况下返回对应的事件标志位的值。否则其中任意一个置位 的时候,这也是常说的“逻辑或”等待事件,在没有超时的情况下函数返回对应的事件标志位的值。 -timeout_ms:超时等待时间 返回值: -返回事件中的哪些事件标志位被置位,返回值很可能并不是用户指定的事件位,需要对返回值进行判断再处理。设置事件标志:
void rtos_set_event_flags( beken_event_t* event_flags, uint32_t flags_to_set ) 参数说明: -event_flags:事件句柄 -flags_to_set:指定事件中的事件标志位
设置事件标志:
beken_event_flags_t rtos_clear_event_flags( beken_event_t* event_flags, uint32_t flags_to_clear )
同步事件标志:
beken_event_flags_t rtos_sync_event_flags( beken_event_t* event_flags, uint32_t flags_to_set, uint32_t flags_to_wait_for, uint32_t timeout_ms) 原子地设置事件组中的位,然后等待同一事件组中的位组合被设置删除事件:
bk_err_t rtos_deinit_event_flags( beken_event_t* event_flags )
更多OS API信息,请参考: