OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_EVENT *)0); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); /* 检查是否有任务在等待该信号量 */ if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on semaphore */ tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { /* 没有任务等待该信号量时,才删除该信号量 */ case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ /* 没有任务等待,则直接删除该信号量 */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; /* 把事件控制块放入空事件控制块链表 */ pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ } else { OS_EXIT_CRITICAL(); *perr = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; /* 强制删除信号量,并取消所有等待任务的等待状态 */ case OS_DEL_ALWAYS: /* Always delete the semaphore */ /* 取消所有等待任务的等待状态,如果任务没有被挂起,则使任务就绪 */ while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for semaphore */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_ABORT); } #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; /* 把事件控制块放入空事件控制块链表 */ pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); /* 如果有任务在等待该事件,说明已经将所有等待该事件的任务就绪了,进行调度 */ if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ break; default: OS_EXIT_CRITICAL(); *perr = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }
/** * Raw send function to initiate a transfer to the mac * * @param net - NET structure associated with the Opencores MAC instance * @param data - pointer to the data payload * * @return SUCCESS if success, else a negative value */ int eth_ocm_raw_send(NET net, char * data, unsigned data_bytes){ int result; int i; unsigned len; eth_ocm_dev *dev; eth_ocm_info *info; eth_ocm_regs *regs; alt_u8 *buf; #ifdef UCOS_II int cpu_sr; #endif OS_ENTER_CRITICAL(); //disable interrupts dev = (eth_ocm_dev *)net->n_local; info = dev->info; regs = dev->regs; len = data_bytes - ETHHDR_BIAS; result = 0; //Check to see if someone is nesting send calls (BAD!) if(info->sem){ dprintf("[eth_ocm_raw_send] ERROR: Nested raw send call\n"); OS_EXIT_CRITICAL(); return ENP_RESOURCE; } //Grab the semaphore info->sem = 1; // clear bit-31 before passing it to SGDMA Driver buf = (alt_u8 *)alt_remap_cached( (volatile void *)data, 4); //advance the pointer beyond the header bias buf = (alt_u8 *)((unsigned int)buf + ETHHDR_BIAS); //Some error checks first if(len < ETH_OCM_MIN_MTU) result = -1; //packet too small if(len > ETH_OCM_MAX_MTU) result = -EFBIG; //packet too big if(regs->txdescs[0].ctrl & ETH_OCM_TXDESC_READY_MSK) result = -EBUSY; //DMA not available if(!result){ //Write pointer to descriptor regs->txdescs[0].ptr = (unsigned int)buf; //Write length and setup transfer regs->txdescs[0].ctrl = ((len << ETH_OCM_TXDESC_LEN_OFST) | ETH_OCM_TXDESC_READY_MSK | ETH_OCM_TXDESC_WRAP_MSK | ETH_OCM_TXDESC_PAD_MSK | ETH_OCM_TXDESC_CRC_MSK); //Wait for transfer to complete i=0; do{ result = regs->txdescs[0].ctrl; i++; }while((result & ETH_OCM_TXDESC_READY_MSK) && i<ETH_OCM_TRANSMIT_TIMEOUT); //Make sure no timeout occurred if(i<ETH_OCM_TRANSMIT_TIMEOUT){ if(result & (ETH_OCM_TXDESC_UR_MSK | ETH_OCM_TXDESC_RL_MSK | ETH_OCM_TXDESC_LC_MSK | ETH_OCM_TXDESC_CS_MSK)){ #if (ETH_OCM_DBG_LVL >= 2) dprintf("[eth_ocm_raw_send] Transmit error 0x%x\n", result); #endif // if ETH_OCM_DBG_LVL result = -EIO; //Some error occured } else{ #if (ETH_OCM_DBG_LVL >= 5) if(result & ETH_OCM_TXDESC_RTRY_MSK) dprintf("[eth_ocm_raw_send] Transmit retries: %d\n", (result & ETH_OCM_TXDESC_RTRY_MSK)>>ETH_OCM_TXDESC_RTRY_OFST); #endif result = 0; } } else{ //Timeout
/*$PAGE*/ void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate 'perr' */ return; } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return; } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return; } if (OSIntNesting > 0) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL(); if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */ pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return; } /* Otherwise, must wait until event occurs */ OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready */ OS_ENTER_CRITICAL(); switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: OS_EventTaskRemove(OSTCBCur, pevent); *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OS_EXIT_CRITICAL(); }
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) { #if (OS_EVENT_EN) OS_EVENT *pevent; #if (OS_EVENT_MULTI_EN > 0) OS_EVENT **pevents; #endif #endif OS_TCB *ptcb; INT8U y_new; INT8U x_new; INT8U y_old; #if OS_LOWEST_PRIO <= 63 INT8U bity_new; INT8U bitx_new; INT8U bity_old; INT8U bitx_old; #else INT16U bity_new; INT16U bitx_new; INT16U bity_old; INT16U bitx_old; #endif #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr = 0; /* Storage for CPU status register */ #endif /*$PAGE*/ #if OS_ARG_CHK_EN > 0 if (oldprio >= OS_LOWEST_PRIO) { if (oldprio != OS_PRIO_SELF) { return (OS_ERR_PRIO_INVALID); } } if (newprio >= OS_LOWEST_PRIO) { return (OS_ERR_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ OS_EXIT_CRITICAL(); return (OS_ERR_PRIO_EXIST); } if (oldprio == OS_PRIO_SELF) { /* See if changing self */ oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ } ptcb = OSTCBPrioTbl[oldprio]; if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */ OS_EXIT_CRITICAL(); /* No, can't change its priority! */ return (OS_ERR_PRIO); } if (ptcb == OS_TCB_RESERVED) { /* Is task assigned to Mutex */ OS_EXIT_CRITICAL(); /* No, can't change its priority! */ return (OS_ERR_TASK_NOT_EXIST); } #if OS_LOWEST_PRIO <= 63 y_new = (INT8U)(newprio >> 3); /* Yes, compute new TCB fields */ x_new = (INT8U)(newprio & 0x07); bity_new = (INT8U)(1 << y_new); bitx_new = (INT8U)(1 << x_new); #else y_new = (INT8U)((newprio >> 4) & 0x0F); x_new = (INT8U)( newprio & 0x0F); bity_new = (INT16U)(1 << y_new); bitx_new = (INT16U)(1 << x_new); #endif OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ y_old = ptcb->OSTCBY; bity_old = ptcb->OSTCBBitY; bitx_old = ptcb->OSTCBBitX; if ((OSRdyTbl[y_old] & bitx_old) != 0) { /* If task is ready make it not */ OSRdyTbl[y_old] &= ~bitx_old; if (OSRdyTbl[y_old] == 0) { OSRdyGrp &= ~bity_old; } OSRdyGrp |= bity_new; /* Make new priority ready to run */ OSRdyTbl[y_new] |= bitx_new; } #if (OS_EVENT_EN) pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) { pevent->OSEventTbl[y_old] &= ~bitx_old; /* Remove old task prio from wait list */ if (pevent->OSEventTbl[y_old] == 0) { pevent->OSEventGrp &= ~bity_old; } pevent->OSEventGrp |= bity_new; /* Add new task prio to wait list */ pevent->OSEventTbl[y_new] |= bitx_new; } #if (OS_EVENT_MULTI_EN > 0) if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { pevents = ptcb->OSTCBEventMultiPtr; pevent = *pevents; while (pevent != (OS_EVENT *)0) { pevent->OSEventTbl[y_old] &= ~bitx_old; /* Remove old task prio from wait lists */ if (pevent->OSEventTbl[y_old] == 0) { pevent->OSEventGrp &= ~bity_old; } pevent->OSEventGrp |= bity_new; /* Add new task prio to wait lists */ pevent->OSEventTbl[y_new] |= bitx_new; pevents++; pevent = *pevents; } } #endif #endif ptcb->OSTCBPrio = newprio; /* Set new task priority */ ptcb->OSTCBY = y_new; ptcb->OSTCBX = x_new; ptcb->OSTCBBitY = bity_new; ptcb->OSTCBBitX = bitx_new; OS_EXIT_CRITICAL(); if (OSRunning == OS_TRUE) { OS_Sched(); /* Find new highest priority task */ } return (OS_ERR_NONE); }
OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *err) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif BOOLEAN tasks_waiting; OS_Q *pq; if (OSIntNesting > 0) { /* See if called from ISR ... */ *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return ((OS_EVENT *)0); } #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return (pevent); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return (pevent); } #endif OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on queue */ tasks_waiting = TRUE; /* Yes */ } else { tasks_waiting = FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */ if (tasks_waiting == FALSE) { pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ pq->OSQPtr = OSQFreeList; OSQFreeList = pq; pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Queue has been deleted */ } else { OS_EXIT_CRITICAL(); *err = OS_ERR_TASK_WAITING; return (pevent); } case OS_DEL_ALWAYS: /* Always delete the queue */ while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for queue */ OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q); } pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */ pq->OSQPtr = OSQFreeList; OSQFreeList = pq; pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *err = OS_NO_ERR; return ((OS_EVENT *)0); /* Queue has been deleted */ default: OS_EXIT_CRITICAL(); *err = OS_ERR_INVALID_OPT; return (pevent); } }
// 要求获得邮箱的消息 void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { void *msg; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (err == (INT8U *)0) /* Validate 'err' */ { return ((void *)0); } if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { *err = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif // 事件类型是邮箱? if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) /* Validate event block type */ { *err = OS_ERR_EVENT_TYPE; return ((void *)0); } // 中断处理里不允许挂起 if (OSIntNesting > 0) /* See if called from ISR ... */ { *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } // 调度禁止时不允许挂起 if (OSLockNesting > 0) /* See if called with scheduler locked ... */ { *err = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return ((void *)0); } OS_ENTER_CRITICAL(); msg = pevent->OSEventPtr; // 可获得邮箱消息? if (msg != (void *)0) /* See if there is already a message */ { // 清空邮箱 pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; // 返回 return (msg); /* Return the message received (or NULL) */ } // 如果获取不到邮箱信息,任务会挂起 // 更新任务状态标志 OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ // 延时等待最大时间未到 OSTCBCur->OSTCBPendTO = OS_FALSE; // 设置延时等待最大时间 OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ // 将任务添加到事件控制块的等待任务表 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); // 找出优先级最高的任务并进行任务切换 OS_Sched(); /* Find next highest priority task ready to run */ // 当邮箱有效或者等待时间到后, // 并且调用OSMboxPend()函数的任务再一次成为最高优先级任务, // 就会回到这里继续执行 OS_ENTER_CRITICAL(); // 延时等待最大时间到了? if (OSTCBCur->OSTCBPendTO == OS_TRUE) /* See if we were given the message */ { // 由于等待超时而将任务置为就绪态。 OS_EventTO(pevent); /* Timed out, Make task ready */ OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate that a timeout occured */ return ((void *)0); /* Return a NULL message */ } // 邮箱可被获得: // 获得邮箱消息 msg = OSTCBCur->OSTCBMsg; // 清空邮箱 OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */ // 更新任务状态标志 OSTCBCur->OSTCBStat = OS_STAT_RDY; // 释放TCB里的ECB OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (msg); /* Return the message received */ }
/* The ambe_decode_wav() function decodes AMBE2+ bits to 80 samples (160 bytes) of 8kHz audio as signed shorts. This hook will optionally print that data to the dmesg buffer, where it can be extracted and recorded on the host. */ int ambe_decode_wav_hook(int *a1, signed int eighty, char *bitbuffer, int a4, short a5, short a6, int a7){ /* This prints the AMBE2+ structure that is to be decoded. The output is decodable with DSD, but it sounds horrible. */ #ifdef AMBEPRINT int ambestate=OS_ENTER_CRITICAL(); short *bits=(short*) bitbuffer; static int i; /* I don't know why, but this output can only be decoded by DSD if half the frames are dropped. The trick is to only decode those when the sixth paramter is zero, ignoring all the ones where that parameter is a one. Strangely enough, we do not skip half the frames of the WAV ouput below. */ if(!a6){ printf("AMBE2+ Corr: "); for(i=0;i<49;i++){ md380_putc(NULL,bits[i]?'1':'0'); } md380_putc(NULL,'\n'); } OS_EXIT_CRITICAL(ambestate); #endif //AMBEPRINT int toret=0xdeadbeef; #ifdef CONFIG_AMBE //First we call the original function. toret=ambe_decode_wav(a1, eighty, bitbuffer, a4, a5, a6, a7); #endif /* Print the parameters printf("ambe_decode_wav(0x%08x, %d, 0x%08x,\n" "%d, %d, %d, 0x%08x);\n", a1, eighty, bitbuffer, a4, a5, a6, a7); */ /* This is very noisy, so we don't enable it by default. It prints the WAV as hex pairs, which will quickly flood the buffer if it isn't cleared in time. */ #ifdef AMBEWAVPRINT //Does this really need to be in a critical section? int wavstate=OS_ENTER_CRITICAL(); //A1 holds audio as signed LE shorts. printf("WAV: "); printhex(a1,160); printf("\n"); OS_EXIT_CRITICAL(wavstate); #endif //AMBEWAVPRINT return toret; }
/******************************************************************************** * FunctionName: TaskSet * * Description : 设置任务,设置完删除任务 * * Parameters : None. * * Returns : None. *******************************************************************************/ void TaskSet(void *p_arg) { unsigned char k, data_flash_temp[208]={0xAE, 0x35, 0x24, 0x70, 0x80, 0xB7, 0x80, 0xBA, 0x1F, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9B, 0x1D, 0x5C, 0x1B, 0x5E, 0x02, 0x77, 0x02, 0xED, 0xEF, 0x80, 0xB8, 0x80, 0xB9, 0x1D, 0x5C, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1F, 0x80, 0x9B, 0x1D, 0x5C, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9B, 0x1D, 0x80, 0x9A, 0x1E, 0x80, 0xF5, 0x1E, 0x8F, 0x70, 0x02, 0xEA, 0x8C, 0x80, 0xB8, 0x80, 0xB9, 0x1D, 0x5C, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9A, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9B, 0x1D, 0x80, 0x9A, 0x1E, 0x80, 0xF5, 0x1E, 0x85, 0x88, 0x80, 0xB8, 0x80, 0xB8, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9A, 0x1E, 0x5C, 0x1E, 0x5B, 0x1F, 0x5B, 0x1E, 0x5B, 0x1F, 0x5B, 0x1F, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9B, 0x15, 0x80, 0xA4, 0x02, 0x86, 0xB7, 0x04, 0x81, 0x6D, 0x02, 0x77, 0x02, 0x77, 0x02, 0x77, 0x02, 0x77, 0x02, 0x77, 0x02, 0x77, 0x02, 0xAF, 0xFB, 0x02, 0x77, 0x1F, 0x5B, 0x1F, 0x5B, 0x1E, 0x5B, 0x1E, 0x80, 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD7}; // INT8U i; u32 seed; u8 random_data,i; //INT32U msg = 0; //INT8U err = 0; OS_CPU_SR cpu_sr = 0; p_arg = p_arg; DelayMs(30); OS_ENTER_CRITICAL(); BSP_Init(); Flash_Read(RFIR_ID_ADDR, MY_ID, 4); //读取FLASH ID存入BUF #if 0 SendString("\n\rMY ID:"); for(i=0;i<4;i++)//sizeof(ID) { SendString(";"); Outint(MY_ID[i]); } #endif /******************************************************************************** * Description : 任务建立 共9个任务 *******************************************************************************/ CT361SndErrSemp = OSSemCreate(0);//creat sem //创建协议解析任务 OSTaskCreate(TaskProtocol, (void*)0, &TaskProtocolStk[TASK_PROTOCOL_STKSIZE-1], TASK_PROTOCOL_PRIO); //创建串口发送任务 OSTaskCreate(TaskProtoSend, (void*)0, &TaskProtoSendStk[TASK_PROTO_SEND_STKSIZE-1], TASK_PROTO_SEND_PRIO ); //创建量产测试任务 OSTaskCreate(TaskTest, (void*)0, &TaskTestStk[TASK_TEST_STKSIZE-1], TASK_TEST_PRIO ); //创建4432接收任务 OSTaskCreate(TaskSi4432Read, (void*)0, &TaskSi4432ReadStk[TASK_SET_STKSIZE-1], TASK_Si4432_READ_PRIO ); //创建返回码接收任务 OSTaskCreate(TaskCT361SndErr,\ (void*)0,\ &TaskCT361SndErrStk[TASK_CT361_SND_ERR_STKSIZE-1],\ TASK_CT361_SND_ERR_PRIO); /******************************************************************************** * Description : 创建消息队列 *******************************************************************************/ // SetMBox = OSQCreate(&SetQBuff[0], TASK_SET_QSIZE); ProtocolMBox = OSQCreate(&ProtocolQBuff[0], TASK_PROTOCOL_QSIZE); ProtoSendMBox = OSQCreate(&ProtoSendQBuff[0], TASK_PROTOSEND_QSIZE); TestMBox = OSQCreate(&TestQBuff[0], TASK_TEST_QSIZE); Si4432ReadMBox = OSQCreate(&Si4432ReadQBuff[0], TASK_Si4432READ_QSIZE); OS_EXIT_CRITICAL(); SysTickInit(); //自我删除 // OSTaskDel(OS_PRIO_SELF); /*自我删除函数会自动进行任务的调度,因此此处不需要添加延时*/ Flash_Write(0x800D678,data_flash_temp,208); for (;;) { /**********学习状态指示灯********/ if(learn_cmd==1) //学习开始标志位 { LED_Send(0);// 绿灯关闭 LED_Learn(1);//红灯闪烁 WatchDog_Feed(); //喂狗 OSTimeDly(4); WatchDog_Feed(); //喂狗 LED_Learn(0); WatchDog_Feed(); //喂狗 OSTimeDly(4); WatchDog_Feed(); //喂狗 Timout_Count--; if(Timout_Count==0) { Timout_Count=TIMOUT_20s; OSQPost(TestMBox, (void*)Stu_Fail); //学习失败信号 learn_cmd=0; //清空学习成功标志位 } } if(learn_cmd==0) //学习成功标志位 { LED_Learn(0);//红灯关闭 LED_Send(1); //绿灯开启 } /**********生成随机滚动序列*********/ seed+=23; if(seed>65000) seed=0; srand(seed); random_data=rand(); test_roll_list=random_data^0x29; if(learn_cmd==0) { Timout_Count2--; if((Timout_Count2>=40)&&(Timout_Count2<=200)) { LED_Send(0); } else if((Timout_Count2<40)&&(Timout_Count2>=1)) { LED_Send(1); // Timout_Count2=200; } else if(Timout_Count2<=0) Timout_Count2=200; } WatchDog_Feed(); //喂狗 OSTimeDly(1); } }
void OSStartHighRdy() { DWORD dwID; OSInitTrace(100000); OS_ENTER_CRITICAL(); OSTaskSwHook(); ++OSRunning; OSCtxSwW32Event = CreateEvent(NULL,FALSE,FALSE,NULL); OSCtxSwW32Handle = CreateThread( NULL, 0, OSCtxSwW32, 0, 0, &dwID ); SetPriorityClass(OSCtxSwW32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSCtxSwW32Handle, 1 ) == 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSCtxSwW32Handle,THREAD_PRIORITY_TIME_CRITICAL); OSTick32Handle = CreateThread( NULL, 0, OSTickW32, 0, 0, &dwID ); SetPriorityClass(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef SET_AFFINITY_MASK if( SetThreadAffinityMask( OSTick32Handle, 1 ) == 0 ) { #ifdef OS_CPU_TRACE OS_Printf("Error: SetThreadAffinityMask\n"); #endif } #endif SetThreadPriority(OSTick32Handle,THREAD_PRIORITY_HIGHEST); #ifdef WIN_MM_TICK timeGetDevCaps(&OSTimeCap, sizeof(OSTimeCap)); if( OSTimeCap.wPeriodMin < WIN_MM_MIN_RES ) OSTimeCap.wPeriodMin = WIN_MM_MIN_RES; timeBeginPeriod(OSTimeCap.wPeriodMin); OSTickEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL); OSTickTimer = timeSetEvent((1000/OS_TICKS_PER_SEC),OSTimeCap.wPeriodMin,(LPTIMECALLBACK)OSTickEventHandle, dwID,TIME_PERIODIC|TIME_CALLBACK_EVENT_SET); #endif SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr; /* OSTCBCur = OSTCBHighRdy; */ /* OSPrioCur = OSPrioHighRdy; */ ResumeThread(SS_SP->Handle); OS_EXIT_CRITICAL(); WaitForSingleObject(OSCtxSwW32Handle,INFINITE); #ifdef WIN_MM_TICK timeKillEvent(OSTickTimer); timeEndPeriod(OSTimeCap.wPeriodMin); CloseHandle(OSTickEventHandle); #endif CloseHandle(OSTick32Handle); CloseHandle(OSCtxSwW32Event); }
//任务控制块初始化 INITIALIZE TCB //描述: 这个函数是uC/OS-II内部函数,在建立任务时调用的初始化任务控制块OS_TCB函数,含7个参数, // (查看 OSTaskCreate() 和 OSTaskCreateExt()). //参数: prio 任务的优先级 // ptos OSTaskInit()建立栈结构以后,ptos是指向栈顶的指针,且保存在OS_TCB的OSTCBStkPrt中 // pbos 指向栈底的指针,保存在OSTCBStkBottom变元中 // id 任务标志符(0..65535),保存在.OSTCBId中 // stk_size 堆栈的容量,保存在OS_TCB的OSTABStkSize中 // pext OS_TCB中的扩展指针,.OSTCBExtPtr的值 // opt OS_TCB的选择项,保存在.OSTCBOpt中 //返回: OS_NO_ERR 调用成功 // OS_NO_MORE_TCB 没有更多的任务控制块被分配,将无法创建新的任务 //注意: 这个函数是uC/OS-II内部函数,你不可以调用它。 INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; OS_ENTER_CRITICAL(); ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */ if (ptcb != (OS_TCB *)0) { OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */ OS_EXIT_CRITICAL(); ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */ ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */ ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */ ptcb->OSTCBDly = 0; /* Task is not delayed */ #if OS_TASK_CREATE_EXT_EN > 0 ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */ ptcb->OSTCBStkSize = stk_size; /* Store stack size */ ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */ ptcb->OSTCBOpt = opt; /* Store task options */ ptcb->OSTCBId = id; /* Store task ID */ #else pext = pext; /* Prevent compiler warning if not used */ stk_size = stk_size; pbos = pbos; opt = opt; id = id; #endif #if OS_TASK_DEL_EN > 0 ptcb->OSTCBDelReq = OS_NO_ERR; #endif ptcb->OSTCBY = prio >> 3; /* Pre-compute X, Y, BitX and BitY */ ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY]; ptcb->OSTCBX = prio & 0x07; ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX]; #if OS_EVENT_EN > 0 ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */ #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0) ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; /* Task is not pending on an event flag */ #endif #if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) ptcb->OSTCBMsg = (void *)0; /* No message received */ #endif #if OS_VERSION >= 204 OSTCBInitHook(ptcb); #endif OSTaskCreateHook(ptcb); /* Call user defined hook */ OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = ptcb; ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */ ptcb->OSTCBPrev = (OS_TCB *)0; if (OSTCBList != (OS_TCB *)0) { OSTCBList->OSTCBPrev = ptcb; } OSTCBList = ptcb; OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); return (OS_NO_ERR); }
void OSSemPend( OS_EVENT * pevent, INT16U timeout, INT8U * err ) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if ( err == ( INT8U * ) 0 ) { /* Validate 'err' */ return; } if ( pevent == ( OS_EVENT * ) 0 ) { /* Validate 'pevent' */ *err = OS_ERR_PEVENT_NULL; return; } #endif if ( pevent->OSEventType != OS_EVENT_TYPE_SEM ) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return; } if ( OSIntNesting > 0 ) { /* See if called from ISR ... */ *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } if ( OSLockNesting > 0 ) { /* See if called with scheduler locked ... */ *err = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL( ); if ( pevent->OSEventCnt > 0 ) { /* If sem. is positive, resource available ... */ pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL( ); *err = OS_NO_ERR; return; } /* Otherwise, must wait until event occurs */ OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ OSTCBCur->OSTCBPendTO = OS_FALSE; OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ OS_EventTaskWait( pevent ); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL( ); OS_Sched( ); /* Find next highest priority task ready */ OS_ENTER_CRITICAL( ); if ( OSTCBCur->OSTCBPendTO == OS_TRUE ) { /* See if we timedout */ OS_EventTO( pevent ); OS_EXIT_CRITICAL( ); *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */ return; } OSTCBCur->OSTCBEventPtr = ( OS_EVENT * ) 0; OS_EXIT_CRITICAL( ); *err = OS_NO_ERR; }
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif #if OS_EVENT_EN > 0 OS_EVENT *pevent; #endif OS_TCB *ptcb; INT8U x; INT8U y; INT8U bitx; INT8U bity; #if OS_ARG_CHK_EN > 0 if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) || newprio >= OS_LOWEST_PRIO) { return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); } else { OSTCBPrioTbl[newprio] = (OS_TCB *)1; /* Reserve the entry to prevent others */ OS_EXIT_CRITICAL(); y = newprio >> 3; /* Precompute to reduce INT. latency */ bity = OSMapTbl[y]; x = newprio & 0x07; bitx = OSMapTbl[x]; OS_ENTER_CRITICAL(); if (oldprio == OS_PRIO_SELF) { /* See if changing self */ oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ } ptcb = OSTCBPrioTbl[oldprio]; if (ptcb != (OS_TCB *)0) { /* Task to change must exist */ OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) { /* If task is ready make it not */ if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { OSRdyGrp &= ~ptcb->OSTCBBitY; } OSRdyGrp |= bity; /* Make new priority ready to run */ OSRdyTbl[y] |= bitx; #if OS_EVENT_EN > 0 } else { pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) { /* Remove from event wait list */ if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY; } pevent->OSEventGrp |= bity; /* Add new priority to wait list */ pevent->OSEventTbl[y] |= bitx; } #endif } OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ ptcb->OSTCBPrio = newprio; /* Set new task priority */ ptcb->OSTCBY = y; ptcb->OSTCBX = x; ptcb->OSTCBBitY = bity; ptcb->OSTCBBitX = bitx; OS_EXIT_CRITICAL(); OS_Sched(); /* Run highest priority task ready */ return (OS_NO_ERR); } else { OSTCBPrioTbl[newprio] = (OS_TCB *)0; /* Release the reserved prio. */ OS_EXIT_CRITICAL(); return (OS_PRIO_ERR); /* Task to change didn't exist */ } } }
INT8U OSTaskDel (INT8U prio) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif #if OS_EVENT_EN > 0 OS_EVENT *pevent; #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) OS_FLAG_NODE *pnode; #endif OS_TCB *ptcb; if (OSIntNesting > 0) { /* See if trying to delete from ISR */ return (OS_TASK_DEL_ISR); } #if OS_ARG_CHK_EN > 0 if (prio == OS_IDLE_PRIO) { /* Not allowed to delete idle task */ return (OS_TASK_DEL_IDLE); } if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF) { /* Task priority valid ? */ return (OS_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */ prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb != (OS_TCB *)0) { /* Task to delete must exist */ if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00) { /* Make task not ready */ OSRdyGrp &= ~ptcb->OSTCBBitY; } #if OS_EVENT_EN > 0 pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) { /* If task is waiting on event */ if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) { /* ... remove task from */ pevent->OSEventGrp &= ~ptcb->OSTCBBitY; /* ... event ctrl block */ } } #endif #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) pnode = ptcb->OSTCBFlagNode; if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */ OS_FlagUnlink(pnode); /* Remove from wait list */ } #endif ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */ ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */ if (OSLockNesting < 255) { OSLockNesting++; } OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */ OS_Dummy(); /* ... Dummy ensures that INTs will be */ OS_ENTER_CRITICAL(); /* ... disabled HERE! */ if (OSLockNesting > 0) { OSLockNesting--; } OSTaskDelHook(ptcb); /* Call user defined hook */ OSTaskCtr--; /* One less task being managed */ OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */ if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */ ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; OSTCBList = ptcb->OSTCBNext; } else { ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; } ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */ OSTCBFreeList = ptcb; OS_EXIT_CRITICAL(); OS_Sched(); /* Find new highest priority task */ return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_TASK_DEL_ERR); }
/*$PAGE*/ void OSSemPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr) { #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return; } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return; } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return; } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL(); /* 信号量大于0,则信号量减1,返回 */ if (pevent->OSEventCnt > 0u) { /* If sem. is positive, resource available ... */ pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return; } /* 信号量为0,则把TCB中的状态设置为等待信号量,并设置请求状态为请求OK */ /* Otherwise, must wait until event occurs */ OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* 把等待时限写入TCB */ OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ /* 设置TCB中等待的事件 * 设置事件控制块中等待任务列表 * 取消当前任务的就绪状态 */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); /* 查找最高优先级的就绪任务,并调度运行 */ OS_Sched(); /* Find next highest priority task ready */ /* 执行OS_Sched()后,已经切换到其他任务。执行这里时,已经是信号量有效或者是等待超时了 */ OS_ENTER_CRITICAL(); /* 根据状态设置函数返回值 */ switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: /* 清除事件等待列表中的当前任务 * 因为OSSemPost()而退出等待状态的任务,会在OSSemPost()中清除事件等待列表中的该任务对应位 * 因为超时而退出等待状态的任务,对应的事件控制块的事件等待列表中该任务不会被清除,需要在这里清除 */ OS_EventTaskRemove(OSTCBCur, pevent); *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } /* 设置当前任务控制块状态 */ OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0u) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OS_EXIT_CRITICAL(); }
int usb_dnld_hook(){ /* These are global buffers to the packet data, its length, and the block address that it runs to. The stock firmware has a bug in that it assumes the packet size is always 2048 bytes. */ int state; /* DFU transfers begin at block 2, and special commands hook block 0. We'll use block 1, because it handily fits in the gap without breaking backward compatibility with the older code. */ if(*md380_blockadr==1){ switch(md380_packet[0]){ //Memory commands case TDFU_DMESG: //The DMESG buffer might move, so this command //sets the target address to the DMESG buffer. *md380_dfu_target_adr=dmesg_start; break; //SPI-FLASH commands #ifdef CONFIG_SPIFLASH case TDFU_SPIFLASHGETID: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; get_spi_flash_type((void *) dmesg_tx_buf); // 0x00aabbcc aa=MANUFACTURER ID, bb,cc Device Identification break; case TDFU_SPIFLASHREAD: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; uint32_t adr= *((uint32_t*)(md380_packet+1)); printf("Dumping %d bytes from 0x%08x in SPI Flash\n", DMESG_SIZE, adr); md380_spiflash_read(dmesg_tx_buf, adr, DMESG_SIZE); break; case TDFU_SPIFLASHWRITE: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; adr = *((uint32_t*)(md380_packet+1)); uint32_t size = *((uint32_t*)(md380_packet+5)); memset(dmesg_tx_buf,0,DMESG_SIZE); if (check_spi_flash_size()>adr) { printf ("TDFU_SPIFLASHWRITE %x %d %x\n", adr, size, md380_packet+9); md380_spiflash_write(md380_packet+9, adr, size); } break; case TDFU_SPIFLASHERASE64K: // experimental //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; adr= *((uint32_t*)(md380_packet+1)); memset(dmesg_tx_buf,0,DMESG_SIZE); if (check_spi_flash_size()>adr) { printf ("TDFU_SPIFLASHERASE64K %x \n", adr); // spiflash_wait(); // spiflash_block_erase64k(adr); md380_spiflash_enable(); md380_spi_sendrecv(0x6); md380_spiflash_disable(); md380_spiflash_enable(); md380_spi_sendrecv(0xd8); md380_spi_sendrecv((adr>> 16) & 0xff); md380_spi_sendrecv((adr>> 8) & 0xff); md380_spi_sendrecv(adr & 0xff); md380_spiflash_disable(); } // md380_spiflash_wait(); // this is the problem :( // must be polled via dfu commenad? break; case TDFU_SPIFLASHWRITE_NEW: // not working, this is not the problem //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; adr = *((uint32_t*)(md380_packet+1)); size = *((uint32_t*)(md380_packet+5)); memset(dmesg_tx_buf,0,DMESG_SIZE); if (check_spi_flash_size()>adr) { printf ("DFU_CONFIG_SPIFLASHWRITE_new %x %d %x\n", adr, size, md380_packet+9); // enable write for (int i=0;i<size;i=i+256) { int page_adr; page_adr=adr+i; printf("%d %x\n",i,page_adr); md380_spiflash_wait(); md380_spiflash_enable(); md380_spi_sendrecv(0x6); md380_spiflash_disable(); md380_spiflash_enable(); md380_spi_sendrecv(0x2); printf("%x ", ((page_adr>> 16) & 0xff)); md380_spi_sendrecv((page_adr>> 16) & 0xff); printf("%x ", ((page_adr>> 8) & 0xff)); md380_spi_sendrecv((page_adr>> 8) & 0xff); printf("%x ", (page_adr & 0xff)); md380_spi_sendrecv(page_adr & 0xff); for (int ii=0; ii < 256; ii++) { md380_spi_sendrecv(md380_packet[9+ii+i]); } md380_spiflash_disable(); md380_spiflash_wait(); printf("\n"); } } break; case TDFU_SPIFLASHSECURITYREGREAD: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; printf("Dumping %d bytes from adr 0 SPI Flash security_registers\n", DMESG_SIZE); md380_spiflash_security_registers_read(dmesg_tx_buf, 0, 3*256); break; #endif //CONFIG_SPIFLASH #ifdef CONFIG_SPIC5000 //Radio Commands case TDFU_C5000_READREG: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; memset(dmesg_tx_buf,0,DMESG_SIZE); state=OS_ENTER_CRITICAL(); c5000_spi0_readreg(md380_packet[1],dmesg_tx_buf); OS_EXIT_CRITICAL(state); break; case TDFU_C5000_WRITEREG: //Re-uses the dmesg transmit buffer. *md380_dfu_target_adr=dmesg_tx_buf; memset(dmesg_tx_buf,0,DMESG_SIZE); state=OS_ENTER_CRITICAL(); c5000_spi0_writereg(md380_packet[1],md380_packet[2]); OS_EXIT_CRITICAL(state); break; #endif //CONFIG_SPIC5000 #ifdef CONFIG_GRAPHICS //Graphics commands. case TDFU_PRINT: // 0x80, u8 x, u8 y, u8 str[]. drawtext((wchar_t *) (md380_packet+3), md380_packet[1],md380_packet[2]); break; case TDFU_BOX: break; #endif //CONFIG_GRAPHICS case TDFU_SYSLOG: syslog_dump_dmesg(); break; default: printf("Unhandled DFU packet type 0x%02x.\n",md380_packet[0]); }
//------------------------------------------------------------------------------ /// Writes a data buffer in the internal flash. This function works in polling /// mode, and thus only returns when the data has been effectively written. /// Returns 0 if successful; otherwise returns an error code. /// \param address Write address. /// \param pBuffer Data buffer. /// \param size Size of data buffer in bytes. //------------------------------------------------------------------------------ unsigned char FLASHD_Write( unsigned int address, const void *pBuffer, unsigned int size) { AT91S_EFC *pEfc; unsigned short page; unsigned short offset; unsigned int writeSize; unsigned int pageAddress; unsigned short padding; unsigned char error; unsigned int sizeTmp; unsigned int *pAlignedDestination; unsigned int *pAlignedSource; ////SANITY_CHECK(address >= (unsigned int)AT91C_IFLASH); ////SANITY_CHECK(pBuffer); ////SANITY_CHECK((address + size) <= (unsigned int)(AT91C_IFLASH + AT91C_IFLASH_SIZE)); #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif OS_ENTER_CRITICAL(); // Translate write address EFC_TranslateAddress(address, &pEfc, &page, &offset); // Write all pages while (size > 0) { // Copy data in temporary buffer to avoid alignment problems writeSize = min(AT91C_IFLASH_PAGE_SIZE - offset, size); EFC_ComputeAddress(pEfc, page, 0, &pageAddress); padding = AT91C_IFLASH_PAGE_SIZE - offset - writeSize; // Pre-buffer data (mask with 0xFF) memcpy(pPageBuffer, (void *) pageAddress, offset); // Buffer data memcpy(pPageBuffer + offset, pBuffer, writeSize); // Post-buffer data memcpy(pPageBuffer + offset + writeSize, (void *) (pageAddress + offset + writeSize), padding); // Write page // Writing 8-bit and 16-bit data is not allowed // and may lead to unpredictable data corruption #ifdef EFC_EVEN_ODD_PROG // Write even words first with auto erase pAlignedDestination = (unsigned int*)pageAddress; pAlignedSource = (unsigned int*)pPageBuffer; sizeTmp = AT91C_IFLASH_PAGE_SIZE; while (sizeTmp >= 4) { *pAlignedDestination = *pAlignedSource; pAlignedDestination += 2; pAlignedSource += 2; sizeTmp -= 8; } // Send writing command error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_START_PROG, page); if (error) { OS_EXIT_CRITICAL(); return error; } // Then write odd words without auto erase EFC_SetEraseBeforeProgramming(AT91C_BASE_EFC0, 0); #ifdef AT91C_BASE_EFC1 EFC_SetEraseBeforeProgramming(AT91C_BASE_EFC1, 0); #endif pAlignedDestination = (unsigned int*)pageAddress + 1; pAlignedSource = (unsigned int*)pPageBuffer + 1; sizeTmp = AT91C_IFLASH_PAGE_SIZE; while (sizeTmp >= 4) { *pAlignedDestination = *pAlignedSource; pAlignedDestination += 2; pAlignedSource += 2; sizeTmp -= 8; } // Send writing command error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_START_PROG, page); if (error) { OS_EXIT_CRITICAL(); return error; } EFC_SetEraseBeforeProgramming(AT91C_BASE_EFC0, 1); #ifdef AT91C_BASE_EFC1 EFC_SetEraseBeforeProgramming(AT91C_BASE_EFC1, 1); #endif #else pAlignedDestination = (unsigned int*)pageAddress; pAlignedSource = (unsigned int*)pPageBuffer; sizeTmp = AT91C_IFLASH_PAGE_SIZE; while (sizeTmp >= 4) { *pAlignedDestination++ = *pAlignedSource++; sizeTmp -= 4; } // Send writing command // error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_START_PROG, page); if (error) { OS_EXIT_CRITICAL(); return error; } #endif // Progression address += AT91C_IFLASH_PAGE_SIZE; pBuffer = (void *) ((unsigned int) pBuffer + writeSize); size -= writeSize; page++; offset = 0; #if defined(AT91C_BASE_EFC1) // Handle EFC crossover if ((pEfc == AT91C_BASE_EFC0) && (page >= (AT91C_IFLASH_NB_OF_PAGES / 2))) { pEfc = AT91C_BASE_EFC1; page = 0; } #endif } //while end OS_EXIT_CRITICAL(); return 0; }
OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; INT8U pip; /* Priority inheritance priority */ INT8U prio; OS_TCB *ptcb; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { *perr = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) /* Validate event block type */ { *perr = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0u) /* See if called from ISR ... */ { *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) /* See if any tasks waiting on mutex */ { tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pip = (INT8U)(pevent->OSEventCnt >> 8u); OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */ pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */ } else {
//------------------------------------------------------------------------------ /// Unlocks all the regions in the given address range. The actual unlock range is /// reported through two output parameters. /// Returns 0 if successful; otherwise returns an error code. /// \param start Start address of unlock range. /// \param end End address of unlock range. /// \param pActualStart Start address of the actual unlock range (optional). /// \param pActualEnd End address of the actual unlock range (optional). //------------------------------------------------------------------------------ unsigned char FLASHD_Unlock( unsigned int start, unsigned int end, unsigned int *pActualStart, unsigned int *pActualEnd) { AT91S_EFC *pStartEfc, *pEndEfc, *pEfc; unsigned int actualStart, actualEnd; unsigned short startPage, endPage; unsigned char error; unsigned short numPagesInRegion = AT91C_IFLASH_LOCK_REGION_SIZE / AT91C_IFLASH_PAGE_SIZE; #if OS_CRITICAL_METHOD == 3u OS_CPU_SR cpu_sr = 0u; #endif OS_ENTER_CRITICAL(); // Compute actual unlock range and store it ComputeLockRange(start, end, &actualStart, &actualEnd); if (pActualStart) { *pActualStart = actualStart; } if (pActualEnd) { *pActualEnd = actualEnd; } // Compute page numbers EFC_TranslateAddress(actualStart, &pStartEfc, &startPage, 0); EFC_TranslateAddress(actualEnd, &pEndEfc, &endPage, 0); // Unlock all pages // If there is an EFC crossover, unlock all pages from first EFC #if defined(AT91C_BASE_EFC1) if (pStartEfc != pEndEfc) { while (startPage < (AT91C_IFLASH_NB_OF_PAGES / 2)) { // error = EFC_PerformCommand(pStartEfc, AT91C_MC_FCMD_UNLOCK, startPage); if (error) { OS_EXIT_CRITICAL(); return error; } startPage += numPagesInRegion; } startPage = 0; } #endif pEfc = pEndEfc; // Unlock remaining pages while (startPage < endPage) { // error = EFC_PerformCommand(pEfc, AT91C_MC_FCMD_UNLOCK, startPage); if (error) { OS_EXIT_CRITICAL(); return error; } startPage += numPagesInRegion; } OS_EXIT_CRITICAL(); return 0; }
OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *perr) { OS_MEM *pmem; INT8U *pblk; void **plink; INT32U loops; INT32U i; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == OS_TRUE) { OS_SAFETY_CRITICAL_EXCEPTION(); } #endif #if OS_ARG_CHK_EN > 0u if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/ *perr = OS_ERR_MEM_INVALID_ADDR; return ((OS_MEM *)0); } if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){ /* Must be pointer size aligned */ *perr = OS_ERR_MEM_INVALID_ADDR; return ((OS_MEM *)0); } if (nblks < 2u) { /* Must have at least 2 blocks per partition */ *perr = OS_ERR_MEM_INVALID_BLKS; return ((OS_MEM *)0); } if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */ *perr = OS_ERR_MEM_INVALID_SIZE; return ((OS_MEM *)0); } #endif OS_ENTER_CRITICAL(); pmem = OSMemFreeList; /* Get next free memory partition */ if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */ OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList; } OS_EXIT_CRITICAL(); if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */ *perr = OS_ERR_MEM_INVALID_PART; return ((OS_MEM *)0); } plink = (void **)addr; /* Create linked list of free memory blocks */ pblk = (INT8U *)addr; loops = nblks - 1u; for (i = 0u; i < loops; i++) { pblk += blksize; /* Point to the FOLLOWING block */ *plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */ plink = (void **)pblk; /* Position to NEXT block */ } *plink = (void *)0; /* Last memory block points to NULL */ pmem->OSMemAddr = addr; /* Store start address of memory partition */ pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */ pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */ pmem->OSMemNBlks = nblks; pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */ *perr = OS_ERR_NONE; return (pmem); }
// 要求获得一个信号量 void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (err == (INT8U *)0) /* Validate 'err' */ { return; } if (pevent == (OS_EVENT *)0) /* Validate 'pevent' */ { *err = OS_ERR_PEVENT_NULL; return; } #endif // 确定事件类型是信号量 if (pevent->OSEventType != OS_EVENT_TYPE_SEM) /* Validate event block type */ { *err = OS_ERR_EVENT_TYPE; return; } // 中断处理里不允许挂起 if (OSIntNesting > 0) /* See if called from ISR ... */ { *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return; } // 调度禁止时不允许挂起 if (OSLockNesting > 0) /* See if called with scheduler locked ... */ { *err = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return; } OS_ENTER_CRITICAL(); // 如果信号量可用 if (pevent->OSEventCnt > 0) /* If sem. is positive, resource available ... */ { // 获得信号量,计数器减一,即可用的资源减少一份 pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */ OS_EXIT_CRITICAL(); *err = OS_NO_ERR; // 返回 return; } // 否则,等待信号量 /* Otherwise, must wait until event occurs */ // 更新任务状态标志 OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */ // 延时等待最大时间未到 OSTCBCur->OSTCBPendTO = OS_FALSE; // 设置延时等待最大时间 OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */ // 将任务添加到事件控制块的等待任务表 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); // 找出优先级最高的任务并进行任务切换 OS_Sched(); /* Find next highest priority task ready */ // 当信号量有效或者等待时间到后, // 并且调用 OSSemPend()函数的任务再一次成为最高优先级任务, // 就会回到这里继续执行 OS_ENTER_CRITICAL(); // 是否延时等待最大时间到了? if (OSTCBCur->OSTCBPendTO == OS_TRUE) /* See if we timedout */ { // 由于等待超时而将任务置为就绪态。 OS_EventTO(pevent); OS_EXIT_CRITICAL(); *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */ return; } // 释放TCB里的ECB OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; }
INT8U OSTaskDel (INT8U prio) { #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) OS_FLAG_NODE *pnode; #endif OS_TCB *ptcb; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif if (OSIntNesting > 0) { /* See if trying to delete from ISR */ return (OS_ERR_TASK_DEL_ISR); } if (prio == OS_TASK_IDLE_PRIO) { /* Not allowed to delete idle task */ return (OS_ERR_TASK_DEL_IDLE); } #if OS_ARG_CHK_EN > 0 if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */ if (prio != OS_PRIO_SELF) { return (OS_ERR_PRIO_INVALID); } } #endif /*$PAGE*/ OS_ENTER_CRITICAL(); if (prio == OS_PRIO_SELF) { /* See if requesting to delete self */ prio = OSTCBCur->OSTCBPrio; /* Set priority to delete to current */ } ptcb = OSTCBPrioTbl[prio]; if (ptcb == (OS_TCB *)0) { /* Task to delete must exist */ OS_EXIT_CRITICAL(); return (OS_ERR_TASK_NOT_EXIST); } if (ptcb == OS_TCB_RESERVED) { /* Must not be assigned to Mutex */ OS_EXIT_CRITICAL(); return (OS_ERR_TASK_DEL); } OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX; if (OSRdyTbl[ptcb->OSTCBY] == 0) { /* Make task not ready */ OSRdyGrp &= ~ptcb->OSTCBBitY; } #if (OS_EVENT_EN) if (ptcb->OSTCBEventPtr != (OS_EVENT *)0) { OS_EventTaskRemove(ptcb, ptcb->OSTCBEventPtr); /* Remove this task from any event wait list */ } #if (OS_EVENT_MULTI_EN > 0) if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) { /* Remove this task from any events' wait lists*/ OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr); } #endif #endif #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) pnode = ptcb->OSTCBFlagNode; if (pnode != (OS_FLAG_NODE *)0) { /* If task is waiting on event flag */ OS_FlagUnlink(pnode); /* Remove from wait list */ } #endif ptcb->OSTCBDly = 0; /* Prevent OSTimeTick() from updating */ ptcb->OSTCBStat = OS_STAT_RDY; /* Prevent task from being resumed */ ptcb->OSTCBStatPend = OS_STAT_PEND_OK; if (OSLockNesting < 255u) { /* Make sure we don't context switch */ OSLockNesting++; } OS_EXIT_CRITICAL(); /* Enabling INT. ignores next instruc. */ OS_Dummy(); /* ... Dummy ensures that INTs will be */ OS_ENTER_CRITICAL(); /* ... disabled HERE! */ if (OSLockNesting > 0) { /* Remove context switch lock */ OSLockNesting--; } OSTaskDelHook(ptcb); /* Call user defined hook */ OSTaskCtr--; /* One less task being managed */ OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Clear old priority entry */ if (ptcb->OSTCBPrev == (OS_TCB *)0) { /* Remove from TCB chain */ ptcb->OSTCBNext->OSTCBPrev = (OS_TCB *)0; OSTCBList = ptcb->OSTCBNext; } else { ptcb->OSTCBPrev->OSTCBNext = ptcb->OSTCBNext; ptcb->OSTCBNext->OSTCBPrev = ptcb->OSTCBPrev; } ptcb->OSTCBNext = OSTCBFreeList; /* Return TCB to free TCB list */ OSTCBFreeList = ptcb; #if OS_TASK_NAME_SIZE > 1 ptcb->OSTCBTaskName[0] = '?'; /* Unknown name */ ptcb->OSTCBTaskName[1] = OS_ASCII_NUL; #endif OS_EXIT_CRITICAL(); if (OSRunning == OS_TRUE) { OS_Sched(); /* Find new highest priority task */ } return (OS_ERR_NONE); }
void GprsSend(int32 fd, uint8 *Data, uint32 n) { int status; OS_ENTER_CRITICAL(); status = write(fd, Data, n); OS_EXIT_CRITICAL(); }
OS_EVENT *OSMutexCreate (INT8U prio, INT8U *perr) { OS_EVENT *pevent; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_EVENT *)0); } #endif #ifdef OS_SAFETY_CRITICAL_IEC61508 if (OSSafetyCriticalStartFlag == OS_TRUE) { OS_SAFETY_CRITICAL_EXCEPTION(); return ((OS_EVENT *)0); } #endif #if OS_ARG_CHK_EN > 0u if (prio != OS_PRIO_MUTEX_CEIL_DIS) { if (prio >= OS_LOWEST_PRIO) { /* Validate PCP */ *perr = OS_ERR_PRIO_INVALID; return ((OS_EVENT *)0); } } #endif if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */ return ((OS_EVENT *)0); } OS_ENTER_CRITICAL(); if (prio != OS_PRIO_MUTEX_CEIL_DIS) { if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */ OS_EXIT_CRITICAL(); /* Task already exist at priority ... */ *perr = OS_ERR_PRIO_EXIST; /* ... ceiling priority */ return ((OS_EVENT *)0); } OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */ } pevent = OSEventFreeList; /* Get next free event control block */ if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */ if (prio != OS_PRIO_MUTEX_CEIL_DIS) { OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */ } OS_EXIT_CRITICAL(); *perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */ return (pevent); } OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */ OS_EXIT_CRITICAL(); pevent->OSEventType = OS_EVENT_TYPE_MUTEX; pevent->OSEventCnt = (INT16U)((INT16U)prio << 8u) | OS_MUTEX_AVAILABLE; /* Resource is avail. */ pevent->OSEventPtr = (void *)0; /* No task owning the mutex */ #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif OS_EventWaitListInit(pevent); *perr = OS_ERR_NONE; return (pevent); }
void *OSQPend (OS_EVENT *pevent, INT32U timeout, INT8U *perr) { void *pmsg; OS_Q *pq; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #if OS_ARG_CHK_EN > 0u if (perr == (INT8U *)0) { /* Validate 'perr' */ return ((void *)0); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return ((void *)0); } if (OSIntNesting > 0u) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } if (OSLockNesting > 0u) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return ((void *)0); } OS_ENTER_CRITICAL(); pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */ if (pq->OSQEntries > 0u) { /* See if any messages in the queue */ pmsg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */ pq->OSQEntries--; /* Update the number of entries in the queue */ if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */ pq->OSQOut = pq->OSQStart; } OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return (pmsg); /* Return message received */ } OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready to run */ OS_ENTER_CRITICAL(); switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: /* Extract message from TCB (Put there by QPost) */ pmsg = OSTCBCur->OSTCBMsg; *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: pmsg = (void *)0; *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: OS_EventTaskRemove(OSTCBCur, pevent); pmsg = (void *)0; *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0u) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */ OS_EXIT_CRITICAL(); return (pmsg); /* Return received message */ }
INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata) { #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif OS_Q *pq; INT8U *psrc; INT8U *pdest; #if OS_ARG_CHK_EN > 0 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ return (OS_ERR_PEVENT_NULL); } if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */ return (OS_ERR_EVENT_TYPE); } #endif OS_ENTER_CRITICAL(); pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message queue wait list */ psrc = &pevent->OSEventTbl[0]; pdest = &pdata->OSEventTbl[0]; #if OS_EVENT_TBL_SIZE > 0 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 1 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 2 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 3 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 4 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 5 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 6 *pdest++ = *psrc++; #endif #if OS_EVENT_TBL_SIZE > 7 *pdest = *psrc; #endif pq = (OS_Q *)pevent->OSEventPtr; if (pq->OSQEntries > 0) { pdata->OSMsg = *pq->OSQOut; /* Get next message to return if available */ } else { pdata->OSMsg = (void *)0; } pdata->OSNMsgs = pq->OSQEntries; pdata->OSQSize = pq->OSQSize; OS_EXIT_CRITICAL(); return (OS_NO_ERR); }
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio) { #if OS_EVENT_EN OS_EVENT *pevent; #endif OS_TCB *ptcb; INT8U x; INT8U y; #if OS_LOWEST_PRIO <= 63 INT8U bitx; INT8U bity; #else INT16U bitx; INT16U bity; #endif INT8U y_old; #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr = 0; /* Storage for CPU status register */ #endif #if OS_ARG_CHK_EN > 0 if (oldprio >= OS_LOWEST_PRIO) { if (oldprio != OS_PRIO_SELF) { return (OS_ERR_PRIO_INVALID); } } if (newprio >= OS_LOWEST_PRIO) { return (OS_ERR_PRIO_INVALID); } #endif OS_ENTER_CRITICAL(); if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) { /* New priority must not already exist */ OS_EXIT_CRITICAL(); return (OS_ERR_PRIO_EXIST); } if (oldprio == OS_PRIO_SELF) { /* See if changing self */ oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */ } ptcb = OSTCBPrioTbl[oldprio]; if (ptcb == (OS_TCB *)0) { /* Does task to change exist? */ OS_EXIT_CRITICAL(); /* No, can't change its priority! */ return (OS_ERR_PRIO); } if (ptcb == (OS_TCB *)1) { /* Is task assigned to Mutex */ OS_EXIT_CRITICAL(); /* No, can't change its priority! */ return (OS_ERR_TASK_NOT_EXIST); } #if OS_LOWEST_PRIO <= 63 y = (INT8U)(newprio >> 3); /* Yes, compute new TCB fields */ x = (INT8U)(newprio & 0x07); bity = (INT8U)(1 << y); bitx = (INT8U)(1 << x); #else y = (INT8U)((newprio >> 4) & 0x0F); x = (INT8U)( newprio & 0x0F); bity = (INT16U)(1 << y); bitx = (INT16U)(1 << x); #endif OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */ OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */ y_old = ptcb->OSTCBY; if ((OSRdyTbl[y_old] & ptcb->OSTCBBitX) != 0) { /* If task is ready make it not */ OSRdyTbl[y_old] &= ~ptcb->OSTCBBitX; if (OSRdyTbl[y_old] == 0) { OSRdyGrp &= ~ptcb->OSTCBBitY; } OSRdyGrp |= bity; /* Make new priority ready to run */ OSRdyTbl[y] |= bitx; } #if OS_EVENT_EN pevent = ptcb->OSTCBEventPtr; if (pevent != (OS_EVENT *)0) { /* ... remove from event wait list */ pevent->OSEventTbl[y_old] &= ~ptcb->OSTCBBitX; if (pevent->OSEventTbl[y_old] == 0) { pevent->OSEventGrp &= ~ptcb->OSTCBBitY; } pevent->OSEventGrp |= bity; /* Add new priority to wait list */ pevent->OSEventTbl[y] |= bitx; } #endif ptcb->OSTCBPrio = newprio; /* Set new task priority */ ptcb->OSTCBY = y; ptcb->OSTCBX = x; ptcb->OSTCBBitY = bity; ptcb->OSTCBBitX = bitx; OS_EXIT_CRITICAL(); if (OSRunning == OS_TRUE) { OS_Sched(); /* Find new highest priority task */ } return (OS_ERR_NONE); }
OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate 'perr' */ return (pevent); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0) { /* See if called from ISR ... */ *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on semaphore */ tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete semaphore only if no task waiting */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_SIZE > 1 pevent->OSEventName[0] = '?'; /* Unknown name */ pevent->OSEventName[1] = OS_ASCII_NUL; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ } else { OS_EXIT_CRITICAL(); *perr = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; case OS_DEL_ALWAYS: /* Always delete the semaphore */ while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for semaphore */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK); } #if OS_EVENT_NAME_SIZE > 1 pevent->OSEventName[0] = '?'; /* Unknown name */ pevent->OSEventName[1] = OS_ASCII_NUL; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0; OSEventFreeList = pevent; /* Get next free event control block */ OS_EXIT_CRITICAL(); if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Semaphore has been deleted */ break; default: OS_EXIT_CRITICAL(); *perr = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }
/*$PAGE*/ void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr) { void *pmsg; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *)0) { /* Validate 'perr' */ return ((void *)0); } if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */ *perr = OS_ERR_PEVENT_NULL; return ((void *)0); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return ((void *)0); } if (OSIntNesting > 0) { /* See if called from ISR ... */ *perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */ return ((void *)0); } if (OSLockNesting > 0) { /* See if called with scheduler locked ... */ *perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */ return ((void *)0); } OS_ENTER_CRITICAL(); pmsg = pevent->OSEventPtr; if (pmsg != (void *)0) { /* See if there is already a message */ pevent->OSEventPtr = (void *)0; /* Clear the mailbox */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; return (pmsg); /* Return the message received (or NULL) */ } OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */ OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */ OS_EXIT_CRITICAL(); OS_Sched(); /* Find next highest priority task ready to run */ OS_ENTER_CRITICAL(); switch (OSTCBCur->OSTCBStatPend) { /* See if we timed-out or aborted */ case OS_STAT_PEND_OK: pmsg = OSTCBCur->OSTCBMsg; *perr = OS_ERR_NONE; break; case OS_STAT_PEND_ABORT: pmsg = (void *)0; *perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */ break; case OS_STAT_PEND_TO: default: OS_EventTaskRemove(OSTCBCur, pevent); pmsg = (void *)0; *perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get event within TO */ break; } OSTCBCur->OSTCBStat = OS_STAT_RDY; /* Set task status to ready */ OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK; /* Clear pend status */ OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* Clear event pointers */ #if (OS_EVENT_MULTI_EN > 0) OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)0; #endif OSTCBCur->OSTCBMsg = (void *)0; /* Clear received message */ OS_EXIT_CRITICAL(); return (pmsg); /* Return received message */ }
OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *perr) { BOOLEAN tasks_waiting; OS_EVENT *pevent_return; #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0u; #endif #ifdef OS_SAFETY_CRITICAL if (perr == (INT8U *)0) { OS_SAFETY_CRITICAL_EXCEPTION(); } #endif #if OS_ARG_CHK_EN > 0u if (pevent == (OS_EVENT *)0) { /*事件控制块指针是否有效 */ *perr = OS_ERR_PEVENT_NULL; return (pevent); } #endif if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* 事件控制块类型是否有效*/ *perr = OS_ERR_EVENT_TYPE; return (pevent); } if (OSIntNesting > 0u) { /* 查看是否在中断服务程序ISR中调用本函数 */ *perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */ return (pevent); } OS_ENTER_CRITICAL(); if (pevent->OSEventGrp != 0u) { /* See if any tasks waiting on mailbox */ tasks_waiting = OS_TRUE; /* Yes */ } else { tasks_waiting = OS_FALSE; /* No */ } switch (opt) { case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */ if (tasks_waiting == OS_FALSE) { #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* 取得空闲的事件控制块ECB */ OS_EXIT_CRITICAL(); *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ } else { OS_EXIT_CRITICAL(); *perr = OS_ERR_TASK_WAITING; pevent_return = pevent; } break; case OS_DEL_ALWAYS: /* Always delete the mailbox */ while (pevent->OSEventGrp != 0u) { /* Ready ALL tasks waiting for mailbox */ (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK); } #if OS_EVENT_NAME_EN > 0u pevent->OSEventName = (INT8U *)(void *)"?"; #endif pevent->OSEventType = OS_EVENT_TYPE_UNUSED; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */ pevent->OSEventCnt = 0u; OSEventFreeList = pevent; /* 取得空闲的事件控制块ECB */ OS_EXIT_CRITICAL(); if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */ OS_Sched(); /* Find highest priority task ready to run */ } *perr = OS_ERR_NONE; pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */ break; default: OS_EXIT_CRITICAL(); *perr = OS_ERR_INVALID_OPT; pevent_return = pevent; break; } return (pevent_return); }
OS_FLAGS OSFlagAccept(OS_FLAG_GRP * pgrp, OS_FLAGS flags, INT8U wait_type, INT8U * perr) { OS_FLAGS flags_rdy; INT8U result; BOOLEAN consume; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr = 0; #endif #if OS_ARG_CHK_EN > 0 if (perr == (INT8U *) 0) { /* Validate 'perr' */ return ((OS_FLAGS) 0); } if (pgrp == (OS_FLAG_GRP *) 0) { /* Validate 'pgrp' */ *perr = OS_ERR_FLAG_INVALID_PGRP; return ((OS_FLAGS) 0); } #endif if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ *perr = OS_ERR_EVENT_TYPE; return ((OS_FLAGS) 0); } result = (INT8U) (wait_type & OS_FLAG_CONSUME); if (result != (INT8U) 0) { /* See if we need to consume the flags */ wait_type &= ~OS_FLAG_CONSUME; consume = OS_TRUE; } else { consume = OS_FALSE; } /*$PAGE*/ *perr = OS_ERR_NONE; /* Assume NO error until proven otherwise. */ OS_ENTER_CRITICAL(); switch (wait_type) { case OS_FLAG_WAIT_SET_ALL: /* See if all required flags are set */ flags_rdy = (OS_FLAGS) (pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ if (flags_rdy == flags) { /* Must match ALL the bits that we want */ if (consume == OS_TRUE) { /* See if we need to consume the flags */ pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we wanted */ } } else { *perr = OS_ERR_FLAG_NOT_RDY; } OS_EXIT_CRITICAL(); break; case OS_FLAG_WAIT_SET_ANY: flags_rdy = (OS_FLAGS) (pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ if (flags_rdy != (OS_FLAGS) 0) { /* See if any flag set */ if (consume == OS_TRUE) { /* See if we need to consume the flags */ pgrp->OSFlagFlags &= ~flags_rdy; /* Clear ONLY the flags that we got */ } } else { *perr = OS_ERR_FLAG_NOT_RDY; } OS_EXIT_CRITICAL(); break; #if OS_FLAG_WAIT_CLR_EN > 0 case OS_FLAG_WAIT_CLR_ALL: /* See if all required flags are cleared */ flags_rdy = (OS_FLAGS) (~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ if (flags_rdy == flags) { /* Must match ALL the bits that we want */ if (consume == OS_TRUE) { /* See if we need to consume the flags */ pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we wanted */ } } else { *perr = OS_ERR_FLAG_NOT_RDY; } OS_EXIT_CRITICAL(); break; case OS_FLAG_WAIT_CLR_ANY: flags_rdy = (OS_FLAGS) (~pgrp->OSFlagFlags & flags); /* Extract only the bits we want */ if (flags_rdy != (OS_FLAGS) 0) { /* See if any flag cleared */ if (consume == OS_TRUE) { /* See if we need to consume the flags */ pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */ } } else { *perr = OS_ERR_FLAG_NOT_RDY; } OS_EXIT_CRITICAL(); break; #endif default: OS_EXIT_CRITICAL(); flags_rdy = (OS_FLAGS) 0; *perr = OS_ERR_FLAG_WAIT_TYPE; break; } return (flags_rdy); }