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

Bulya

Участник
  • Постов

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

  • Посещение

Репутация

0 Обычный

Информация о Bulya

  • Звание
    Участник
    Участник
  • День рождения 23.12.1983

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array
  1. Если нужно отправить одну команду и вернуться в основной режим, то нужно просто синхронно выполнить одну функцию с отправкой этой команды. Но за "буквально" могут скрываться неприятные нюансы. Для того, чтобы при получении определенного сообщения завершить текущую итерацию, стек функций от корня итерации до чтения этого сообщения должен поддерживать код возврата, который обрабатывается как и любая нештатная ситуация и приводит к досрочному завершению текущей операции. Сложно что-то советовать когда непонятны критерии выбора решения. К чему такая экономия на задачах? Не хватает памяти? (При том, что судя по всему требуемый объем стека небольшой и легко прогнозируем.) Если итерацию основного режима все-равно нужно прервать, то в ней так или иначе необходима обработка исключений. А значит переключение режима должно эскалироваться как любая ошибка и приводить к началу новой итерации. И там в самом начале итерации должен проверяться какой-то флаг и обрабатываться "другой режим". А вообще нужно просто организовать задачу в виде стейт-машины. И все переключения режимов сразу станут штатными ситуациями. Проблемма, судя по всему в том, что задача принимает сообщения в разных местах кода или даже принимает сообщения из нескольких очередей. Это в принципе плохо - повышает количество гонок и вероятность взаминых блокировок. Нужно стремиться к тому, чтобы поток, обрабатывающий события, получал их в одном месте и из одного источника.
  2. Таск имеет один поток выполнения. Вам требуется либо два потока, либо два состояния. Если девайс должен переключатся между двумя режимами, то он может это делать переключение синхронно: - по окончании текущей итерации (проверка флага в начале тела цикла); - либо в определенных контрольных точках (между функциями или внутри них, но тогда нужно предусмотреть код возврата, проверяемый во внешнем цикле после каждой функции). При синхронном обнаружении переключения режима: - выход из цикла и переход к исполнению соответстующего кода (имплементация кооперативной многопоточности); - либо, если "другой режим" относительно кратковременный и из него нужно возобновить работу в основном цикле, можно просто синхронно вызвать функцию работы этого режима (иммитация програмного прерывания). В любом случае это будет компромисс между величиной плохо детерминируемой задержки (между обнаружением смены режима в прерывании и "переключением" таска) и сложностью поддержки кода (многократные проверки смены режима и его обработка, разбросанные по коду). Но зачем нужны увечные велосипеды, если можно использовать детерминированные подходы: - два отдельных потока (если режимы независимы и между ними нужно переключаться, возобновляя прерванную работу); - машина состояний (если переключение режима должно полностью прекратить текущую работу). Но для машины состояний нужно, чтобы все входные сообщения для таска шли через одну очередь. Тогда в начале цикла производится ожидание сообщения и затем - выбор функции обработчика в зависимости от режима и его состояния.
  3. Что-то долго без ответа. Уже, наверное, и не актуально. Исходя из описания, "другой режим" должен быть реализован как другой таск. Скорее всего с более высоким приоритетом, чем первый. Этот другой таск должен проинициализироваться и заблокироваться любым примитивом синхранизации (семафор, ивент, чтение очереди - в завсимости от необходимости передачи ему данных из прерывания) В прерывании по сообщеню смены режима этот таск должен будиться. Если его приоритет выше - он начнет выполнятся сразу по выходу из прерывания. Остальные детали зависят от того, есть ли у него общие данные с основным режимом и нужно ли будет потом вернутся в основной режим (и с какого момента продолжить выполнение).
  4. размеры стека и кучи определены в define symbol __ICFEDIT_size_cstack__ = 0x2000; define symbol __ICFEDIT_size_heap__ = 0x200; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; все остальное - статические переменные, созданные в программе define symbol __region_NAND_RAM_start__ = 0x20100000; define symbol __region_NAND_RAM_end__ = 0x2010107F; define region NAND_RAM_region = mem:[from __region_NAND_RAM_start__ to __region_NAND_RAM_end__]; Но определять какие секции должны лечь в этот регион надо в .icf самому. Можно, например, перенести туда из RAM1_region стек и кучу: place in NAND_RAM_region { block HEAP, block CSTACK }; или какие-то крупные объекты, которые легко выделить в отдельную секцию через #pragma location = "NAND_RAM_section" place in NAND_RAM_region { section NAND_RAM_section }; Именно в .map и нужно смотреть на что расходуется память.
  5. pragma всегда относится к следующему за ним определению. #pragma location задает секцию, в которую должен быть помещен определяемый объектю Вы кроме TempStorage помещаете в RAM0_region все статические переменные и кучу надо place in RAM0_region { section TempStorage }; place in RAM1_region { readwrite, block HEAP, block CSTACK };
  6. в скрипте линкера должны быть объявлены регионы SRAM define region SRAM0 = Mem:[from 0x20000000 size 32K]; define region SRAM1 = Mem:[from 0x20080000 size 16K]; в .icf place in SRAM0 { section TempStorage }; place in SRAM1 { readwrite, block CSTACK, ... }; в .с #pragma location = "TempStorage" unsigned char Buf[0x8000]; в .icf place in SRAM0 { readwrite, block CSTACK, ... }; place in SRAM1 { section SRAM1_data }; в .с unsigned char Buf0[0x4000]; #pragma location = "SRAM1_data" unsigned char Buf1[0x4000];
  7. FatFs на SAM9260

    да, запоминающее устройство может иметь собственный кеш (например в DataFlash), используемый драйвером. эта команда его должна выгрузить. FatFs дергает ее при синхронизации с накопителем
  8. FatFs на SAM9260

    Если выполняется кеширование записи - кеш (если в нем были изменения) нужно выгрузить.
  9. Спасибо. Действительно, четыре дня назад в CVS http://sources.redhat.com/newlib/ появилась ревизия libgloss/arm/linux-syscalls0.S, в которой выбросили весь код для __thumb__. Пропатченная библиотека собралась.
  10. Здравствуйте. Собираю binutils-2.20, gcc-4.3.4, newlib-1.17.0 с ключами --target=arm-elf --enable-interwork --enable-multilib --enable-languages="c,c++" --with-gnu-as --with-gnu-ld --disable-shared --disable-nls --disable-newlib-supplied-syscalls --disable-newlib-io-float компиляция newlib прекращается с ошибками в linux-syscalls0.S .../newlib-1.17.0/libgloss/arm/linux-syscalls0.S:37: Error: missing expression -- `swi' .../newlib-1.17.0/libgloss/arm/linux-syscalls0.S:102: Error: missing expression -- `swi' ... linux-syscalls0.S: #include "linux-syscall.h" #if __thumb__ # define FUNC(name) .type name, %function; .thumb_func; name: # define SET .thumb_set #else # define FUNC(name) .type name, %function; name: # define SET .set #endif #define GLOBAL(name) .global name; FUNC(name) #define SIZE(name) .size name, .-name #if __thumb__ # define SYSCALL0(name) \ GLOBAL(_ ## name); \ mov r12, r7; \ mov r7, #SYS_ ## name; \ swi; \ mov r7, r12; \ b _set_errno; \ SIZE(_ ## name) /* static int _syscall3(int a, int b, int c, int number); */ FUNC(_syscall3) push { r7 } mov r7, r3 swi pop { r7 } b _set_errno SIZE(_syscall3) # define SYSCALL3(name) \ GLOBAL(_ ## name); \ mov r3, #SYS_ ## name; \ b _syscall3; \ SIZE(_ ## name) # define SYSCALL6(name) \ GLOBAL(_ ## name); \ push { r4 - r5, r7 }; \ ldr r4, [sp, #12]; \ ldr r5, [sp, #16]; \ mov r7, #SYS_ ## name; \ swi; \ pop { r4 - r5, r7 }; \ b _set_errno; \ SIZE(_ ## name) # define SYSCALL4(name) SYSCALL6(name) #else /* __thumb__ */ # define SYSCALL4(name) \ GLOBAL(_ ## name); \ swi #SYS_ ## name; \ b _set_errno; \ SIZE(_ ## name) # define SYSCALL6(name) \ GLOBAL(_ ## name); \ push { r4 - r5 }; \ ldr r4, [sp, #8]; \ ldr r5, [sp, #12]; \ swi #SYS_ ## name; \ pop { r4 - r5 }; \ b _set_errno; \ SIZE(_ ## name) #define SYSCALL0(name) SYSCALL3(name) #define SYSCALL3(name) SYSCALL4(name) #endif /* __thumb__ */ #define SYSCALL1(name) SYSCALL3(name) #define SYSCALL2(name) SYSCALL3(name) #define SYSCALL5(name) SYSCALL6(name) SYSCALL1(alarm) SYSCALL1(brk) SYSCALL1(chdir) SYSCALL2(chmod) SYSCALL3(chown) SYSCALL1(close) SYSCALL1(dup) SYSCALL2(dup2) SYSCALL3(execve) SYSCALL1(exit) SYSCALL3(fcntl) SYSCALL2(fstat) SYSCALL2(ftruncate) SYSCALL3(getdents) SYSCALL0(getegid) SYSCALL0(geteuid) SYSCALL0(getgid) SYSCALL2(getgroups) SYSCALL1(getpgid) SYSCALL0(getpgrp) SYSCALL0(getpid) SYSCALL0(getuid) SYSCALL2(gettimeofday) SYSCALL3(ioctl) SYSCALL2(kill) SYSCALL3(lchown) SYSCALL2(link) SYSCALL3(lseek) SYSCALL2(lstat) SYSCALL2(mkdir) SYSCALL3(mknod) SYSCALL2(nanosleep) SYSCALL3(open) SYSCALL0(pause) SYSCALL1(pipe) SYSCALL3(read) SYSCALL3(readlink) SYSCALL4(reboot) SYSCALL1(rmdir) SYSCALL5(select) SYSCALL2(setpgid) SYSCALL1(setgid) SYSCALL0(setsid) SYSCALL1(setuid) SYSCALL3(sigprocmask) SYSCALL2(socketcall) SYSCALL2(stat) SYSCALL1(stime) SYSCALL2(symlink) SYSCALL1(sync) SYSCALL1(sysinfo) SYSCALL1(times) SYSCALL2(truncate) SYSCALL1(umask) SYSCALL1(uname) SYSCALL1(unlink) SYSCALL2(utime) SYSCALL0(vfork) SYSCALL4(wait4) SYSCALL3(write) т.е. передача номера прерывания через регистр r7 (в __thumb__), а не в инструкции swi вызывает ошибку. Что характерно, системные вызовы linux мне вообще не нужны для arm-elf. Подскажите, пожалуйста, решение проблемы (правильную конфигурацию при сборке или правильный синтаксис системных вызовов).
  11. Надеюсь, поста в этой ветке достаточно будет.
  12. Неужели тема заглохнет так и не сформировав решения? Задача распространенная и не вполне очевидная. Хотелось бы чтоб специалисты таки высказали свое решение.
  13. PVI5033 по цене порядка 5 USD дороговато будет Я конечно понимаю, что USB в качестве стабильного источника питания 5-вольтовых устройств не годится, но в штатном режиме работа от него и не предполагается, основная задача USB - запись/чтение конфигурации/логов при обслуживании (там питание 3,3В), но при этом, как минимум, должны работать pull-up 5V и все цепи ввода-вывода. А сброс 5-вольтового контроллера по собственной БОД или от внешнего супервизора можно отследить и впоследствии провести реинициализацию. Зато работа от DC/DC 5V (точность 1%) - штатный режим и сбросов контроллера с требованиями 5% быть не должно. может быть такой вариант? компараторы с открытым коллектором И как будет реагировать линейный стабилизатор при отсутствии напряжения на входе и наличии на вхыходе (насколько я понимаю - ток через него будет небольшим (на его входе мост)) или его тоже нужно отключать?
  14. Данная схема "родилась" в поисках наиболее дешевого решения коммутации питания на доступных элементах. Конденсаторы на затворах действительно лишние - сглупил. Резервирование питания на входе стабилизатора приведет к недопустимому падению напряжения на его выходе, а DC/DC с КПД порядка 70% и линейным стабилизатором следом - слишком большое увеличение тока источника, они и так великоваты (один из источников - 3Вт DC/DC(т.е. max 600мА), другой - шина USB(500мА)). Я сам подумываю о включении делителей на входах компараторов - это позволит гарантированно отключать их при подключенном основном источнике. Но хотелось бы еще жестко определить приоритет между дополнительными. (Конденсаторы в питании - само собой) А гистерезис компараторов - это ж величины порядка десятков миливольт, в пределаз 100-150мВ вполне допустимо. Предложите, пожалуйста, более удачный вариант (по возможности недорогой).
  15. Не хочется плодить подобные темы, поэтому возрождаю эту. У меня все та же задача - резервирование питания 5В. Допустимое отклонение 3%, потребляемый ток 100-600мА Хотелось бы узнать работоспособность предложенного варианта транзисторы, например, IRF7316 или подобные в качестве компаратора - что-то вродеLM293 Требуется ли ограничение в цепях компаратора Буду благодарен за отклик.
×
×
  • Создать...