Перейти к содержанию
    

devnir

Новичок
  • Постов

    3
  • Зарегистрирован

  • Посещение

Репутация

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 Собственно помогите разобратся в чем проблема ? перелыл уже кучу всего. ничего не помогает
×
×
  • Создать...