Jump to content

    

Digi

Свой
  • Content Count

    169
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Digi

  • Rank
    Частый гость
  • Birthday 07/10/1978

Контакты

  • Сайт
    Array
  • ICQ
    Array

Recent Profile Visitors

2704 profile views
  1. Вопрос так был сформулирован потому, что я многого не знал. Сейчас для себя нашёл удобный способ работы. Пишу проги сразу на удалённой машине с использованием VisualStudio code и расширения Remote SSH. VSCode кэширует файлы на локальной машине и при медленном и нестабильном инете работать достаточно комфортно. При необходимости скачиваю оттуда файлы по SCP при помощи SmartTTY. GDB пока не настроил, нет необходимости.
  2. Очередной косяк найден. Оказалось, что переменные объявлялись несколько раз, из-за этого их адреса перекрывались.
  3. Попробую упростить проект и перешлю. Но описание структуры и обращение к ней у меня правильно реализовано ? Или я что то не так понял и делаю недопустимые действия ?
  4. Причину падения нашёл. Её вызывает эта строчка st_stat_data[0].peak_levels[9] = 155; При её вызове перезаписывается переменная volatile uint16_t period_ms_cdg5; Разве я делаю неправильное обращение ? При выполнении записи пишет по адресу 0x8001d7f4 хотя, судя по регистрам, должен по другому адресу записать. Описана структура вот так: volatile typedef struct _station_status { double mean_comp_shift; uint32_t mean_levels[23]; uint32_t peak_levels[23]; uint32_t noise_levels[23]; uint8_t good_comps[23]; uint32_t comp_edges[23*2]; uint8_t n_good; uint8_t status_synhro[3]; //1й бит - цикл найден, 2й - точная подстройка выполнена, 3й - подстройка ои выполнена //float mean_phases[23]; } station_status; station_status st_stat_data[4]; map файл .scommon 0x000000008001d7e8 0x2c ./control.o 0x000000008001d7e8 alive_skip 0x000000008001d7ec portAnsCalibr 0x000000008001d7f0 prev_xtime 0x000000008001d7f4 period_ms_cdg5 0x000000008001d7f6 portAnsAutoFreqOI 0x000000008001d7f8 xtick_cntr 0x000000008001d7fc curr_time_msec 0x000000008001d800 addrDSTAnsAutoFreqOI 0x000000008001d804 xtime .... *(COMMON) COMMON 0x000000008001d940 0x7d0 ./_main.o 0x000000008001d940 st_stat_data 0x000000008001e100 head_stat_data COMMON 0x000000008001e110 0x80000 ./dprint.o 0x000000008001e110 Data COMMON 0x000000008009e110 0x0 ./hardware.o COMMON 0x000000008009e110 0x145478 ./reciever.o 0x000000008009e110 re_bank2 Дизассемблер: 999 st_stat_data[0].peak_levels[9] = 155; 0x8000fd0c: lui v0,0x8002 0x8000fd10: addiu v0,v0,-10600 0x8000fd14: li v1,155 0x8000fd18: sw v1,136(v0) v0 = 0x8001d698 v1 = 155 Вот ещё добавил запись двух переменных, пишет в одно и тоже место. В симуляторе эффект тот же. 366 period_ms_cdg5 =154; 0x800012ac: lui v0,0x8002 0x800012b0: li v1,154 0x800012b4: sh v1,-10440(v0) 367 st_stat_data[0].peak_levels[9] = 155; 0x800012b8: lui v0,0x8002 0x800012bc: addiu v0,v0,-10576 0x800012c0: li v1,155 0x800012c4: sw v1,136(v0)
  5. Когда значение переменной уже испорчено стек равен 0x9801ffe8. Вроде в норме. cram (rw!x) : ORIGIN = 0x98000000, LENGTH = 128K _estack = ORIGIN(cram) + LENGTH(cram); В CRAM кроме стека никто больше не обращается и не находится. Весь код и переменные в SDRAM. Видимо не там ищу. В коде используются некоторые моменты типа for (set = 0; n = *p++;) ... while (ch = *p++) ... это не ошибка, вроде так задумано (взято из готовых библиотек), проверю на всякий случай.
  6. 1) Да, кэширование включено. Использую сейчас ваш обработчик прерываний. В нём кэш сбразывается. 2) Возникновение исключения - это уже следствие. Перед тем как возникнуть исключению, происходит изменение переменной, которое меняться не должно. Это происходит через случайное время и только если я из прерывания пытаюсь вызывать какую либо функцию. Даже пустую. void int_handler() // функция обработчика прерывваний { ActiveIRQ0 = SYS_REG.QSTR0.data & SYS_REG.MASKR0.data; ActiveIRQ1 = SYS_REG.QSTR1.data & SYS_REG.MASKR1.data; ActiveIRQ2 = SYS_REG.QSTR2.data & SYS_REG.MASKR2.data; if (ActiveIRQ0 & (1 << 22)) // если есть прерывание от IT0 { IT0.ITCSR.bits.INT = 0; // сбрасываем флаг прерывания IT0.ITCSR.bits.EN = 1; // снова запускаем таймер timer_update(); } volatile unsigned int curr_time_msec; void timer_update() { // curr_time_msec++; } Если timer_update() не вызывать, а вместо этого написать curr_time_msec++ то работает. Но стоит вызвать любую функцию из прерывания, то через некоторое время - ошибка. А почему не сохраняются регистры k0 и k1, разве они в основном Си коде не используются ? timer_update: 800012d4: addiu sp,sp,-8 800012d8: sw s8,4(sp) 800012dc: move s8,sp 30 } 800012e0: move sp,s8 800012e4: lw s8,4(sp) 800012e8: nop 800012ec: addiu sp,sp,8 800012f0: jr ra 800012f4: nop В функции timer_update ничего криминального не вижу. Ещё вопрос, почему после eret ещё есть команды , если я правильно понимаю, то после eret ничего не будет выполнятся. ...... addi $sp, 32*4 # Deallocate saved context # Return from exception .set mips3 sync # settle things down eret # PC <= EPC; EXL <= 0 nop # just to be safe mfc0 $k1, $14 #save epc in gp 27 mfc0 $k0, $12 # Get STATUS xori $k0, 0x2 # allow interupts after eret mtc0 $k0, $12 # Put SR back nop j $k1 #go continue nop .set mips0 fault_exeption: FLUSH_CACHE SAVE_REGS # Save all registers in stack move $a0, $sp # Arg0: pointer to saved state lui $gp, RAM_HI # Set global pointer la $k0, fault_handler #exception code can be far away from internal memory jr $k0 # Jump to C code, no return
  7. Тем не менее проблема сохранилась, но уже более сложно диагностируемая. Опять появляется ошибка, но теперь - Address Save и указывает на адреса 0x0000****. Пока пытаюсь найти, что вызывает эту ошибку. Проявляется достаточно редко. Попробую добавить так же и сохранение регистров FPU
  8. Оказывается - да. В Элвисовском примере оказалась засада. С этой проблемой вопрос наверное решён. ))) Всем огромное спасибо !!! Исправил вот так.
  9. Думал об этом. По идее я его задаю уже выровненым. Использовал скрипт линковщика из uOS и немного исправлял, добавив свою память и точку входа. Кстати память внешней ПЛИС я в линковщике не указывал. Это правильно ? Обращаюсь я к ПЛИС так : #define FPGA_BASE 0xA8000000 // KernekSeg2 uncashed #define MANUAL_FREQ_REGS (FPGA_BASE + 0x0004) int SetFrequency(uint32_t freq) { *(volatile unsigned*)(MANUAL_FREQ_REGS) = freq; return 1; } Привожу фрагменты кода. Вдруг что нибудь бросится в глаза.
  10. Кто сможет объяснить особенности работы и подсказать правильную настройку компилятора и проца 1892ВМ10Я. Конфиг следующий: - Внешняя память SDRAM 32 бит, базовый адрес 0x80000000, kseg0 - ПЛИС с базовым адресом со стороны проца 0xA8000000 (обращение к её регистрам осуществляется как к памяти) Находится в не кэшируемой области. kseg1) До этого проект работал под uOS. Сейчас uOS убрал. Проблема такая: проект работает, но по не понятной причине вылетает с ошибкой Address Load, Addres Save. Вылетает очень редко, раз в несколько часов. Причём вылеты не зависят от того, что делает прога. (Хотя делает она всё время одно и то же). После того как убрал ОС, переписал обработчик прерывания, вылет локализовался. Происходит он в случае, когда я находясь в прерывании пытаюсь вызвать функцию у которой в качестве параметра передается double. Если вызываемая из прерывания функция ожидает тип данных не double, то работает нормально. Вылет (исключение) происходит с ошибкой Alddress Load и адрес указывает на стек. Та же самая функция, вызываемая не из прерывания работает нормально. double test(double a) // при вызове этой функции из прерывания - вылетает { return a*5; } double test(float a) // а эта работает нормально. { return a*5; } Кто может помочь работающими настройками, примером и.т.д. и вообще чем угодно ? PS: Я уже в полной растерянности. Кроме того как больше не применять такой проц - идей нет.....
  11. Всем спасибо, общая идея понятна. Буду разбираться с SSHFS , оно мне больше подходит.
  12. Не знаю, в ту ли ветку пишу, но назрел вопрос. Есть удалённая железка на Raspbian, на ней работают некоторые программные модули. На железке есть хреновый мобильный интернет и можно открыть несколько портов. Один порт открыт для SSH. Редактировать код, запускаемый на малине, необходимо с локального компа. Как автоматизировать процесс загрузки новых файлов с локальной машины и их запуск ? Кто нибудь такое делал ? Пока есть идея использовать в качестве облака - GitHub. Залить на него изменённый код, затем при помощи скрипта на малине, запускаемого через SSH, выполнить необходимые действия. Может есть какое либо более изящное решение ?
  13. Ясное дело, что ошибка у меня. Виснет не мьютекс, а функция работы с СД картой. Зависала в цикле ожидания какого-то состояния с карты (уже не помню какого именно) внутри низкоуровневой функции. Причём это происходило при работе с несколькими файлами. Сейчас работаю в один момент времени только с одним файлом. Но это временно )) Да, обращения к СД у меня блокировались мьютексами, но тем не менее проблема была. Поэтому и спросил, как это правильно реализовать. Планирую переосмыслить и переделать как положено )
  14. Так пытался делать, но либо чего то упустил, либо что то ещё. Иногда при обращении к карте, функция (уже не помню какая) зависала внутри. А кто нибудь такое, в такой конфигурации, реализовывал ?
  15. Пишу проект на STM32 с использованием FreeRTOS и для доступа к SD карте - FAT FS. У меня в проекте есть несколько задач, из которых я планирую записывать информацию в файлы на SD. Лог файлы, результаты. Таких файлов 3. Например логи будут писаться (дописываться) сразу из нескольких задач в один файл. Как правильно и красиво реализовать такое обращение ?