ticc25411 nv的地址id怎么理解

德州仪器 (TI) 是一家跨国性的半导体设计与制造公司。因具有100,000+个以上模拟IC和嵌入式处理器而独树一帜、同时兼备软件、工具以及业界最大的销售团队/技术支持团队。
Texas Instruments Incorporated. 版权所有.本文档的目的是定义OS抽象层(OSAL)的API。这个API适用于TI协议栈软件组的产品,例如Z-堆栈(TM),RemoTI(TM)和BLE。
该文件列举了由OSAL提供的所有函数调用。详细地说明了所有函数调用,方便码农们快速调用。
API 应用程序接口
BLE 蓝牙低功耗
OSAL 操作系统(OS)抽象层
RF4CE 射频消费电子
RemoTI 德州仪器(TI)的RF4CE协议栈
Z-Stack Z-Stack德州仪器ZigBee协议栈
操作系统抽象层用来屏蔽指定TI栈软件组件的环境的细节处理。它以独立于处理环境的方式,包括以下的功能。
1.消息管理
2.任务同步
3.时间管理
4.中断管理
5.任务管理
6.内存管理
7.电源管理
8.非易失性闪存管理
9.简单的非易失性闪存管理
10.时钟管理
11.其他常用
消息管理API提供了一种机制用于交换具有不同处理环境的任务或处理元件之间的消息(例如,中断服务程序在一个控制环中被调用)。功能主要包括为任务分配消息缓存、释放消息缓存、接收消息和发送消息等API函数。
osal_msg_allocate()
这个函数通过被一个任务调用来分配消息缓冲区,该任务(函数)将填充到消息列表中并调用osal_msg_send()将消息发送给另一个任务。如果缓冲器不能分配出消息缓冲区的话,msg_ptr指针将被设置为NULL。
注意:不要搞混osal_mem_alloc(),这个函数是用来分配一个缓冲区,而任务之间发送消息使用osal_msg_send()。使用osal_mem_alloc()分配的是内存块。
函数原型:
uint8 * osal_msg_allocate( uint16 len )
osal_msg_hdr_t *
if ( len == 0 )
return ( NULL );
hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
if ( hdr )
hdr-&next = NULL;
hdr-&len = len;
hdr-&dest_id = TASK_NO_TASK;
return ( (uint8 *) (hdr + 1) );
return ( NULL );
参数:len消息的长度
返回值:返回分配一个指向消息缓冲区的指针,返回空代表分配消息缓冲区失败。
osal_msg_deallocate( )
此功能用于解除分配的消息缓冲器。这个功能是由一个任务(或处理元件)称为后处理完接收到的消息。
函数原型:
uint8 osal_msg_deallocate( uint8 *msg_ptr )
if ( msg_ptr == NULL )
return ( INVALID_MSG_POINTER );
if ( OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )
return ( MSG_BUFFER_NOT_AVAIL );
x = (uint8 *)((uint8 *)msg_ptr - sizeof( osal_msg_hdr_t ));
osal_mem_free( (void *)x );
return ( SUCCESS );
参数: msg_ptr指针是指向需要被解除分配的消息缓冲器。
返回值:msg_ptr指针是指向需要被解除分配的消息缓冲器。
INVALID_MSG_POINTER
无效的消息指针
MSG_BUFFER_NOT_AVAIL
缓冲区排队
osal_msg_send( )
所述osal_msg_send函数通过被一个任务调用发送一个命令或数据消息到另一任务或处理元件。该destination_task标识符字段必须指向一个有效的系统任务。osal_msg_send()函数同样也设置目标任务事件列表中的SYS_EVENT_MSG事件。
uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )
return ( osal_msg_enqueue_push( destination_task, msg_ptr, FALSE ) );
destination_task是任务的ID来接收该消息。
msg_ptr是指向包含消息的缓冲器。Msg_ptr必须是一个指针()通过osal_msg_allocate分配的一个有效的消息缓冲区。
返回值是1字节字段,指示该操作的结果。
INVALID_MSG_POINTER
无效的消息指针
MSG_BUFFER_NOT_AVAIL
缓冲区排队
osal_msg_receive( )
该功能称为由任务来检索接收的命令消息。使用osal_msg_deallocate()调用处理消息后,调用任务必须取消分配的消息缓冲区。
uint8 *osal_msg_receive( uint8 task_id )
osal_msg_hdr_t *listH
osal_msg_hdr_t *prevHdr = NULL;
osal_msg_hdr_t *foundHdr = NULL;
halIntState_t
// Hold off interrupts
HAL_ENTER_CRITICAL_SECTION(intState);
// Point to the top of the queue
listHdr = osal_qH
// Look through the queue for a message that belongs to the asking task
while ( listHdr != NULL )
if ( (listHdr - 1)-&dest_id == task_id )
if ( foundHdr == NULL )
// Save the first one
foundHdr = listHdr;
// Second msg found, stop looking
if ( foundHdr == NULL )
prevHdr = listHdr;
listHdr = OSAL_MSG_NEXT( listHdr );
// Is there more than one?
if ( listHdr != NULL )
// Yes, Signal the task that a message is waiting
osal_set_event( task_id, SYS_EVENT_MSG );
// No more
osal_clear_event( task_id, SYS_EVENT_MSG );
// Did we find a message?
if ( foundHdr != NULL )
// Take out of the link list
osal_msg_extract( &osal_qHead, foundHdr, prevHdr );
// Release interrupts
HAL_EXIT_CRITICAL_SECTION(intState);
return ( (uint8*) foundHdr );
TASK_ID是调用任务(该消息注定)的标识。
返回值是一个指针,指向包含该消息或NULL,如果没有接收到的消息的缓冲器。
osal_msg_find( )
此功能搜索现有的OSAL信息匹配TASK_ID和事件的参数。
osal_event_hdr_t *osal_msg_find(uint8 task_id, uint8 event)
osal_msg_hdr_t *pH
halIntState_t intS
HAL_ENTER_CRITICAL_SECTION(intState);
// Hold off interrupts.
pHdr = osal_qH
// Point to the top of the queue.
// Look through the queue for a message that matches the task_id and event parameters.
while (pHdr != NULL)
if (((pHdr-1)-&dest_id == task_id) && (((osal_event_hdr_t *)pHdr)-&event == event))
pHdr = OSAL_MSG_NEXT(pHdr);
HAL_EXIT_CRITICAL_SECTION(intState);
// Release interrupts.
return (osal_event_hdr_t *)pHdr;
TASK_ID是标识符的入队OSAL信息必须匹配。
事件是OSAL事件ID的入队OSAL信息必须匹配。
返回值是一个指向上的成功或NULL失败匹配的OSAL信息。
此API允许一个任务等待事件处理,再进行返回控制。该API中的函数可以被用来设置为任务的事件,并通知任务一旦任何事件被设置。
osal_set_event()
这个函数被调用来设置事件标志的任务。
uint8 osal_set_event( uint8 task_id, uint16 event_flag )
if ( task_id & tasksCnt )
halIntState_t
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[task_id] |= event_
HAL_EXIT_CRITICAL_SECTION(intState);
return ( SUCCESS );
return ( INVALID_TASK );
TASK_ID是该事件是要设置的任务的标识符。
event_flag是一个2字节的比特映射表,每个比特指定一个事件。只有一个系统事件(SYS_EVENT_MSG),事件的其余/位由接收任务定义。
返回值指示该操作的结果。
INVALID_TASK
无效的任务
该API允许通过内部(TI堆栈)的任务和外部的(应用层)任务使用定时器。该API提供的功能来启动和停止计时器。该定时器可在1millisecond的增量进行设置。
这个函数被调用,以启动一个定时器。当计时器到期时,给定的事件位将被设置。本次活动将针对TaskID定义任务设置。该定时器是一个单次定时器,这意味着当定时器期满它不重新加载。
uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint32 timeout_value )
halIntState_t intS
osalTimerRec_t *newT
HAL_ENTER_CRITICAL_SECTION( intState );
newTimer = osalAddTimer( taskID, event_id, timeout_value );
HAL_EXIT_CRITICAL_SECTION( intState );
return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
TaskID: 当定时器到期时,获得该事件的任务的任务ID。
EVENT_ID: 是用户定义的事件比特位。当定时器到期时,被调用的任务将被通知(事件)。
timeout_value: 是时间的量(以毫秒为单位)的计时器事件被设置之前。
NO_TIMER_AVAIL
无法启动定时器
设置一个定时时间,定时时间到后,相应任务的相应事件被设置,这一点跟“osal_start_timerEx()”功能一样,但是本接口还多了一个功能:就是定时时间到后相应事件被执行,并重新加载定时器,也就是又重新设置了定时器,继续进行定时工作,除非调用“osal_stop_timerEx()”接口,否则一直循环定时操作。
uint8 osal_start_reload_timer( uint8 taskID, uint16 event_id, uint32 timeout_value )
halIntState_t intS
osalTimerRec_t *newT
HAL_ENTER_CRITICAL_SECTION( intState );
newTimer = osalAddTimer( taskID, event_id, timeout_value );
if ( newTimer )
newTimer-&reloadTimeout = timeout_
HAL_EXIT_CRITICAL_SECTION( intState );
return ( (newTimer != NULL) ? SUCCESS : NO_TIMER_AVAIL );
TaskID:当定时器到期时,获得该事件的任务的任务ID。
EVENT_ID:是用户定义的事件比特位。当定时器到期时,被调用的任务将被通知(事件)。
timeout_value:是时间的量(以毫秒为单位)的计时器事件被设置之前。此值加载到定时器,当定时器超时。
返回值指示该操作的结果。
NO_TIMER_AVAIL
无法启动定时器
这个函数被调用来停止已启动的计时器。如果成功,该函数将取消定时器,并防止与计时器相关联的事件。
uint8 osal_stop_timerEx( uint8 task_id, uint16 event_id )
halIntState_t intS
osalTimerRec_t *foundT
HAL_ENTER_CRITICAL_SECTION( intState );
foundTimer = osalFindTimer( task_id, event_id );
if ( foundTimer )
osalDeleteTimer( foundTimer );
HAL_EXIT_CRITICAL_SECTION( intState );
return ( (foundTimer != NULL) ? SUCCESS : INVALID_EVENT_ID );
task_ID是要为其停止定时器的任务。
event_id的是要被停止的定时器的标识符。
返回值指示该操作的结果。
NO_TIMER_AVAIL
无法启动定时器
osal_GetSystemClock()
这个函数被调用,以读取系统时钟
uint32 osal_GetSystemClock( void )
return ( osal_systemClock );
参数 无参数
返回值 无返回值
这部分的API可以控制一个任务以外部中断的方式交互。 API中的函数允许一个任务到一个特定的服务程序与每个中断相关联。中断可以启用或禁用。里面的服务程序,事件可能会被用于其他任务设置。
osal_int_enable
这个函数被调用,以允许中断。一旦启用,中断相关的服务程序被调用发生中断。
uint8 osal_int_enable( uint8 interrupt_id )
if ( interrupt_id == INTS_ALL )
HAL_ENABLE_INTERRUPTS();
return ( SUCCESS );
return ( INVALID_INTERRUPT_ID );
interrupt_id标识要启用中断。
返回值指示该操作的结果。
INVALID_INTERRUPT_ID
osal_int_disable()
这个函数被调用来禁止中断。当禁用中断时,与该中断相关的服务例程不被调用
uint8 osal_int_disable( uint8 interrupt_id )
if ( interrupt_id == INTS_ALL )
HAL_DISABLE_INTERRUPTS();
return ( SUCCESS );
return ( INVALID_INTERRUPT_ID );
interrupt_id标识要禁用中断。
返回值指示该操作的结果。
INVALID_INTERRUPT_ID
这部分API是用来添加和管理在OSAL系统层的任务。每个任务是由一个初始化函数和一个事件处理函数组成。OSAL调用osalInitTasks()提供的应用程序初始化任务,OSAL使用任务表(const的pTaskEventHandlerFn tasksArr []),呼吁每个任务(也提供应用程序)的事件处理器。
任务列表实例:
const pTaskEventHandlerFn tasksArr[] =
LL_ProcessEvent,
Hal_ProcessEvent,
HCI_ProcessEvent,
#if defined ( OSAL_CBTIMER_NUM_TASKS )
OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),
L2CAP_ProcessEvent,
GAP_ProcessEvent,
GATT_ProcessEvent,
SM_ProcessEvent,
GAPRole_ProcessEvent,
GAPBondMgr_ProcessEvent,
GATTServApp_ProcessEvent,
HeartRate_ProcessEvent
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0]);
任务列表初始化实例
void osalInitTasks( void )
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
LL_Init( taskID++ );
Hal_Init( taskID++ );
HCI_Init( taskID++ );
#if defined ( OSAL_CBTIMER_NUM_TASKS )
osal_CbTimerInit( taskID );
taskID += OSAL_CBTIMER_NUM_TASKS;
L2CAP_Init( taskID++ );
GAP_Init( taskID++ );
GATT_Init( taskID++ );
SM_Init( taskID++ );
GAPRole_Init( taskID++ );
GAPBondMgr_Init( taskID++ );
GATTServApp_Init( taskID++ );
HeartRate_Init( taskID );
osal_init_system()
初始化OSAL,该函数是第一个被调用的OSAL函数。
uint8 osal_init_system( void )
osal_mem_init();
osal_qHead = NULL;
osalTimerInit();
osal_pwrmgr_init();
osalInitTasks();
osal_mem_kick();
return ( SUCCESS );
参数: NULL
返回值指示该操作的结果。
osal_start_system
该函数包含一个无限循环,反复调用执行osal_run_system()函数。此函数没有返回值。
void osal_start_system( void )
#if !defined ( ZBIT ) && !defined ( UBIT )
osal_run_system();
参数: NULL
返回值: NULL
osal_run_system
查询所有的任务事件,如果有事件发生,则调用相应的事件处理函数,处理完该事件后将没有处理的事件返回,到主循环中继续检测是否有事件发生,如果开启了休眠模式,则没有事件发生时,该函数将使处理器进入休眠模式,以降低系统功耗。
void osal_run_system( void )
uint8 idx = 0;
#if defined (WDT_USED)
WD_KICK();
#ifndef HAL_BOARD_CC2538
osalTimeUpdate();
Hal_ProcessPoll();
if (tasksEvents[idx])
} while (++idx & tasksCnt);
if (idx & tasksCnt)
halIntState_t intS
HAL_ENTER_CRITICAL_SECTION(intState);
events = tasksEvents[idx];
tasksEvents[idx] = 0;
HAL_EXIT_CRITICAL_SECTION(intState);
activeTaskID =
events = (tasksArr[idx])( idx, events );
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |=
HAL_EXIT_CRITICAL_SECTION(intState);
#if defined( POWER_SAVING )
osal_pwrmgr_powerconserve();
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
osal_task_yield();
返回值 NULL
osal_self( )
返回当前正在执行事件处理的任务的ID,如果没有,则返回TASK_NO_TASK。
uint8 osal_self( void )
return ( activeTaskID );
返回当前有效OSAL任务的ID。
有效OSAL任务的ID
0xFF(TASK_NO_TASK)
无有效的OSAL任务的ID
此部分的API提供了简单的内存分配系统。这部分允许动态的进行内存分配。
osal_mem_alloc()
在堆上分配指定大小的缓冲区。这里需要注意一定要与函数 osal_mem_free( )要成对使用,防止产生内存泄露。
#define osal_mem_alloc(_size ) osal_mem_alloc_dbg(_size, __FILE__, __LINE__)
想要分配的buffer的大小。
一个void型的指针指向分配buffer的首地址(应该强转成指定的类型)。如果没有足够的内存可以分配的话,返回值NULL空指针。
osal_mem_free()
释放使用osal_mem_alloc()分配的缓冲区。
#define osal_mem_free(_ptr ) osal_mem_free_dbg(_ptr, __FILE__, __LINE__)
_ptr - 指向osal_mem_alloc分配的缓冲区被释放。
返回值 NULL
该部分描述了OSAL的电源管理系统。该系统提供了为应用程序/任务通知OSAL何时可以安全关闭接收器和外部硬件,并使处理器进入睡眠模式的方式。
一共有两个函数控制电源管理。第一个函数,osal_pwrmgr_device()用来设置设备的level模式(有低功耗功能和无低功耗功能)。第二个函数,任务的功耗状态,osal_pwrmgr_task_state(PWRMGR_HOLD),不允许该任务进入低功耗功能,osal_pwrmgr_task_state(PWRMGR_CONSERVE),允许该任务进入低功耗功能。
默认状态下,当所有的任务被初始化,初始化的任务状态是PWRMGR_CONSERVE,如果一个任务不想要功耗保护(维持不变)就不需要调用osal_pwrmgr_task_state()。
此外,在默认情况下,电池供电的设备将在PWRMGR_ALWAYS_ON状态,直到它加入了系统进程中,那么这将改变其状态PWRMGR_BATTERY。这意味着,如果设备无法找到设备的加入也不会进入节电状态。如果你想改变这种行为,在应用程序的任务初始化函数中添加osal_pwrmgr_device(PWRMGR_BATTERY),或者当您的应用程序停止/暂停连接过程。
在进入电源保护状态时,电源管理器监听设备状态和电源状态
osal_pwrmgr_init
此功能将初始化所使用的电源管理系统的变量。重要提示:不要调用这个函数,它已经称为osal_init_system()。
void osal_pwrmgr_init( void )
pwrmgr_attribute.pwrmgr_device = PWRMGR_ALWAYS_ON;
pwrmgr_attribute.pwrmgr_task_state = 0;
返回值 NULL
osal_pwrmgr_powerconserve()
这个函数被调用来进入掉电模式。重要提示:不需要调用此函数,因为此函数已经在osal_start_system()循环中被调用了。
void osal_pwrmgr_powerconserve( void )
halIntState_t intS
if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON )
if ( pwrmgr_attribute.pwrmgr_task_state == 0 )
HAL_ENTER_CRITICAL_SECTION( intState );
next = osal_next_timeout();
HAL_EXIT_CRITICAL_SECTION( intState );
OSAL_SET_CPU_INTO_SLEEP( next );
返回值 NULL
osal_pwrmgr_device()
设置电源管理的特性方式,主要有两种方式:“PWRMGR_ALWAYS_ON”和“PWRMGR_BATTERY”。如果是“PWRMGR_ALWAYS_ON”方式,电源持续供电,不会进入休眠模式;如果是“PWRMGR_BATTERY”方式,系统将在没有事件要处理的时候进入休眠模式,降低功耗。
void osal_pwrmgr_device( uint8 pwrmgr_device )
pwrmgr_attribute.pwrmgr_device = pwrmgr_
pwrmgr_device :改变或设置power savings模式。
PWRMGR_ALWAYS_ON
关闭PowerSaving功能,系统一直运行
PWRMGR_BATTERY
打开PowerSaving功能
返回值 NULL
osal_pwrmgr_task_state
该函数是用来表示该任务是否想要进入低功耗。
uint8 osal_pwrmgr_task_state( uint8 task_id, uint8 state )
if ( task_id &= tasksCnt )
return ( INVALID_TASK );
if ( state == PWRMGR_CONSERVE )
pwrmgr_attribute.pwrmgr_task_state &= ~(1 && task_id );
pwrmgr_attribute.pwrmgr_task_state |= (1 && task_id);
return ( SUCCESS );
PWRMGR_CONSERVE
所有的PowerSaving打开,必须所有task同意。
PWRMGR_HOLD
关闭PowerSaving功能
返回操作结果
INVALID_TASK
无效的任务
非易失性闪存管理
这部分描述了OSAL非易失性内存系统。该系统提供了一套为应用程序把所有的信息永久的保存到设备内存中。适用于由堆栈对ZigBee所规范的某些项目的持久存储。NV函数的读写适用于用户自定义的任意类型的结构体和数组。用户可以通过适当的偏移或者长度读写整个item的或者item的某一个部分。该API是独立于NV存储的介质,可以被应用到善存或者E2PROM。
每一个NV的item有一个独立的ID。应用程序有特定的ID值范围,一些ID值被预留给栈或平台使用。如果你的应用程序创建自己的NV项目时,必须选择从应用程序的价值范围内的ID。请参阅下表:
Commissioning SAS
0x00E1–0x0100
Trust Center Link Keys
ZigBee-Pro: APS Links Key ZigBee-RF4CE: network layer
ZigBee-Pro: Master Keys ZigBee-RF4CE: app framework
0x0401 – 0x0FFF
0x0401 – 0x0FFF
0x1000 -0xFFFF
0x1000 -0xFFFF
注意事项:
1.这些堵塞函数的调用以及一个操作可能需要数十毫秒才能完成。NV写操作尤其如此。所以,中断可能被禁止了几个毫秒。最好是在时间执行这些功能时,他们不与其他时序关键的操作发生冲突。举例,一个好的时间去写NV的items在接收器被关闭。
2.尽量少进行NV的写操作。它既花时间有耗功耗。所以说大多数的flash设备都有有限的擦写次数。
3.如果NV的items有一个或者多个结构体发生改变,尤其是TI的软件的协议栈的版本更新到另一个,所以有必要擦除或者重新初始化NV内存。否则的话,NV的items发生改变会导致读写操作在发生错误或者产生错误的结果。
osal_nv_item_init()
初始化NV项目。此功能检查中的某个项目NV的存在。如果它不存在,则创建并用,传递给函数的数据。
该功能必须在调用osal_nv_read()或osal_nv_write()之前被调用。
uint8 osal_nv_item_init( uint16 id, uint16 len, void *buf );
id:用户定义的item 的ID
len:item的字节长度
*buf:指针指向item初始化的数据。如果没有初始化,设置为NULL。
返回操作的结果
NV_ITEM_UNINIT
成功,但是item不存在
NV_OPER_FAILED
osal_nv_read()
阅读来自NV的数据。这个函数可用于通过索引入项目具有偏移来读取从NV整个项目或项目的一个元素。读取数据复制到* buf中。
uint8 osal_nv_read( uint16 id, uint16 offset, uint16 len, void *buf );
id:用户定义的item的id
offset:内存在item中字节偏移量
len:item的字节长度
*buf:数据会被读到buf中
返回操作的结果
NV_OPER_FAILED
osal_nv_write()
将数据写入NV。这个函数可用于通过索引入项目具有偏移来写整个项NV或一个项目的一个元素。
uint8 osal_nv_write( uint16 id, uint16 offset, uint16 len, void *buf );
id:用户定义的item的id
offset:内存在item中字节偏移量
len:item的字节长度
*buf:需要被写的数据
返回操作的结果
NV_ITEM_UNINIT
item没有被初始化
NV_OPER_FAILED
osal_nv_delete()
从NV中删除某个item。此函数会检测NV的存在。如果items存在以及它的长度匹配的长度提供了功能的调用,该item就是从NV中删除。
uint8 osal_nv_delete( uint16 id, uint16 len );
id:用户定义的item的id
len:item的字节长度
返回操作的结果
NV_ITEM_UNINIT
item没有被初始化
NV_BAD_ITEM_LEN
不正确长度的参数
NV_OPER_FAILED
osal_nv_item_len()
获取NV项目的长度。如果有这个函数返回一个NV项目的长度,否则返回零。
uint16 osal_nv_item_len( uint16 id );
id: 用户定义的item的ID
返回操作的结果
NV item没有被发现
NV item的长度
osal_offsetof()
该宏计算存储器中的结构中的一个元素的字节偏移。它可以用于计算所使用的NV API函数的偏移参数。
#define osal_offsetof(type, member) ((uint16) &(((type *) 0)-&member))
type :结构体类型
member:结构体的长度
返回值 NULL
简单的易挥发性内存的API
本节介绍OSAL简单的非挥发性内存系统。像OSAL NV存储器系统,简单NV存储系统提供了一种方法,应用到持久存储信息到设备内存。另一方面,在OSAL NV存储器系统不同,简单NV存储器系统提供更简单的API来驱动应用程序代码大小和堆栈代码大小向下以及OSAL简单的NV系统实现的代码大小。用户可以读或写整个项目,但它不能部分读取或写入的项目。
就像NV存储器系统,每个NV项具有一个唯一的ID。有特定的ID值范围为应用程序,同时一些ID值预留或使用的栈或平台。如果你的应用程序创建自己的NV项目,它必须选择从应用程序的价值范围内的ID。请参阅下表:
0x01–0x6F
Reserved for ZigBee RF4CE network layer
0x70–0x7F
Reserved for ZigBee RF4CE application framework (RTI)
0x80 – 0xFE
Application
1.这些堵塞函数的调用以及一个操作可能需要数十毫秒才能完成。NV写操作尤其如此。所以,中断可能被禁止了几个毫秒。最好是在时间执行这些功能时,他们不与其他时序关键的操作发生冲突。举例,一个好的时间去写NV的items在接收器被关闭。
2.此外,这些函数不可以在中断服务程序中调用。
3.量少进行NV的写操作。它既花时间有耗功耗。所以说大多数的flash设备都有有限的擦写次数。
4如果NV的items有一个或者多个结构体发生改变,尤其是TI的软件的协议栈的版本更新到另一个,所以有必要擦除或者重新初始化NV内存。否则的话,NV的items发生改变会导致读写操作在发生错误或者产生错误的结果。
osal_snv_read()
读来自NV的数据。此功能可被用于读取来自NV整个item。读取的数据被复制到*pbuf。
uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void *pBuf )
uint16 offset = findItem(activePg, pgOff, id);
if (offset != 0)
HalFlashRead(activePg, offset, pBuf, len);
return SUCCESS;
return NV_OPER_FAILED;
id:用户定义的item的id
offset:内存在item中字节偏移量
len:item的字节长度
*buf:数据会被读到buf中
返回操作结果。
NV_OPER_FAILED
osal_snv_write()
将数据写入NV。该功能可用于编写整个项目NV。
uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void *pBuf )
uint16 alignedL
uint16 offset = findItem(activePg, pgOff, id);
if (offset & 0)
osalSnvLen_
for (i = 0; i & len; i++)
HalFlashRead(activePg, offset, &tmp, 1);
if (tmp != ((uint8 *)pBuf)[i])
if (i == len)
return SUCCESS;
alignedLen = ((len + OSAL_NV_WORD_SIZE - 1) / OSAL_NV_WORD_SIZE) * OSAL_NV_WORD_SIZE;
if ( pgOff + alignedLen + OSAL_NV_WORD_SIZE & OSAL_NV_PAGE_SIZE )
setXferPage();
compactPage(activePg);
writeItem(activePg, pgOff, id, alignedLen, pBuf);
if (failF)
return NV_OPER_FAILED;
pgOff += alignedLen + OSAL_NV_WORD_SIZE;
return SUCCESS;
id:用户定义的item的id
len:item的字节长度
*buf:需要被写的数据
返回操作结果。
NV_OPER_FAILED
本节介绍了OSAL时钟系统。该系统提供了一种方法,按照日期和时间的格式。该系统将保留的秒数,从秒日0时0分0秒。以下两种数据类型/结构被用于在该系统中(在OSAL_Clock.h定义):
typedef uint32 UTCT
typedef struct
} UTCTimeS
您必须启用OSAL_CLOCK编译器标志使用此功能。另外,此功能在睡眠状态不能够维持。
更新系统时钟。
void osalTimeUpdate( void )
uint16 ticks625
uint16 elapsedMSec = 0;
// Get the free-running count of 625us timer ticks
tmp = ll_McuPrecisionCount();
if ( tmp != previousLLTimerTick )
// Calculate the elapsed ticks of the free-running timer.
ticks625us = tmp - previousLLTimerT
// Store the LL Timer tick count for the next time through this function.
previousLLTimerTick =
/* It is necessary to loop to convert the usecs to msecs in increments so as
* not to overflow the 16-bit variables.
while ( ticks625us & MAXCALCTICKS )
ticks625us -= MAXCALCTICKS;
elapsedMSec += MAXCALCTICKS * 5 / 8;
remUsTicks += MAXCALCTICKS * 5 % 8;
// update converted number with remaining ticks from loop and the
// accumulated remainder from loop
tmp = (ticks625us * 5) + remUsT
// Convert the 625 us ticks into milliseconds and a remainder
elapsedMSec += tmp / 8;
remUsTicks = tmp % 8;
// Update OSAL Clock and Timers
if ( elapsedMSec )
osalClockUpdate( elapsedMSec );
osalTimerUpdate( elapsedMSec );
osal_setClock()
调用此函数初始化设备的时间。
void osal_setClock( UTCTime newTime )
OSAL_timeSeconds = newT
newTime:从0小时0分0秒,于日UTC以秒为单位的新时间
返回值 NULL
osal_getClock()
调用此函数来获取设备的当前时间。
UTCTime osal_getClock( void )
return ( OSAL_timeSeconds );
当前时间,以秒为单位自零小时,0分0秒,于日UTC。
调用此函数UTCTime转换为UTCTimeStruct。
void osal_ConvertUTCTime( UTCTimeStruct *tm, UTCTime secTime )
uint32 day = secTime % DAY;
tm-&seconds = day % 60UL;
tm-&minutes = (day % 3600UL) / 60UL;
tm-&hour = day / 3600UL;
uint16 numDays = secTime / DAY;
tm-&year = BEGYEAR;
while ( numDays &= YearLength( tm-&year ) )
numDays -= YearLength( tm-&year );
tm-&year++;
tm-&month = 0;
while ( numDays &= monthLength( IsLeapYear( tm-&year ), tm-&month ) )
numDays -= monthLength( IsLeapYear( tm-&year ), tm-&month );
tm-&month++;
tm-&day = numD
*tm:UTCTimeStruct结构体
secTime:UTCTime时间
返回值 NULL
osal_ConvertUTCSecs()
调用此函数UTCTimeStruct转换为UTCTime。
UTCTime osal_ConvertUTCSecs( UTCTimeStruct *tm )
/* Seconds for the partial day */
seconds = (((tm-&hour * 60UL) + tm-&minutes) * 60UL) + tm-&
/* Account for previous complete days */
/* Start with complete days in current month */
uint16 days = tm-&day;
/* Next, complete months in current year */
int8 month = tm-&month;
while ( --month &= 0 )
days += monthLength( IsLeapYear( tm-&year ), month );
/* Next, complete years before current year */
uint16 year = tm-&year;
while ( --year &= BEGYEAR )
days += YearLength( year );
/* Add total seconds before partial day */
seconds += (days * DAY);
return ( seconds );
*tm :UTCTimeStruct的指针
返回UTCTime秒值。
本节介绍不适合以前的OSAL分类杂项OSAL功能
osal_rand()
此函数返回一个16位的随机数。
uint16 osal_rand( void )
return ( Onboard_rand() );
返回一个随机数。
osal_memcmp()
比较内存部分。
uint8 osal_memcmp( const void GENERIC *src1, const void GENERIC *src2, unsigned int len )
const uint8 GENERIC *pSrc1;
const uint8 GENERIC *pSrc2;
pSrc1 = src1;
pSrc2 = src2;
while ( len-- )
if( *pSrc1++ != *pSrc2++ )
return FALSE;
return TRUE;
src1: 内存比较位置1。
src2 : 内存比较位置2。
len: 比较长度。
返回比较结果
osal_memset()
设置一个缓冲器为特定值。
void *osal_memset( void *dest, uint8 value, int len )
return memset( dest, value, len );
*dest:内存地址
value : 设置的值
返回设置到的停止的位置的地址。
osal_memcpy()
复制一个缓冲到另一个缓冲区。
void *osal_memcpy( void *dst, const void GENERIC *src, unsigned int len )
const uint8 GENERIC *pS
while ( len-- )
*pDst++ = *pSrc++;
return ( pDst );
dst - 目标缓冲区。
src - 原缓冲区。
len - 长度。
指针最终的目标缓冲区。
OSAL(操作系统抽象层)API解读
ZigBee学习之7——OSAL(操作系统抽象层)API解读
ZigBee学习 |
|字号大中...
CC2540/CC2541/CC254x之OSAL操作系统抽象层
本文主要介绍CC2541/CC2540/CC254x系列芯片的操作系统抽象层OSAL的有关内容
CC2541 OSAL工作原理
蓝牙为了实现同多个设备相连,或实现多功能,也实现了功能扩充,这就产生了调度问题。因为,虽然软件和协议栈可扩充,但终究最底层的执行部门只有一个。为了实现多事件和多任务切换,需要把事件和任务对应的应用,并...
TI BLE CC2541 关于Notification的设置及应用
注:本文的主要目的是为了记录自己的学习过程,也方便与大家做交流。转载请注明来自:
http://blog.csdn.net/ab198604
一、修改从机端代码(Ser...
操作系统抽象层_一种支持跨平台的新技术
http://www.cnki.com.cn/Article/CJFDTotal-JSJC.htm
为了使开发的应用支持多平台,提出了一个新的概念和技术:操作系统抽象层。阐述了操作...
OSAL函数分析-osal_start_reload_timer,osalAddTimer,osalFindTimer
/*********************************************************************
osalAddTimer
Z-Stack中OSAL定时器事件触发流程分析---转载
写在前面:之所以会注意到定时器事件是因为在做断点调试的时候会进入osal_start_timerEx这个函数,而且这个函数之后还会涉及到hal_uartpoll有关DMA之类的函数,于是发现了这篇文章...
浅析CC2540的OSAL原理
原文链接一、概述  OSAL (Operating System Abstraction Layer),翻译为“操作系统抽象层”。OSAL就是一种支持多任务运行的系统资源分配机制。OSAL与标准的操作...
OSAL操作系统实验学习笔记01
从uCOUS-II 接触操作系统后,了解了操作系统的基本概念和工作流程后开始接触OSAL系统,首先操作系统的工作流程如下图暂时不提这个系统,来分析OSAL系统.
这里提到一个Source Isigh...
【BLE】CC2541之SNV
本文以SimpleBLEPeripheral工程为例,介绍SNV的使用
没有更多推荐了,}

我要回帖

更多关于 ticc2541 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信