Kopa 0 4 июня, 2009 Опубликовано 4 июня, 2009 (изменено) · Жалоба Вопрос пока не до конца понятный с прерываниями. Схемы при обработке прерываний могут иметь отличия. И с ними всегда не всё однозначно:) Как бы это дело оптимизировать. То есть сохранять именно те регистры, которые мы собираемся испортить. Или просто ограничить использование общих регистров в базовых словах и сохранять их все? если реализация сделана через исполнитель ссылок слов ( байт-кодов), то наверное, использовать последний описанный вариант, Обычно вершина стека данных - это один регистр, остальная часть через указатель + 2-3 регистра ( оценочно) интенсивного использования в примитивах. но при этом если необходим базис ядра, то возможно придётся использовать указатель на отдельную область обработчика и предусмотреть его ( их ) переключение. 1-й вариант, наверное, тоже можно использовать. P.S. Если требуется мультизадачность, то простейший вариант - кооперативная:) ( в tinyboot она используется ) Изменено 4 июня, 2009 пользователем Kopa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
chu 0 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба P.S. Если требуется мультизадачность, то простейший вариант - кооперативная:) Еще раз об SWiftX/MSP430(Evaluation, канешн;)) В комлекте есть подробные доки, где все доступно изложено. В частности прерывания и мультизадачность идут рука об руку. SECTION 5: THE SWIFTOS MULTITASKING EXECUTIVE 5.2.2 Interrupts and Tasks "Interrupt routines are often used to awaken tasks. A common way to perform complex, non-critical interrupt servicing is to have the interrupt routine perform all time-critical operations, and then store WAKE into a task’s STATUS." PS. Moving Forth Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 4 июня, 2009 Опубликовано 4 июня, 2009 · Жалоба P.S. Если требуется мультизадачность, то простейший вариант - кооперативнаяsmile.gif ( в tinyboot она используется ) Да нет, хотелось бы рилтайм :) а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся. Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kopa 0 4 июня, 2009 Опубликовано 4 июня, 2009 (изменено) · Жалоба Да нет, хотелось бы рилтайм :) а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся. Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное. Надо смотреть на использование регистров в примитивах. ( у нас же не стековый контроллер:) и произвольное использование без чёткого контроля ( если ничего не сохранять, а в прерывании использовать отдельные регистры) вряд ли получится. А так мысль здравая, при начальном сохранении 2-3х требуемых регистров. P.S. Реальная мультизадачность в Форт системе должна быть легче в реализации. Изменено 4 июня, 2009 пользователем Kopa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
chu 0 4 июня, 2009 Опубликовано 4 июня, 2009 (изменено) · Жалоба Уважаемые участники, а приведите плз., кто владеет этим языком, так, хотя бы ради интереса, код вычисления контрольной суммы CRC16 на форте ? Просто интересно сравнить с привычными решениями на Ц. Есть CRC8, делал для 1-wire, по документу AVR318 ATMEL Application Note.Rev.2579A-AVR-09/04 ( page_17). 0x18 VALUE POLYNOM 0x80 CONSTANT MSB# 0x01 CONSTANT LSB# : LSB LSB# AND ; : CRC8 8 0 DO 2DUP LSB SWAP LSB XOR IF SWAP POLYNOM XOR 1 RSHIFT MSB# OR ELSE SWAP 1 RSHIFT THEN SWAP 1 RSHIFT LOOP DROP ; Если данные находятся в стеке: \ ( ... d[n] d[n-1] ... d[1] 's n --- crc ) : CRC 0 ?DO SWAP CRC8 LOOP ; где: d[] - байты данных; 's - ноль; n - количество данных в стеке Если данные находятся в памяти: : CRC ( 's addr n -- crc ) \ 's - seed=0 ; addr - адрес начала блока данных; n - количество байтов OVER + SWAP ( 's addr2 addr1 ) DO I C@ CRC8 LOOP ; А следующий фрагмент я использовал для построения таблицы ( табличный метод получения CRC8 ) \ \ построение таблицы crc8 \ : crc8tab ( -- ) CR ." crc8tab:" CR 0 0x100 0 DO DUP I CRC8 I 0x8 /MOD DROP 0= IF CR 0x09 EMIT ." DB" 0x09 EMIT THEN ." 0x" .XB ." , " LOOP DROP ; при котором входной байт используется как индекс в таблице значений контрольной суммы. Вот, как-то так. Да, забыл: : .XB BASE @ >R HEX 0 <# # # #> TYPE SPACE R> BASE ! ; это печать байта в шестнадцатиричном виде. Таблица напечаталась вот такая: crc8tab: DB 0x00 , 0x5E , 0xBC , 0xE2 , 0x61 , 0x3F , 0xDD , 0x83 DB 0xC2 , 0x9C , 0x7E , 0x20 , 0xA3 , 0xFD , 0x1F , 0x41 DB 0x9D , 0xC3 , 0x21 , 0x7F , 0xFC , 0xA2 , 0x40 , 0x1E DB 0x5F , 0x01 , 0xE3 , 0xBD , 0x3E , 0x60 , 0x82 , 0xDC DB 0x23 , 0x7D , 0x9F , 0xC1 , 0x42 , 0x1C , 0xFE , 0xA0 DB 0xE1 , 0xBF , 0x5D , 0x03 , 0x80 , 0xDE , 0x3C , 0x62 DB 0xBE , 0xE0 , 0x02 , 0x5C , 0xDF , 0x81 , 0x63 , 0x3D DB 0x7C , 0x22 , 0xC0 , 0x9E , 0x1D , 0x43 , 0xA1 , 0xFF DB 0x46 , 0x18 , 0xFA , 0xA4 , 0x27 , 0x79 , 0x9B , 0xC5 DB 0x84 , 0xDA , 0x38 , 0x66 , 0xE5 , 0xBB , 0x59 , 0x07 DB 0xDB , 0x85 , 0x67 , 0x39 , 0xBA , 0xE4 , 0x06 , 0x58 DB 0x19 , 0x47 , 0xA5 , 0xFB , 0x78 , 0x26 , 0xC4 , 0x9A DB 0x65 , 0x3B , 0xD9 , 0x87 , 0x04 , 0x5A , 0xB8 , 0xE6 DB 0xA7 , 0xF9 , 0x1B , 0x45 , 0xC6 , 0x98 , 0x7A , 0x24 DB 0xF8 , 0xA6 , 0x44 , 0x1A , 0x99 , 0xC7 , 0x25 , 0x7B DB 0x3A , 0x64 , 0x86 , 0xD8 , 0x5B , 0x05 , 0xE7 , 0xB9 DB 0x8C , 0xD2 , 0x30 , 0x6E , 0xED , 0xB3 , 0x51 , 0x0F DB 0x4E , 0x10 , 0xF2 , 0xAC , 0x2F , 0x71 , 0x93 , 0xCD DB 0x11 , 0x4F , 0xAD , 0xF3 , 0x70 , 0x2E , 0xCC , 0x92 DB 0xD3 , 0x8D , 0x6F , 0x31 , 0xB2 , 0xEC , 0x0E , 0x50 DB 0xAF , 0xF1 , 0x13 , 0x4D , 0xCE , 0x90 , 0x72 , 0x2C DB 0x6D , 0x33 , 0xD1 , 0x8F , 0x0C , 0x52 , 0xB0 , 0xEE DB 0x32 , 0x6C , 0x8E , 0xD0 , 0x53 , 0x0D , 0xEF , 0xB1 DB 0xF0 , 0xAE , 0x4C , 0x12 , 0x91 , 0xCF , 0x2D , 0x73 DB 0xCA , 0x94 , 0x76 , 0x28 , 0xAB , 0xF5 , 0x17 , 0x49 DB 0x08 , 0x56 , 0xB4 , 0xEA , 0x69 , 0x37 , 0xD5 , 0x8B DB 0x57 , 0x09 , 0xEB , 0xB5 , 0x36 , 0x68 , 0x8A , 0xD4 DB 0x95 , 0xCB , 0x29 , 0x77 , 0xF4 , 0xAA , 0x48 , 0x16 DB 0xE9 , 0xB7 , 0x55 , 0x0B , 0x88 , 0xD6 , 0x34 , 0x6A DB 0x2B , 0x75 , 0x97 , 0xC9 , 0x4A , 0x14 , 0xF6 , 0xA8 DB 0x74 , 0x2A , 0xC8 , 0x96 , 0x15 , 0x4B , 0xA9 , 0xF7 DB 0xB6 , 0xE8 , 0x0A , 0x54 , 0xD7 , 0x89 , 0x6B , 0x35 я ее тупо воткнул в исходник на асме. \ Табличный метод CRC8: : CRC ( c -- crc ) 0xFF AND crc8tab + C@ ; Вот, собственно и все. А CRC16 - аналогичным образом, только полином другой и сдвигов побольше... PS. Примеры реальные, использовал российский SP-Forth4 Изменено 4 июня, 2009 пользователем chu Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба Я от форта просто тащусь! Весь процессор как на ладони, без никаких отладчиков и спецпакетов! Голым терминалом через голый уарт! Вопрос возник такого плана. Как соорудить конструкцию типа сишного #ifndef и подобных директив препроцессора? Поясняю. Вчера написал слово OR! и AND! : AND! (Addr Mask --) >R DUP @ R> AND SWAP !; : OR! (Addr Mask --) >R DUP @ R> OR SWAP !; : ? @ .; Работает, но логичнее написать на ассемблере. так вот, как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
chu 0 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения? В разных системах по-разному, я думаю. В SPF4, например, можно так: [DEFINED] AND! NOT [iF] : AND! ... ; [THEN] Я от форта просто тащусь! Уррраааа!!! Фортеров прибыло :1111493779: PS.Moving Forth Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба В разных системах по-разному, я думаю. В SPF4, например, можно так: [DEFINED] AND! NOT [iF] : AND! ... ; [THEN] А как самому определить эти [DEFINED],[iF] и [THEN]? а заодно и [ELSE]? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
chu 0 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба А как самому определить эти [DEFINED],[iF] и [THEN]? а заодно и [ELSE]? А для этого надо свою форт-систему писать , я думаю. PS. Moving Forth. : AND! (Addr Mask --) >R DUP @ R> AND SWAP !; : OR! (Addr Mask --) >R DUP @ R> OR SWAP !; : ? @ .; Работает, но логичнее написать на ассемблере. Логичнее, конечно, но код типа: and #mask,&address ... or #mask,&address генерит (для embedded) только кросс-компилер ( /оптимизатор). А CamelForth' у такое не под силу :crying: ЗЫ. Двигаюсь Дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kopa 0 5 июня, 2009 Опубликовано 5 июня, 2009 (изменено) · Жалоба Я от форта просто тащусь! Весь процессор как на ладони, без никаких отладчиков и спецпакетов! Голым терминалом через голый уарт! Супер! Вопрос возник такого плана. Как соорудить конструкцию типа сишного #ifndef и подобных директив препроцессора? Соорудить используя возможности Форт языка, но обычно те или иные решения существуют в разных Форт системах для SPF4 - близкий аналог REQUIRED ... если нужное слово уже загружено, то повторно из заданой библиотеки не грузить ( но тут могут возникнуть коллизиии если семантика загруженного слова отличается от необходимой ) в других Форт системах, часто вводят в употребление слово [DEFINED] СЛОВО оставляющее на стеке во время трансляции кода значение флага. Поясняю. Вчера написал слово OR! и AND! : AND! (Addr Mask --) >R DUP @ R> AND SWAP !; : OR! (Addr Mask --) >R DUP @ R> OR SWAP !; : ? @ .; Работает, но логичнее написать на ассемблере. Замечание: последовательность параметров для AND! ( Mask Addr -- ) привычнее \ по аналогии со словами ! +! например так: : AND! ( Mask Addr -- ) DUP >R @ AND R> ! ; и на ассемблере это слово логичнее сделать:) А если оптимизатору этот код дать, то не факт, что это превратится в одну команду процессора так вот, как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения? Можно воспользоваться, например, словом FIND при его наличии. ( комментарии из SPF4 и стандарта 94г.) FIND ( addr u -- addr u 0 | xt 1 | xt -1 ) \ 94 SEARCH \ Расширить семантику FIND следующим: \ Искать определение с именем, заданным строкой addr u. \ Если определение не найдено после просмотра всех списков в порядке поиска, \ возвратить addr u и ноль. Если определение найдено, возвратить xt. \ Если определение немедленного исполнения, вернуть также единицу (1); \ иначе также вернуть минус единицу (-1). Для данной строки, значения, \ возвращаемые FIND во время компиляции, могут отличаться от значений, \ возвращаемых не в режиме компиляции. А дальше используя [iF] ... [ELSE] ... [THEN] Изменено 5 июня, 2009 пользователем Kopa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба А для этого надо свою форт-систему писать biggrin.gif , я думаю. Эх, с чужой бы разобраться... В синтаксисе я пока что двоечник и чайник. Вот кучу интересных слов обнаружил. Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты. ; STACK OPERATIONS ;C DUP x -- x x duplicate top of stack HEADER DUP,3,'DUP',DOCODE PUSHTOS: SUB #2,PSP ; 1 push old TOS.. MOV TOS,0(PSP) ; 4 ..onto stack NEXT ; 4 ;C ?DUP x -- 0 | x x DUP if nonzero HEADER QDUP,4,'?DUP',DOCODE CMP #0,TOS ; 1 test for TOS nonzero JNZ PUSHTOS ; 2 NODUP: NEXT ; 4 ;C DROP x -- drop top of stack HEADER DROP,4,'DROP',DOCODE MOV @PSP+,TOS ; 2 NEXT ; 4 ;C SWAP x1 x2 -- x2 x1 swap top two items HEADER SWAP,4,'SWAP',DOCODE MOV @PSP,W ; 2 MOV TOS,0(PSP) ; 4 MOV W,TOS ; 1 NEXT ; 4 ;C OVER x1 x2 -- x1 x2 x1 per stack diagram HEADER OVER,4,'OVER',DOCODE MOV @PSP,W ; 2 SUB #2,PSP ; 2 MOV TOS,0(PSP) ; 4 MOV W,TOS ; 1 NEXT ; 4 ;C ROT x1 x2 x3 -- x2 x3 x1 per stack diagram HEADER ROT,3,'ROT',DOCODE MOV @PSP,W ; 2 fetch x2 MOV TOS,0(PSP) ; 4 store x3 MOV 2(PSP),TOS ; 3 fetch x1 MOV W,2(PSP) ; 4 store x2 NEXT ; 4 ;X NIP x1 x2 -- x2 per stack diagram HEADER NIP,3,'NIP',DOCODE ADD #2,PSP ; 1 NEXT ; 4 ;C >R x -- R: -- x push to return stack HEADER TOR,2,'>R',DOCODE PUSH TOS MOV @PSP+,TOS NEXT ;C R> -- x R: x -- pop from return stack HEADER RFROM,2,'R>',DOCODE SUB #2,PSP ; 2 MOV TOS,0(PSP) ; 4 MOV @RSP+,TOS NEXT ;C R@ -- x R: x -- x fetch from rtn stk HEADER RFETCH,2,'R@',DOCODE SUB #2,PSP MOV TOS,0(PSP) MOV @RSP,TOS NEXT ;Z SP@ -- a-addr get data stack pointer HEADER SPFETCH,3,'SP@',DOCODE SUB #2,PSP MOV TOS,0(PSP) MOV PSP,TOS NEXT ;Z SP! a-addr -- set data stack pointer HEADER SPSTORE,3,'SP!',DOCODE MOV TOS,PSP MOV @PSP+,TOS ; 2 NEXT ;Z RP@ -- a-addr get return stack pointer HEADER RPFETCH,3,'RP@',DOCODE SUB #2,PSP MOV TOS,0(PSP) MOV RSP,TOS NEXT ;Z RP! a-addr -- set return stack pointer HEADER RPSTORE,3,'RP!',DOCODE MOV TOS,RSP MOV @PSP+,TOS ; 2 NEXT ;X TUCK x1 x2 -- x2 x1 x2 per stack diagram HEADER TUCK,4,'TUCK',DOCOLON DC16 SWAP,OVER,EXIT Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kopa 0 5 июня, 2009 Опубликовано 5 июня, 2009 (изменено) · Жалоба А как самому определить эти [DEFINED],[iF] и [THEN]? а заодно и [ELSE]? В Форт системе существует доступ к входному потоку текущей транслируемой программы ( слова SOURCE TIB #TIB >IN ACCEPT и возможно другие ) и механизм IMMEDIATE слов и доступ к STATE переменной состояния системы. не забываем также про [ и ] P.S. Это достаточно мощные средства для создания Форт расширений. Но это, часто, для небольших контроллеров лучше использовать в кросс системе или наращивать внутреннюю программную память ( можно и оптимизатор туда поместить :) 60Кб Flash для реализации полноценной Форт системы - это, впрочем, достаточно много. ( пример 32-разрядный spf4, с кучей возможностей, для Windows ~100Кб где половину занимает оптимизатор ) Эх, с чужой бы разобраться... В синтаксисе я пока что двоечник и чайник. В Форте почти нет синтаксиса. В асме его гораздо больше:) А с чужим кодом, в силу тех или иных ограничений при реализации и индивидуальности разработки, воспринимаемость может ухудшиться:) Вот кучу интересных слов обнаружил. ... Эти слова стандартные примитивы Форт систем:) Слова сгруппированы по функциональности и можно порекомендовать составлять словарик изученных слов:) Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты. Почти все Форт системы, исключая немногочисленное количество коммерческих, имеют открытые исходники:) Да и в комерческих много открытого кода. ( вопрос только в лицензии использования ) Изменено 5 июня, 2009 пользователем Kopa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
chu 0 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба Эх, с чужой бы разобраться... Этопуть, по которому проходит каждый фортер. В синтаксисе я пока что двоечник и чайник. Ну какой синтаксис в форте? Примитивнейший. И это есть плюс+плюс. Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты. А простота и доступность понимания реализации форта - величайшее достижение человечества в технологии программирования. PS. Moving Forth Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kopa 0 5 июня, 2009 Опубликовано 5 июня, 2009 (изменено) · Жалоба Вчера написал слово OR! и AND! Работает, но логичнее написать на ассемблере. для Сamel по аналогии с ! ;C AND! x a-addr -- and cell in memory HEADER AND!,4,'AND!',DOCODE AND @PSP+,0(TOS) MOV @PSP+,TOS NEXT Вроде должно работать:) Изменено 5 июня, 2009 пользователем Kopa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 23 5 июня, 2009 Опубликовано 5 июня, 2009 · Жалоба : Pulse ( Addr Mask --) 2DUP OR! FFFF XOR AND! ; Формирует импульс длительностью 23 мкс при тактировании от DCO (4.8МГц) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться