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

А вот бы на FORTH написать...

Вопрос пока не до конца понятный с прерываниями.

 

Схемы при обработке прерываний могут иметь отличия.

И с ними всегда не всё однозначно:)

 

Как бы это дело оптимизировать.

То есть сохранять именно те регистры, которые мы собираемся испортить.

Или просто ограничить использование общих регистров в базовых словах и сохранять их все?

 

если реализация сделана через исполнитель ссылок слов ( байт-кодов),

то наверное, использовать последний описанный вариант,

Обычно вершина стека данных - это один регистр, остальная часть через указатель

+ 2-3 регистра ( оценочно) интенсивного использования в примитивах.

 

но при этом если

необходим базис ядра, то возможно придётся использовать указатель на

отдельную область обработчика и предусмотреть его ( их ) переключение.

 

1-й вариант, наверное, тоже можно использовать.

 

P.S. Если требуется мультизадачность, то простейший вариант - кооперативная:)

( в tinyboot она используется )

Изменено пользователем Kopa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

P.S. Если требуется мультизадачность, то простейший вариант - кооперативнаяsmile.gif

( в tinyboot она используется )

Да нет, хотелось бы рилтайм :)

а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся.

Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да нет, хотелось бы рилтайм :)

а что, если примитивы языка использовать в критических секциях? Ведь между словами в регистрах ничего не передаётся.

Конечно, будут затраты на EINT - DINT в каждом слове, зато переключение контекста практически мгновенное.

 

Надо смотреть на использование регистров в примитивах. ( у нас же не стековый контроллер:)

и произвольное использование без чёткого контроля ( если ничего не сохранять, а

в прерывании использовать отдельные регистры) вряд ли получится.

А так мысль здравая, при начальном сохранении 2-3х требуемых регистров.

 

 

 

P.S. Реальная мультизадачность в Форт системе должна быть легче в реализации.

Изменено пользователем Kopa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уважаемые участники, а приведите плз., кто владеет этим языком, так, хотя бы ради интереса, код вычисления контрольной суммы 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

Изменено пользователем chu

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я от форта просто тащусь!

Весь процессор как на ладони, без никаких отладчиков и спецпакетов!

Голым терминалом через голый уарт!

 

Вопрос возник такого плана.

Как соорудить конструкцию типа сишного #ifndef и подобных директив препроцессора?

Поясняю.

Вчера написал слово OR! и AND!

: AND! (Addr Mask --)
    >R DUP @ R> AND SWAP !;
: OR! (Addr Mask --)
    >R DUP @ R> OR SWAP !;
: ? @ .;

Работает, но логичнее написать на ассемблере.

так вот, как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как сделать, чтобы в системах, где эти слова определены, они не определялись, а где нет - вставлялись определения?

 

 

В разных системах по-разному, я думаю. В SPF4, например, можно так:

 

[DEFINED] AND! NOT [iF]

 

: AND! ... ;

 

[THEN]

 

Я от форта просто тащусь!

 

Уррраааа!!!

Фортеров прибыло :1111493779:

 

PS.Moving Forth

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В разных системах по-разному, я думаю. В SPF4, например, можно так:

[DEFINED] AND! NOT [iF]

: AND! ... ;

[THEN]

А как самому определить эти [DEFINED],[iF] и [THEN]?

а заодно и [ELSE]?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как самому определить эти [DEFINED],[iF] и [THEN]?

а заодно и [ELSE]?

 

А для этого надо свою форт-систему писать :biggrin: , я думаю.

 

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:

 

ЗЫ. Двигаюсь Дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я от форта просто тащусь!

Весь процессор как на ладони, без никаких отладчиков и спецпакетов!

Голым терминалом через голый уарт!

 

Супер!

 

 

Вопрос возник такого плана.

Как соорудить конструкцию типа сишного #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]

Изменено пользователем Kopa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А для этого надо свою форт-систему писать 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как самому определить эти [DEFINED],[iF] и [THEN]?

а заодно и [ELSE]?

 

В Форт системе существует доступ к входному потоку текущей транслируемой программы

( слова SOURCE TIB #TIB >IN ACCEPT и возможно другие )

и механизм IMMEDIATE слов и доступ к STATE переменной состояния системы.

не забываем также про [ и ]

 

P.S. Это достаточно мощные средства для создания Форт расширений.

Но это, часто, для небольших контроллеров лучше использовать в кросс системе

или наращивать внутреннюю программную память ( можно и оптимизатор туда поместить :)

60Кб Flash для реализации полноценной Форт системы - это, впрочем, достаточно много.

( пример 32-разрядный spf4, с кучей возможностей, для Windows ~100Кб где половину занимает

оптимизатор )

 

Эх, с чужой бы разобраться...

В синтаксисе я пока что двоечник и чайник.

 

В Форте почти нет синтаксиса. В асме его гораздо больше:)

 

А с чужим кодом, в силу тех или иных ограничений при реализации и

индивидуальности разработки, воспринимаемость может ухудшиться:)

 

Вот кучу интересных слов обнаружил.

...

 

Эти слова стандартные примитивы Форт систем:)

Слова сгруппированы по функциональности и можно порекомендовать составлять

словарик изученных слов:)

 

Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты.

 

Почти все Форт системы, исключая немногочисленное количество коммерческих,

имеют открытые исходники:)

Да и в комерческих много открытого кода. ( вопрос только в лицензии использования )

Изменено пользователем Kopa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эх, с чужой бы разобраться...

 

Этопуть, по которому проходит каждый фортер.

 

В синтаксисе я пока что двоечник и чайник.

 

Ну какой синтаксис в форте? Примитивнейший. И это есть плюс+плюс.

 

Опять же, всё на виду! Можно "открыть ящик" и посмотреть, какие в нём инструменты.

 

А простота и доступность понимания реализации форта - величайшее достижение человечества в технологии программирования. :biggrin:

 

 

PS. Moving Forth

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вчера написал слово 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

 

Вроде должно работать:)

Изменено пользователем Kopa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

: Pulse ( Addr Mask --)

2DUP OR! FFFF XOR AND! ;

 

Формирует импульс длительностью 23 мкс при тактировании от DCO (4.8МГц)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...