//----添加根节点---------------------------------------------------------------- //功能: 在资源链中添加一棵树的根节点 //参数: Obj,新添加的节点指针 // Size,新节点连负载的尺寸,字节数 // RscType, 资源类型,用于区分不同资源,原则上,资源的数据结构不同,类型就不同 // Name,资源名字,所指向的字符串内存区不能是局部变量,可以是空 //返回: 新加入的节点 //备注: 修改逻辑,将原来挂载到根下的组建(/dev分支除外),全部接入新建的/SYS下 //------------------------------------------------------------------------------ struct Object *OBJ_AddTree(struct Object *Obj, u16 Size, u16 RscType, const char *Name) { struct Object *root_node; atom_low_t low_atom; if(Obj == NULL) return NULL; if(OBJ_SearchTree(Name) != NULL) return NULL; Obj->Parent = s_ptRscRoot; Obj->Child=NULL; Obj->Size = Size; Obj->Type = RscType; Obj->Name = (char *)Name; low_atom = Int_LowAtomStart(); //资源队列中至少存在一个信号量节点,无须判断是否空 root_node = s_ptRscRoot->Child; Obj->Next = root_node; Obj->Previous = root_node->Previous; root_node->Previous->Next = Obj; root_node->Previous = Obj; Int_LowAtomEnd(low_atom); return Obj; }
//----替换节点----------------------------------------------------------------- //功能: 用一个新节点替换掉资源队列中的原有节点,新节点原来必须不是队列中的节点 //参数: Old,被替换的节点 // New,新节点 //返回: 无 //----------------------------------------------------------------------------- bool_t OBJ_Displace(struct Object *Old, struct Object *New) { struct Object *temp1, *temp2; atom_low_t low_atom; if((NULL == Old) || (NULL == New)) return FALSE; low_atom = Int_LowAtomStart(); temp1 = Old->Child; if(temp1 != NULL) //把oldnode所有子节点的父指针指向newnode { temp2 = temp1; do { temp2->Parent = New; temp2 = temp2->Next; }while(temp2 != temp1); } New->Child = temp1; New->Next = Old->Next; New->Previous = Old->Previous; New->Parent = Old->Parent; Old->Next->Previous = New; Old->Previous->Next = New; if(Old->Parent->Child == Old) //如果是队列头节点 Old->Parent->Child = New; //父节点的子节点指向队列头节点 Int_LowAtomEnd(low_atom); return TRUE; }
//----CAN接收函数------------------------------------- //功能: CAN发送函数 //参数: // byChip: CAN控制器选择 0~4(为兼容项目组代码,保留此参数,在SR5333中该参数 // 为0,SR5333 V1.01版本中只使用了一个CAN控制器) // txBuf: 报文的接收缓冲区 // len: 请求读取的长度 // pRd: 缓冲区读指针 //返回: 成功读取数据的长度 //----------------------------------------------------------------------------- uint32_t CAN_ReadData(uint8_t byChip, uint8_t* rxBuf, uint32_t len, uint32_t *pRd) { uint32_t rdLen=0x0000,ringlen,pkgnum,r_len; CAN_DevCtrl *CAN_DevCtrlTempptr=NULL; struct RingBuf *rxRingBuf=NULL; atom_low_t atom; //先作参数检查 if(rxBuf==NULL) return 0; if(byChip>=2) return 0; CAN_DevCtrlTempptr=CAN_DevCtrlPtr+byChip; rxRingBuf=CAN_DevCtrlTempptr->RcvRing; atom = Int_LowAtomStart(); ringlen=Ring_Check(rxRingBuf); Int_LowAtomEnd(atom); if(len>ringlen) { r_len=ringlen; } else { r_len=len; } rdLen=Ring_Read(rxRingBuf,rxBuf,r_len); pkgnum=rdLen/13; gs_u64AppRcvCnt[byChip]+=pkgnum; return rdLen; }
// ============================================================================= // 函数功能:__GPTimer_Free // 释放定时器 // 输入参数:timer,分配的定时器 // 输出参数: // 返回值 :true成功false失败 // 说明 : // ============================================================================= bool_t __GPTimer_Free(ptu32_t timerhandle) { u8 timerno; u8 irqline; atom_low_t timeratom; //保护公用资源 struct tagGPTimerHandle *timer; timer = (struct tagGPTimerHandle *)timerhandle; if(timer->timerstate & CN_TIMER_ENUSE) { timerno = timer->timerno; irqline = timer->irqline; if(timerno < CN_GP_TIMER_NUM )//还有空闲的,则设置标志位 { //修改全局标志一定是原子性的 timeratom = Int_LowAtomStart(); //解除掉中断所关联的内容 timer->timerstate = 0; Int_CutLine(irqline); Int_IsrDisConnect(irqline); Int_EvttDisConnect(irqline); Int_LowAtomEnd(timeratom); //原子操作完毕 return true; } else//没有的话直接返回就可以了,用不着再啰嗦了 { return false; } } else { return false; } }
//----移动节点到最后--------------------------------------------------------- //功能: 朝next指针方向移动资源队列中的一个节点,到同级队列头的前一个节点位置 //参数: Obj,被移动的节点指针 //返回: 无 //----------------------------------------------------------------------------- bool_t OBJ_MoveToLast(struct Object *Obj) { struct Object *eldest; atom_low_t low_atom; if(Obj == NULL) return FALSE; low_atom = Int_LowAtomStart(); if(Obj->Parent != NULL) //根节点不能移动 { eldest = Obj->Parent->Child; if(eldest == Obj) //如果node是头节点,则直接移动父节点的子指针到下一个节点就可以了. Obj->Parent->Child = Obj->Next; //以下从链表中取出节点 Obj->Next->Previous = Obj->Previous; Obj->Previous->Next = Obj->Next; //以下把node插入队列尾位置,由于是循环链表,头节点的前面就是尾节点. Obj->Next = eldest; Obj->Previous = eldest->Previous; eldest->Previous->Next = Obj; eldest->Previous = Obj; } Int_LowAtomEnd(low_atom); return TRUE; }
// ============================================================================= // 函数功能:复位看门狗 // 输入参数:wdt,待操作的看门狗 // 输出参数: // 返回值 :true success while false failed // 说明 : // ============================================================================= bool_t Wdt_Clean(tagWdt *wdt) { bool_t result; tagWdtMsg wdtmsg; atom_low_t atom; s64 ostime; result = false; if(NULL != wdt) { atom = Int_LowAtomStart(); if(ptWdtHead != wdt) { //可以直接修改wdtqueue ostime = DjyGetTime(); __Wdt_RemovefQueue(wdt); wdt->deadtime = wdt->cycle + ostime; __Wdt_Add2Queque(wdt); Int_LowAtomEnd(atom); } else { //snd msg to the monitor task Int_LowAtomEnd(atom); wdtmsg.pwdt = wdt; wdtmsg.opcode = EN_WDTCMD_CLEAN; wdtmsg.para = 0; result = MsgQ_Send(ptWdtMsgBox,(u8 *)&wdtmsg,sizeof(tagWdtMsg),\ CN_TIMEOUT_FOREVER,CN_MSGQ_PRIO_NORMAL); } } return result; }
//---删除一个节点--------------------------------------------------------------- //功能: 把一个节点从资源链表中断开节点,该节点不能有子节点 //参数: Obj,被删除的节点,如该节点有子节点则不删除 //返回: 返回被删除节点指针,出错则返回NULL //------------------------------------------------------------------------------ struct Object *OBJ_Del(struct Object *Obj) { atom_low_t low_atom; struct Object *result; if(Obj == NULL) return NULL; low_atom = Int_LowAtomStart(); if(Obj->Child != NULL) //子节点非空,不操作 result = NULL; else { if(Obj->Next == Obj) //说明该节点没有兄弟节点. { Obj->Parent->Child = NULL; } else { if(Obj->Parent->Child == Obj) { //说明该节点是队列头节点,需要改变队列头节点 Obj->Parent->Child = Obj->Next; } Obj->Previous->Next = Obj->Next; Obj->Next->Previous = Obj->Previous; } result = Obj; } Int_LowAtomEnd(low_atom); return result; }
//----准静态内存分配----------------------------------------------------------- //功能:执行准静态分配的方法,分配一块内存,该方法实际上是模拟编译器分配行为,再 // 加上对齐。 //参数:size,欲分配的内存块尺寸 //返回:分配的内存指针,NULL表示没有内存可以分配 //备注: 1.准静态分配与静态内存分配类似,这种分配方法使用原子操作来确保数据一致, // 不会引起阻塞,内存不足则直接返回。 // 在执行module_init_heap_dynamic之前,所有的内存分配均采用准静态分配 //------------ //更新记录: // 1.日期: 2015/3/16 // 说明: 增加对参数size的零值判断 // 作者: 季兆林 //----------------------------------------------------------------------------- void *__M_StaticMallocHeap(ptu32_t size,struct tagHeapCB *Heap,u32 Timeout) { void *temp,*result = NULL; struct tagHeapCession *Cession; atom_low_t atom_m; if((Heap == NULL) || (0 == size)) return NULL; Cession = Heap->Cession; atom_m = Int_LowAtomStart(); while(Cession != NULL) { temp = Cession->heap_bottom; //保存当前堆底 //留下保存块尺寸的空间后对齐 Cession->heap_bottom = (u8 *)align_up(Heap->AlignSize, (ptu32_t)Cession->heap_bottom + sizeof(ptu32_t)); if((ptu32_t)(Cession->heap_top-Cession->heap_bottom) >= size) { //新分配的内存尺寸保存在当前堆底前面 temp = Cession->heap_bottom - sizeof(ptu32_t); *(ptu32_t *)temp = align_up(Heap->AlignSize,size); //保存申请的内存块尺寸 result = Cession->heap_bottom; Cession->heap_bottom += align_up(Heap->AlignSize,size); break; } else { Cession->heap_bottom = temp; //恢复当前堆底 } Cession = Cession->Next; } Int_LowAtomEnd(atom_m); return(result); }
//----释放准静态分配的内存块--------------------------------------------------- //功能:释放准静态分配的一个内存块,在heap的cession中查找,如果待释放的内存是从该 // session分配的最后一块内存,释放之。 //参数:pl_mem,待释放的内存块指针 // Heap,指定从这个堆中释放。 //返回:true = 成功释放,false = 释放失败 //备注: 1.准静态分配与静态内存分配类似,没有保护措施,正确性要程序员自己保证.这种 // 分配方法也不会引起阻塞,在执行module_init_heap_dynamic之前,所有的内存分配 // 均采用准静态分配 // 2.本函数在初始化完成之前调用,中断尚未开启,无需考虑关闭中断的问题. //----------------------------------------------------------------------------- void __M_StaticFreeHeap(void * pl_mem,struct tagHeapCB *Heap) { atom_low_t atom_m; struct tagHeapCession *Cession; ptu32_t *psize; if(pl_mem == NULL) return ; if(pl_mem != (void *)align_up(Heap->AlignSize,pl_mem))//不符合对齐要求的指针 return ; Cession = Heap->Cession; atom_m = Int_LowAtomStart(); while(Cession != NULL) { psize = (ptu32_t *)pl_mem; psize--; if( (*psize + (u8*)pl_mem) == Cession->heap_bottom) { //pl_mem是从该cession最后分配的内存,可以释放 Cession->heap_bottom = (void*)align_down(Heap->AlignSize,psize); break; } Cession = Cession->Next; } Int_LowAtomEnd(atom_m); return ; }
//----插入一个头节点--------------------------------------------------------- //功能: 给指定节点增加一个子节点,新节点将在队列头位置 //参数 Parent,新节点的父亲节点 // Child,待插入的新节点 // Size,新节点连负载的尺寸,字节数 // RscType, 资源类型,用于区分不同资源,原则上,资源的数据结构不同,类型就不同 // Name,资源名字,所指向的字符串内存区不能是局部变量,可以是空 //返回: 新加入的节点 //------------------------------------------------------------------------------ struct Object *OBJ_AddChildHead(struct Object *Parent, struct Object *Child, u16 Size, u16 RscType, const char *Name) { atom_low_t low_atom; struct Object *p; if((Parent == NULL) || (Child == NULL)) return NULL; low_atom = Int_LowAtomStart(); Child->Size = Size; Child->Type = RscType; Child->Name = (char *)Name; Child->Child = NULL; if(Parent->Child == NULL) { Parent->Child = Child; Child->Parent = Parent; Child->Next = Child; Child->Previous = Child; } else { p = Parent->Child; Child->Next = p; Child->Previous = p->Previous; Child->Parent = Parent; p->Previous->Next = Child; p->Previous = Child; Parent->Child = Parent->Child->Previous; } Int_LowAtomEnd(low_atom); return Child; }
//----删除一个树枝------------------------------------------------------------- //功能: 把一个树枝从资源队列中删除 //参数: Branch,被删除的分支。 //返回: 被删除分支指针,NULL表示分支不存在 //----------------------------------------------------------------------------- struct Object *OBJ_DelBranch(struct Object *Branch) { struct Object *result; atom_low_t low_atom; if(Branch == NULL) return NULL; low_atom = Int_LowAtomStart(); if(Branch->Next == Branch) //说明该节点没有兄弟节点. { Branch->Parent->Child = NULL; } else { if(Branch->Parent->Child == Branch) { //说明该节点是队列头节点,需要改变队列头节点 Branch->Parent->Child = Branch->Next; } Branch->Previous->Next = Branch->Next; Branch->Next->Previous = Branch->Previous; } result = Branch; Int_LowAtomEnd(low_atom); return result; }
// ============================================================================= // 函数功能:Rtc_SetTime // 设置日历时间,单位微秒 // 输入参数:rtctime,设置RTC时间,微秒数 // 输出参数: // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;先设置RTC模块的日历时间;如果有RTC设备,同样记得设置RTC设备时间 // ============================================================================= bool_t __Rtc_SetTime(s64 rtctime) { bool_t result = true; atom_low_t atom; s64 systime; systime = DjyGetTime(); if(NULL == fnRtcSetTime) { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; Int_LowAtomEnd(atom); #else sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; #endif } else { if(fnRtcSetTime(rtctime)) { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; Int_LowAtomEnd(atom); #else sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; #endif } else { //rtc set failed, so don't update the rtc module time,otherwise will //make the rtc dev and rtc module time not sync result = false; } } return result; }
// ============================================================================= // 功能:设置RTC设备RTC时间,单位微秒,该时间从1970年1月1日0:0:0到现在的时间差 // 参数:time, 时间值 // 返回:true,正常操作,否则出错 // ============================================================================= bool_t Rtc_SetTime(s64 time) { atom_low_t atom_bak; atom_bak = Int_LowAtomStart(); UpdateTime = time; Int_LowAtomEnd(atom_bak); Lock_SempPost(pRtcSemp); return true; }
// ============================================================================= // 函数功能:__GPTimer_Alloc // 分配定时器 // 输入参数:cycle,定时器周期 // timerisr,定时器的中断处理函数 // 输出参数: // 返回值 :分配的定时器句柄,NULL则分配不成功 // 说明 : // ============================================================================= ptu32_t __GPTimer_Alloc(u32 cycle,fnTimerIsr timerisr) { u8 timerno; u8 i=0; u8 irqline; struct tagGPTimerHandle *timer; ptu32_t timerhandle; //原子操作,防止资源竞争 atom_low_t timeratom; timeratom = Int_LowAtomStart(); timer=&s_tGPTimerHandle[0]; if(!timer->timerstate) { timerno=timer->timerno; } else { timer=&s_tGPTimerHandle[1]; if(!timer->timerstate) { timerno=timer->timerno; } else //没有的话直接返回就可以了,用不着再啰嗦了 { return NULL; } } Int_LowAtomEnd(timeratom); //原子操作完毕 irqline = sgHaltimerIrq[timerno]; timer = &s_tGPTimerHandle[timerno]; timer->cycle = cycle; timer->timerno = timerno; timer->irqline = irqline; timer->timerstate = CN_TIMER_ENUSE; //好了,中断号和定时器号码都有了,该干嘛就干嘛了。 //先设置好定时器周期 //__P1020PicTimer_PauseCount(timer); __GPTimer_SetCycle(timer,cycle); //设置定时器中断,先结束掉该中断所有的关联相关内容 Int_CutLine(irqline); Int_IsrDisConnect(irqline); Int_EvttDisConnect(irqline); Int_SettoAsynSignal(irqline); Int_IsrConnect(irqline, timerisr); timerhandle = (ptu32_t)timer; return timerhandle; }
//----读取当前时间(uS)--------------------------------------------------------- //功能:读取当前时间(uS),从计算机启动以来经历的us数,64位,默认不会溢出 // g_s64OsTicks 为64位变量,非64位系统中,读取 g_s64OsTicks 需要超过1个 // 周期,需要使用原子操作。 //参数:无 //返回:当前时钟 //说明: 这是一个桩函数,被rtc.c文件的 DjyGetTime 函数调用 //----------------------------------------------------------------------------- s64 __DjyGetTime(void) { LARGE_INTEGER litmp; s64 cnt; s64 time; atom_low_t atom_low; atom_low = Int_LowAtomStart(); QueryPerformanceCounter(&litmp); cnt = litmp.QuadPart; time = (u32)(cnt*1000000/s64g_freq); Int_LowAtomEnd(atom_low); return time;// (((u32)cn_tick_us*1000/cn_fine_ns)-pg_timer_reg->TCNTO3) *cn_fine_ns; }
//----------------------------------------------------------------------------- //功能: //参数: //返回: //备注: //----------------------------------------------------------------------------- s32 Get(struct Object *Obj) { s32 Ret = 0; atom_low_t ALock; ALock = Int_LowAtomStart(); if(NULL == Obj) Ret = -1; else if(Obj->Inuse == -1) Ret = -2; else Obj->Inuse++; Int_LowAtomEnd(ALock); return (Ret); }
//----移动节点成为队列头------------------------------------------------------- //功能: 朝previous指针方向移动资源队列中的一个节点,成为同级队列头 //参数: Obj,被移动的节点指针 //返回: TRUE = 成功执行,FALSE = 失败 //------------------------------------------------------------------------------ bool_t OBJ_MoveToHead(struct Object *Obj) { atom_low_t low_atom; if(Obj == NULL) return FALSE; low_atom = Int_LowAtomStart(); if(Obj->Parent) //根节点不能移动 { OBJ_MoveToLast(Obj); Obj->Parent->Child = Obj; } Int_LowAtomEnd(low_atom); return TRUE; }
// ============================================================================= // 函数功能: __Socket_GetSocket // 通过套接字号获取套接字 // 输入参数: 套接字号 // 输出参数: // 返回值 :获取的套接字 // 说明 :NULL表示参数不正确,或者没有该套接字 // ============================================================================= tagSocket * __Socket_GetSocket(int fd) { tagSocket *result; atom_low_t atom; result = NULL; atom = Int_LowAtomStart(); if((fd < CN_SOCKET_POOLSIZE)&&(fd >= 0)) { result = sgSocketMap[fd]; } Int_LowAtomEnd(atom); return result; }
//----线性缓冲区写入----------------------------------------------------------- //功能: 线性缓冲区写入若干个字节,返回实际写入的数据量,并移动写指针,如果线性 // 缓冲区没有足够的空间,按实际剩余空间写入 //参数: line,目标线性缓冲区结构指针 // buffer,待写入的数据指针 // len,待写入的数据长度.单位是字节数 //返回: 实际写入的字节数,如果缓冲区有足够的空间,=len //----------------------------------------------------------------------------- u32 Line_Write(struct tagLineBuf *line,u8 *buffer,u32 len) { u32 wr_len; atom_low_t atom_bak; wr_len = line->limit - line->current; if(wr_len == 0) return 0; if(wr_len > len) wr_len = len; memcpy( &line->buf[line->current],buffer,wr_len); atom_bak = Int_LowAtomStart(); line->current += wr_len; Int_LowAtomEnd(atom_bak); return wr_len; }
// ============================================================================= // 函数功能: __Socket_FreeInt // Free an link no // 输入参数: the no to free // 输出参数: // 返回值 :true success while false failed // 说明 : // ============================================================================= bool_t __Socket_FreeInt(int fd) { bool_t result; atom_low_t atom; result = false; atom = Int_LowAtomStart(); if((fd < CN_SOCKET_POOLSIZE)&&(fd >= 0)) { sgSocketMap[fd] = (tagSocket *)NULL; result = true; } Int_LowAtomEnd(atom); return result; }
//----队列头位置前移----------------------------------------------------------- //功能: Parent的子节点的相对位置不变,队列头朝next方向移动一格。 //参数: Parent,父节点指针 //返回: TRUE = 成功执行,FALSE = 失败 //------------------------------------------------------------------------------ bool_t OBJ_RoundNext(struct Object *Parent) { atom_low_t low_atom; if(Parent == NULL) return FALSE; low_atom = Int_LowAtomStart(); if(Parent->Child != NULL) { Parent->Child = Parent->Child->Next; } Int_LowAtomEnd(low_atom); return TRUE; }
// ============================================================================= // 函数功能:__AtTimer_Alloc // 分配定时器 // 输入参数:timerisr,定时器的中断处理函数 // 输出参数: // 返回值 :分配的定时器句柄,NULL则分配不成功 // 说明 : // ============================================================================= ptu32_t __AtTimer_Alloc(fntTimerIsr timerisr) { u8 timerno; u8 irqline; struct AtTimerHandle *timer; ptu32_t timerhandle; //原子操作,防止资源竞争 atom_low_t timeratom; timeratom = Int_LowAtomStart(); //寻找空闲的timer timerno = __AtTimer_GetFirstZeroBit(gs_dwAtTimerBitmap); if(timerno < CN_ATTIMER_NUM)//还有空闲的,则设置标志位 { gs_dwAtTimerBitmap = gs_dwAtTimerBitmap | (CN_ATTIMER_BITMAP_MSK<< timerno); Int_LowAtomEnd(timeratom); //原子操作完毕 } else//没有的话直接返回就可以了,用不着再啰嗦了 { Int_LowAtomEnd(timeratom); //原子操作完毕 return NULL; } PMC_EnablePeripheral(CN_PERI_ID_TC0 + timerno); irqline = sgHaltimerIrq[timerno]; timer = &stgTimerHandle[timerno]; timer->cycle = 0; timer->timerno = timerno; timer->irqline = irqline; timer->timerstate = CN_TIMER_ENUSE; //好了,中断号和定时器号码都有了,该干嘛就干嘛了。 //先设置好定时器周期 __AtTimer_PauseCount(timer); // __AtTimer_SetCycle(timer,cycle); //设置定时器中断,先结束掉该中断所有的关联相关内容 Int_Register(irqline); Int_CutLine(irqline); Int_IsrDisConnect(irqline); Int_EvttDisConnect(irqline); Int_SettoAsynSignal(irqline); Int_IsrConnect(irqline, timerisr); timerhandle = (ptu32_t)timer; return timerhandle; }
// ============================================================================= // 函数功能:__P1020PicTimer_Alloc // 分配定时器 // 输入参数:cycle,定时器周期 // timerisr,定时器的中断处理函数 // 输出参数: // 返回值 :分配的定时器句柄,NULL则分配不成功 // 说明 : // ============================================================================= ptu32_t __P1020PicTimer_Alloc(u32 cycle,fnTimerIsr timerisr) { u8 timerno; u8 irqline; struct tagP1020PicTimerHandle *timer; ptu32_t timerhandle; //原子操作,防止资源竞争 atom_low_t timeratom; timeratom = Int_LowAtomStart(); //寻找空闲的timer timerno = __P1020PicTimer_GetFirstZeroBit(gs_dwP1020PicTimerBitmap); if(timerno < CN_P1020PICTIMER_NUM)//还有空闲的,则设置标志位 { gs_dwP1020PicTimerBitmap = gs_dwP1020PicTimerBitmap | (CN_P1020PICTIMER_BITMAP_MSK<< timerno); Int_LowAtomEnd(timeratom); //原子操作完毕 } else//没有的话直接返回就可以了,用不着再啰嗦了 { Int_LowAtomEnd(timeratom); //原子操作完毕 return NULL; } irqline = sgHaltimerIrq[timerno]; timer = &stgP1020TimerHandle[timerno]; timer->cycle = cycle; timer->timerno = timerno; timer->irqline = irqline; timer->timerstate = CN_TIMER_ENUSE; //好了,中断号和定时器号码都有了,该干嘛就干嘛了。 //先设置好定时器周期 __P1020PicTimer_PauseCount(timer); __P1020PicTimer_SetCycle(timer,cycle); //设置定时器中断,先结束掉该中断所有的关联相关内容 Int_CutLine(irqline); Int_IsrDisConnect(irqline); Int_EvttDisConnect(irqline); Int_SettoAsynSignal(irqline); Int_SetClearType(irqline,CN_INT_CLEAR_PRE); Int_IsrConnect(irqline, timerisr); timerhandle = (ptu32_t)timer; return timerhandle; }
//----移动节点到某节点previous位置--------------------------------------------- //功能: 移动资源队列中的一个节点NewPre到另一个节点Obj的previous位置 //参数: Obj,被移动的节点指针 // NewPre,目标节点,obj移动到本节点前面 //返回: TRUE = 成功执行,FALSE = 失败 //------------------------------------------------------------------------------ bool_t OBJ_MoveToPrevious(struct Object *Obj, struct Object *NewPre) { atom_low_t low_atom; if((Obj == NULL) || (NewPre == NULL) || (Obj == NewPre)) return FALSE; else if(Obj->Parent != NewPre->Parent) return FALSE; low_atom = Int_LowAtomStart(); //以下从链表中取出节点 NewPre->Next->Previous = NewPre->Previous; NewPre->Previous->Next = NewPre->Next; NewPre->Next = Obj; NewPre->Previous = Obj->Previous; Obj->Previous->Next = NewPre; Obj->Previous = NewPre; Int_LowAtomEnd(low_atom); return TRUE; }
//----增加节点------------------------------------------------------------------ //功能: 在资源链表中增加一个节点,新节点在原节点的next位置 //参数 Obj,在此节点后面插入节点 // NewObj,待插入的新节点 // Size,新节点连负载的尺寸,字节数 // RscType, 资源类型,用于区分不同资源,原则上,资源的数据结构不同,类型就不同 // Name,资源名字,所指向的字符串内存区不能是局部变量,可以是空 //返回: 新加入的节点 //------------------------------------------------------------------------------ struct Object *OBJ_AddToNext(struct Object *Obj, struct Object *NewObj, u16 Size, u16 RscType, const char *Name) { atom_low_t low_atom; if((Obj == NULL) || (NewObj == NULL)) return NULL; low_atom = Int_LowAtomStart(); NewObj->Previous = Obj; NewObj->Next = Obj->Next; NewObj->Parent = Obj->Parent; NewObj->Child = NULL; NewObj->Size = Size; NewObj->Type = RscType; NewObj->Name = (char *)Name; Obj->Next->Previous = NewObj; Obj->Next = NewObj; Int_LowAtomEnd(low_atom); return NewObj; }
//----获取树根节点------------------------------------------------------------- //功能: 返回指定节点所在的树的根节点指针 //参数: Obj,目标节点。 //返回: 根节点指针 //---------------------------------------------------------------------------- struct Object *OBJ_GetTree(struct Object *Obj) { atom_low_t low_atom; struct Object *node = Obj; if(node == NULL) //目标节点空 return NULL; low_atom = Int_LowAtomStart(); while(node->Parent != s_ptRscRoot) { if(NULL != node->Parent) node = node->Parent; else { node = NULL; break; } } Int_LowAtomEnd(low_atom); return node; }
// ============================================================================= // 函数功能: __Socket_NewNo // alloc an new no to link the socket // 输入参数: 无 // 输出参数: // 返回值 : the link no if success, otherwise -1 failed // 说明 : // ============================================================================= int __Socket_NewNo() { static int newno = 0; int result; int i ; result = -1; atom_low_t atom; atom = Int_LowAtomStart(); for(i =0; i <CN_SOCKET_POOLSIZE; i++ ) { if(NULL == sgSocketMap[newno]) { sgSocketMap[newno]= (tagSocket *)CN_SOCKET_MAP_2USE; result = newno; newno = (newno+1)%CN_SOCKET_POOLSIZE; i = CN_SOCKET_POOLSIZE; } } Int_LowAtomEnd(atom); return result; }
// ============================================================================= // 函数功能:NetHard_Send // 网卡发送数据包 // 输入参数:netdev,使用的网卡 // pkg,待发送的数据包 // netdevtask,网卡需要完成的工作 // 输出参数: // 返回值 :true发送成功 false发送失败。 // 说明 :采用拷贝的方式发送,后续考虑使用链表发送 // ============================================================================= //bool_t DM9000_Send(int devindex,tagNetPkg *pkg,u32 netdevtask) //{ // bool_t result; // tagNetPkg *tmp; // u8 *src; // u8 *dst; // u32 sndlen; // // result = false; // if((ptNetDev == devindex)&&(NULL != pkg)) // { // sndlen = 0; // tmp = pkg; // //拷贝完毕之后记得释放 // while(NULL != tmp) // { // src = (u8 *)(tmp->buf + tmp->offset); // dst = (u8 *)(sgSndBuf + sndlen); // memcpy(dst, src, tmp->datalen); // sndlen += tmp->datalen; // tmp = tmp->partnext; // } // Pkg_GeneralFreeLst(pkg); // if(sndlen < 60)//小于60的包,记得填充 // { // dst = (u8 *)(sgSndBuf + sndlen); // memset(dst,0 ,60-sndlen); // sndlen = 60; // } // if(Lock_SempPend(MacSemp,CN_MAC_SEMP_TIMEOUT)) // { // DM9000_TxPacket(sgSndBuf,sndlen); // Lock_SempPost(MacSemp); // result = true; // } // } // return result; //} bool_t DM9000_Send(tagNetDev *dev,tagNetPkg *pkg,u32 netdevtask) { bool_t result; tagNetPkg *tmp; u16 *mysrc; u16 sndlen; u16 i; atom_low_t atom; result = false; if((ptNetDev == dev)&&(NULL != pkg)) { sndlen = 0; tmp = pkg; //cout the len tmp = pkg; sndlen = 0; while(NULL != tmp) { sndlen +=tmp->datalen; tmp = tmp->partnext; } atom = Int_LowAtomStart(); //snd all the pkg tmp = pkg; //init the dm9000 dm_reg_write(DM9000_IMR, 0x80); //在发送数据过程中禁止网卡中断 dm_reg_write(DM9000_TXPLH, (sndlen>>8) & 0x0ff);//设置发送数据长度 dm_reg_write(DM9000_TXPLL, sndlen & 0x0ff); DM_ADDR_PORT = DM9000_MWCMD; //发送数据缓存赋予数据端口 while(NULL!= tmp) { sndlen = tmp->datalen; mysrc = (u16 *)(tmp->buf + tmp->offset); //发送数据 for(i=0;i<sndlen;i+=2) { DM_DATA_PORT = *mysrc++; //8位数据转换为16位数据输出 } tmp = tmp->partnext; } //ok now start transfer; dm_reg_write(DM9000_TCR, 0x01); //把数据发送到以太网上 while((dm_reg_read(DM9000_NSR) & 0x0c) == 0) ; //等待数据发送完成 dm_reg_write(DM9000_NSR, 0x2c); //清除TX状态 dm_reg_write(DM9000_IMR, 0x81); //打开DM9000接收数据中断 Int_LowAtomEnd(atom); //free the pkg lst Pkg_LstFlagFree(pkg); result = true; }
// ============================================================================= // 函数功能:Rtc_TimeUs // 获取日历时间,单位微秒 // 输入参数: // 输出参数:rtctime,存储获取的RTC时间,秒数 // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;如果有RTC设备,则直接读取RTC设备的US,如果没有RTC时间,则自己用系统运行时间计算 // ============================================================================= s64 __Rtc_TimeUs(s64 *rtctime) { s64 result; s64 systime; atom_low_t atom; systime = DjyGetTime(); //we'd better to get the RTC time now if(NULL == fnRtcGetTime) { //no rtc dev yet,we could cal the rtc time use the sysrunning time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { if(false == fnRtcGetTime(&result)) { //failed to get the rtc dev time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } } result = result; if(NULL != rtctime) { *rtctime = result; } return result; }
// ============================================================================= // 函数功能:Rtc_Time // 获取日历时间,单位秒 // 输入参数: // 输出参数:rtctime,存储获取的RTC时间,秒数 // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;当连续的多次获取RTC时间时,可能获取的值相同,因为我们 // 近似的认为在一秒内的值差不多,所以用同一个无可厚非,因为本身都是用的秒, // 精度自然在秒级 // ============================================================================= s64 __Rtc_Time(s64 *rtctime) { s64 result; s64 systime; atom_low_t atom; systime = DjyGetTime(); if((sgRtcUpdateTime2SysTime/CN_RTC_UNIT_SECOND) ==(systime/CN_RTC_UNIT_SECOND)) { //which means that we get the RTC time at the same second //we could return the same time as last time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet; #endif } else { //we'd better to get the RTC time now if(NULL == fnRtcGetTime) { //no rtc dev yet,we could cal the rtc time use the sysrunning time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { if(false == fnRtcGetTime(&result)) { //failed to get the rtc dev time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } } } result = result/CN_RTC_UNIT_SECOND; if(NULL != rtctime) { *rtctime = result; } return result; }