Jump to content

    

devnir

Новичок
  • Content Count

    3
  • Joined

  • Last visited

Community Reputation

0 Обычный
  1. Работа с FPU ARM1176

    Собственно проблема с портированием uCOS II на ARM1176, а именно с FPU отталкивался от порта Порт от Micrium for the ARM1176JZ(F)-S Processor Использую IAR. Проблема в том что в вышеописаном порте отсутсвует работа с FPU как таковая. Пробывал брать с другого порта uCOS работу с ФПУ, но похоже что-то забываю. Делал так: 1. дописываю в os_cpu_a.s: Код        EXPORT OS_CPU_FP_Restore OS_CPU_FP_Restore         FLDMIAS R0!, {S0-S31}        ; Restore the VFP registers from pblk         BX      LR                ; Return to calling function         EXPORT OS_CPU_FP_Save OS_CPU_FP_Save         FSTMIAS R0!, {S0-S31}        ; Save the VFP registers in pblk               BX      LR                ; Return to calling function 2. в добавляю os_cpu_c.c Кодvoid  OSTaskCreateHook (OS_TCB *ptcb) { #if OS_CPU_FPU_EN > 0     INT8U  err;     void  *pblk=(void*)1; #endif #if OS_CPU_FPU_EN > 0     if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {           pblk = malloc(33*4);         if (pblk != (void *)0) {             ptcb->OSTCBExtPtr = pblk;             OS_CPU_FP_Save(pblk);             }     } #endif Кодvoid  OSTaskDelHook (OS_TCB *ptcb) [code]{ #if OS_CPU_FPU_EN > 0     if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {            /* See if task had FP support               */         if (ptcb->OSTCBExtPtr != (void *)0) {              /* Yes, OSTCBExtPtr must not be NULL        */             free(ptcb->OSTCBExtPtr);//OSMemPut(OSFPPartPtr, ptcb->OSTCBExtPtr);      /*      Return memory block to free pool    */         }     } #endif Кодvoid  OSTaskSwHook (void) { #if OS_CPU_FPU_EN > 0     void  *pblk; #endif #if OS_CPU_FPU_EN > 0                                                if (OSRunning == OS_TRUE) {                                           if (OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {                       pblk = OSTCBCur->OSTCBExtPtr;                         if (pblk != (void *)0) {                                                   OS_CPU_FP_Save(pblk);                             }         }     }                                                      if (OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {         pblk = OSTCBHighRdy->OSTCBExtPtr;                         if (pblk != (void *)0) {                                     OS_CPU_FP_Restore(pblk);                                         }     } #endif но помоему чтото забыл... так как даже простое: Кодcom_print("%lf\n", 0.1234); вызваное в любой задаче выводит: 0,00000 зато есл вызвать это же перед инициализацией оси: Кодint main(){ uart_init(); com_print("%lf\n", 0.1234); ... ... } все работает шикарно... Может будут у кого какие идеи, или способы решения данной проблемы, посоветуйте - подскажите. Очень надо. заранее спс
  2. ARM1176JF-S + IAR + uCos + FPU

    Локализировал проблему. Отключив uCOS все начало работать корректно. Кодint main(void) {   float a =0.25;   uart_open(UART1,0,0, 115200);     com_print(UART1, "%lf\n", a);   for(;;); } Следовательно FPU инициализируется корректно. (проверял отключив кусок кода отвечающий за инициализацию, соответсвенно работать перестало) Но от этого легче не стало кто по uCOS-у подскажет что я там пропустил когда пытался его заставить работать с ФПУ ?
  3. ARM1176JF-S + IAR + uCos + FPU

    Предисловие: Портирую uCos на ARM1176JF-S, использую IAR. Процесс: впринципе проблем не возникало пока не дошел до FPU Казалось бы, проблем возникать не должно, но.. 1. Micrium предлогает порт для ARM1176 - для RVDS, не беда, асемблерные файлы переписали. проинициализировали все - прекрасно работает. 2. Все в том же злополучном порте от Micrium-а, напрось отсутсвует инициализация и использование FPU. Опять же не проблема, в init.s добавляю: Код      ;; Enable the VFP coprocessor.       ; Enable ARM11 VFP (cp10 and cp11) full access       ; in the Coprocessor Access Control Register         MRC     p15, 0, r0, c1, c0, 2         ORR     r0, r0, #0x00F00000         MCR     p15, 0, r0, c1, c0, 2         MOV     r0, #0x40000000    ; Set EN bit in VFP         FMXR    fpexc, r0             ; FPEXC, clear others. ; ; Disable underflow exceptions by setting flush to zero mode. ; For full IEEE 754 underflow compliance this code should be removed ; and the appropriate exception handler installed. ;         MOV     r0, #0x03000000    ; Set FZ and DN bits in VFP         FMXR    fpscr, r0             ; FPSCR, clear others. после чего подключаю еще arm_cpu_fpu.s со следующим содержанием: Код    PUBLIC  OS_CPU_FP_Restore     PUBLIC  OS_CPU_FP_Save     RSEG CODE:CODE:NOROOT(2)     CODE32 OS_CPU_FP_Restore         FLDMIAS R0!, {S0-S31}         ; Restore the VFP registers from pblk         BX      LR                    ; Return to calling function OS_CPU_FP_Save         FSTMIAS R0!, {S0-S31}         ; Save the VFP registers in pblk         BX      LR                    ; Return to calling function         END ну и собственно в os_cpu_c.c добавляю: Код#define  OS_NTASKS_FP          (OS_MAX_TASKS + OS_N_SYS_TASKS - 1) #define  OS_FP_STORAGE_SIZE            128L #if OS_TMR_EN > 0 static  INT16U  OSTmrCtr; #endif #if OS_CPU_FPU_EN > 0 static  OS_MEM  *OSFPPartPtr;                    /* Ptr to memory partition for storing FPU registers  */ static  INT32U   OSFPPart[OS_NTASKS_FP][OS_FP_STORAGE_SIZE / sizeof(INT32U)]; #endif #if OS_CPU_FPU_EN > 0 void  OS_CPU_FP_Init (void) {     INT8U    err; #if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN     OS_TCB  *ptcb;     void    *pblk; #endif     OSFPPartPtr = OSMemCreate(&OSFPPart[0][0], OS_NTASKS_FP, OS_FP_STORAGE_SIZE, &err); #if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN           /* CHANGE 'OPTIONS' for OS_TaskStat()           */     ptcb            = OSTCBPrioTbl[OS_TASK_STAT_PRIO];     ptcb->OSTCBOpt |= OS_TASK_OPT_SAVE_FP;             /* Allow floating-point support for Stat task   */     pblk            = OSMemGet(OSFPPartPtr, &err);     /* Get storage for VFP registers                */     if (pblk != (void *)0) {                           /* Did we get a memory block?                   */         ptcb->OSTCBExtPtr = pblk;                      /* Yes, Link to task's TCB                      */         OS_CPU_FP_Save(pblk);                          /*      Save the VFP registers in block         */     } #endif } #endif в OSInitHookEnd Кодvoid  OSInitHookEnd (void) { #if OS_CPU_INT_DIS_MEAS_EN > 0     OS_CPU_IntDisMeasInit(); #endif      #if OS_CPU_FPU_EN > 0     OS_CPU_FP_Init();                            /* Initialize support for VFP register save / restore */ #endif в OSTaskCreateHook Кодvoid  OSTaskCreateHook (OS_TCB *ptcb) { #if OS_CPU_FPU_EN > 0     INT8U  err;     void  *pblk; #endif #if OS_CPU_FPU_EN > 0     if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {  /* See if task needs FP support                       */         pblk = OSMemGet(OSFPPartPtr, &err);      /* Yes, Get storage for VFP registers                 */         if (pblk != (void *)0) {                 /*      Did we get a memory block?                    */             ptcb->OSTCBExtPtr = pblk;            /*      Yes, Link to task's TCB                       */             OS_CPU_FP_Save(pblk);                /*           Save the VFP registers in block          */         }     } #endif в OSTaskDelHook Кодvoid  OSTaskDelHook (OS_TCB *ptcb) { #if OS_CPU_FPU_EN > 0     if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {            /* See if task had FP support               */         if (ptcb->OSTCBExtPtr != (void *)0) {              /* Yes, OSTCBExtPtr must not be NULL        */             OSMemPut(OSFPPartPtr, ptcb->OSTCBExtPtr);      /*      Return memory block to free pool    */         }     } #endif OSTaskSwHookКодvoid  OSTaskSwHook (void) {    #if OS_CPU_FPU_EN > 0     void  *pblk; #endif #if OS_CPU_FPU_EN > 0                                      /* Save VFP context of preempted task       */     if (OSRunning == OS_TRUE) {                            /* Don't save on OSStart()!                 */         if (OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {    /* See if task used FP                      */             pblk = OSTCBCur->OSTCBExtPtr;                  /* Yes, Get pointer to FP storage area      */             if (pblk != (void *)0) {                       /*      Make sure we have storage           */                 OS_CPU_FP_Save(pblk);                      /*      Save the VFP registers in block     */             }         }     }                                                            /* Restore VFP context of new task          */     if (OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) {    /* See if new task uses FP                  */         pblk = OSTCBHighRdy->OSTCBExtPtr;                  /* Yes, Get pointer to FP storage area      */         if (pblk != (void *)0) {                           /*      Make sure we have storage           */             OS_CPU_FP_Restore(pblk);                       /*      Get contents of VFP registers       */         }     } #endif 3. Включаю в опцыях проекта использование FPU 2.0 4. Тестовая задача: Кодfloat a =0; while(1){ .... ждем семафора if(a > 0.7) a = 0; a+=0.1; LedToggle(a*10); //переключаем диод, параметр ф-и  - номер диода. com_print("%lf", a); //выводим в порт значение "а" } Результат: 1. задачи работавшие паралельно - работают и далее, прекрасно, адекватно... 2. постоянно мигает 1й диод. 3. в порт получаю: 0.000000 Собственно помогите разобратся в чем проблема ? перелыл уже кучу всего. ничего не помогает