|
Циклический буфер на AVR, (Примеры применения) |
|
|
|
Aug 24 2007, 15:16
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Тема открыта по горячим следам недавней острой дискуссии. В ней одним из участников (defunct) была приведена программа, в которой использовался циклический буфер для работы с последовательным портом МК AT90S2313. На взгляд автора программа написана достаточно грамотно, но как-то слишком размашисто, без учёта мизерности ресурсов данного МК. Предлагаю участникам поделиться примерами и приёмами использования циклического буфера в программных разработках. Для затравки предлагаю следующие фрагменты. А. Запись байта из регистра AL в циклический буфер Код mov xl,qhead ;указатель на запись st x+,al ;запишем байт cp xl,qend ;конец буфера? brne .+2 ;нет, обходим ldi xl,buffer ;да, установим начало Б. Чтение байта из циклического буфера в регистр AL Код mov xl,qtail ;указатель на чтение ld al,x+ ;прочитаем байт cp xl,qend ;конец буфера? brne .+2 ;нет, обходим ldi xl,buffer ;да, установим начало Если использовать буфер не произвольной длины, а кратный степени 2, и размещать его в памяти не произвольно, а начиная с адресов, кратных длине буфера, то размер кода можно немного сократить. Например. В. Запись байта из регистра AL в циклический буфер длиной 32 Код mov xl,qhead ;указатель на запись st x+,al ;запишем байт cbr xl,0xE0 ;держим указатель в предписанных рамках Г. Чтение байта из циклического буфера длиной 32 в регистр AL Код mov xl,qtail ;указатель на чтение ld al,x+ ;прочитаем байт cbr xl,0xE0 ;держим указатель в предписанных рамках Здесь qhead, qtail, qend – регистровые переменные, содержащие адреса-указатели ячеек в озу для записи, чтения и конца буфера соответственно.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
 |
Ответов
|
Aug 31 2007, 12:37
|
Участник

Группа: Участник
Сообщений: 44
Регистрация: 30-03-06
Пользователь №: 15 598

|
Вот одна из возможных реализаций. Имеется индекс чтения, количество занятых ячеек, флаг состояния переполнения и сам буфер. Запрет прерывания при чтении нужен, если запись в буфер происходит в прерываниях. Внимание! Программа не тестировалась в реальной работе. Если есть косяки, буду признателен за поправки. Опыт работы с AVR очень маленький. Код .dseg
.equ BUF_SIZE = 64 ; размер буфера, может быть n^2 <= 256
buf: .byte 3 + BUF_SIZE; счетчик занятых ячеек, индекс чтения, состояние буфера, буфер
.cseg
;------------------------------------------------ init_buf: ;------------------------------------------------ ; инициализация буфера ; используются r16, r28, r29
; в Y адрес структуры, задающей буфер mov YL, LOW(buf) mov YH, HIGH(buf) clr r16 std Y, r16 std Y+1, r16 std Y+2, r16 ret
;------------------------------------------------ write_buf: ;------------------------------------------------ ; в r16 байт для записи ; используются регисты r17, r18, r28, r29
; в Y адрес структуры, задающей буфер mov YL, LOW(buf) mov YH, HIGH(buf)
; если буфер полный не записывать, установить флаг переполнения ld r17, Y cpi r17, BUF_SIZE - 1 brcs L1 ldi r17, 1 std Y+2, r17 ret L1: ; определить индекс для записи ; i = (rindex + count) & (BUF_SIZE - 1) ld r18, Y + 1 add r18, r17 andi r18, BUF_SIZE-1 ; увеличить счетчик занятых ячеек в буфере ; count++ inc r17 st Y, r17
; buf[i] = data; clr r17 add YL, r18 adc YH, r17 std Y+3, r16 ret
;------------------------------------------------ read_buf: ;------------------------------------------------ ; возвращает байт в r16 ; используются регисты r16, r17, r28, r29
; в Y адрес структуры, задающей буфер mov YL, LOW(buf) mov YH, HIGH(buf)
; c = buf[rindex] ldd r16, Y+3
cli
; count-- ld r17, Y dec r17 st Y, r17 ; rindex = (rindex + 1) & BUF_SIZE - 1 ldd r17, Y+1 dec r17 andi r17, BUF_SIZE-1 std Y+1, r16 sei ret
Сообщение отредактировал alcosar - Aug 31 2007, 12:40
|
|
|
|
|
Aug 31 2007, 15:12
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(alcosar @ Aug 31 2007, 11:37)  Код ; в Y адрес структуры, задающей буфер mov YL, LOW(buf) mov YH, HIGH(buf) ; c = buf[rindex] ldd r16, Y+3 Здесь логическая ошибка, вы всё время читаете из одной и той же ячейки памяти. Идея сделать отдельный счётчик на заполнение буфера мне кажется здравой, надо обдумать на досуге. Для загрузки непосредственных данных в регистр применяется команда ldi, а не mov.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Aug 31 2007, 18:37
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(prottoss @ Aug 31 2007, 19:53)  Пара вопросов:
1.Сколько памяти программ и памяти данных занимает код с циклическими буферами для USART?
2.Почему во всех приведенных кодах процедуры чтения-записи из-в буферЫ нет команд запрета прерываний от обработчиков приема-окончания-передачи USART? 1. Вы же видите - очень мало. Но не это главное. Циклический буфер позволяет работать с максимальной производительностью и абсолютно отделяет работу с внешним устройством от интерфейса. Это можно использовать в любом месте. Например в последней теме у меня два таких буфера. 1-UART, 2-EEPROM. 2. В этом есть особый смысл.  Классическая структура буфера - сам буфер+2переменных. Указатель на голову и указатель на хвост. Представим себе приём. В прерывании используется только хвост(добавляются символы), а в main только голова буфера (забираются данные). Есть ещё один приятный момент. Если работаешь с подтверждениями (например CRC), то тоже имеется огромный плюс. Представьте кольцевой буфер и три указателя. Первых два я описал, а третий - указатель на недостоверные данные. Таким образом всё работает тем же способом, а по принятию решения (сравнение CRC) указатель на хвост присваивается либо указателю на принятые недостоверные данные (данные верны) либо наоборот указателю на недостоверные данные присваивается указатель на хвост (данные неверны и пакет требуется повторить). Никаких дополнительных средств и инструментов не требуется. 2 GM сенькую именно такую книгу искал (в смысле задача стоит именно как вы и написали). Сейчас буду искать саму книгу.
|
|
|
|
|
Aug 31 2007, 18:57
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(SasaVitebsk @ Sep 1 2007, 02:37)  1. Вы же видите - очень мало. Но не это главное. Циклический буфер позволяет работать с максимальной производительностью и абсолютно отделяет работу с внешним устройством от интерфейса. Это можно использовать в любом месте. Например в последней теме у меня два таких буфера. 1-UART, 2-EEPROM. В полезности циклических буферов я нисколько не сомневаюсь  и сам оччень часто их применяю. НО, очень мало, это сколько?  допустим применительно к АВР и его USART. Просто не вижу большого смысла тщательно рассказывать, как забивать гвозди... Почему нет ни единого примера на Си? Цитата(SasaVitebsk @ Sep 1 2007, 02:37)  2. В этом есть особый смысл.  Классическая структура буфера - сам буфер+2переменных. Указатель на голову и указатель на хвост. Представим себе приём. В прерывании используется только хвост(добавляются символы), а в main только голова буфера (забираются данные). А когда хвост догнал голову, а он важнее (ибо прерывание) получается баальшой булик  Цитата(SasaVitebsk @ Sep 1 2007, 02:37)  Есть ещё один приятный момент.
..................Никаких дополнительных средств и инструментов не требуется. Кроме анальгина
--------------------
|
|
|
|
Сообщений в этой теме
=GM= Циклический буфер на AVR Aug 24 2007, 15:16 defunct Цитата(=GM= @ Aug 24 2007, 18:16) Если ис... Aug 24 2007, 22:12 =AVR= Такой метод (посредством урезания операцией ... Aug 25 2007, 05:42 SasaVitebsk Цитата(=AVR= @ Aug 25 2007, 08:42) Такой ... Aug 26 2007, 10:50  =GM= Привет всем! Отъезжал ненадолго, тут праздник ... Aug 28 2007, 16:02   WHALE Цитата(=GM= @ Aug 28 2007, 20:02) Привет ... Aug 28 2007, 18:33    =GM= Цитата(WHALE @ Aug 28 2007, 18:33) Господ... Aug 28 2007, 22:33   SasaVitebsk Цитата(=GM= @ Aug 28 2007, 19:02) 1) To S... Aug 28 2007, 19:20   =AVR= Аппаратные буфера отличаются от address mode тем ж... Aug 28 2007, 20:21 sensor_ua IMHO, обсуждение циклических буферов в привязке к ... Aug 25 2007, 07:11 mse Цитата(=GM= @ Aug 24 2007, 19:16) Код m... Aug 25 2007, 07:48 adnega Доброго дня!
Мне вот очень интересно применен... Aug 27 2007, 06:45 zltigo Moderator:
Так, оба двое и присоединившийся к ним ... Aug 28 2007, 22:41 =GM= Цитата(zltigo @ Aug 28 2007, 22:41) Если ... Aug 29 2007, 00:07 SasaVitebsk 2 AVR спасибо. До вашего варианта не додумался. Пр... Aug 29 2007, 11:05 =GM= Цитата(SasaVitebsk @ Aug 29 2007, 10:05) ... Aug 29 2007, 12:13     SasaVitebsk Цитата(prottoss @ Aug 31 2007, 21:57) В п... Sep 3 2007, 14:31  alcosar [quote name='=GM=' date='Aug 31 2007, ... Sep 2 2007, 18:55 sensor_ua ЦитатаЦиклический буфер позволяет работать с макси... Aug 31 2007, 19:56 mse Цитата(sensor_ua @ Aug 31 2007, 23:56) Вс... Sep 1 2007, 07:03  prottoss Цитата(mse @ Sep 1 2007, 15:03) Практика ... Sep 1 2007, 07:15   mse Цитата(prottoss @ Sep 1 2007, 11:15) Прак... Sep 1 2007, 08:57    prottoss Цитата(mse @ Sep 1 2007, 16:57) Если загр... Sep 1 2007, 09:02     mse Цитата(prottoss @ Sep 1 2007, 13:02) Ну В... Sep 1 2007, 09:23      =GM= To alcosar
1) Здесь: std Y+1,r16 у вас ошибка, на... Sep 3 2007, 11:54       alcosar Цитата(=GM= @ Sep 3 2007, 14:54) To alcos... Sep 3 2007, 19:33        =GM= Цитата(alcosar @ Sep 3 2007, 19:33) 2. По... Sep 3 2007, 20:45 sensor_ua ЦитатаПочему нет ни единого примера на Си?
Файл пр... Sep 1 2007, 07:45 zltigo Цитата(sensor_ua @ Sep 1 2007, 10:45) Код... Sep 1 2007, 08:36 prottoss Выложу и я свое здесь, хоть уже и выкладывал в тем... Sep 1 2007, 08:43 sensor_ua ЦитатаНу хоть тэгами пользуйтесь для выделения исх... Sep 1 2007, 09:03 sensor_ua Цитата2. Размер указателей зависит от размера буфе... Sep 3 2007, 15:03 SasaVitebsk Цитата(sensor_ua @ Sep 3 2007, 18:03) Про... Sep 3 2007, 15:14 sensor_ua ЦитатаЕстественно на стадии написания программы
Ра... Sep 3 2007, 17:51 =GM= Цитата(sensor_ua @ Sep 3 2007, 17:51) Ука... Sep 3 2007, 19:25 SasaVitebsk Цитата(sensor_ua @ Sep 3 2007, 20:51) Рац... Sep 3 2007, 19:33 sensor_ua ЦитатаЧто вас смущает.
Цитата2. Размер указателей ... Sep 3 2007, 19:50 SasaVitebsk Цитата(sensor_ua @ Sep 3 2007, 22:50) Ну ... Sep 4 2007, 17:07 sensor_ua ЦитатаЕсли ввёл кого в заблуждение
Да всё путём. П... Sep 4 2007, 17:46 Dog Pawlowa Люди, а как Вы синхронизируете скорости заполнения... Sep 4 2007, 18:06  mse Цитата(Dog Pawlowa @ Sep 4 2007, 22:06) Л... Sep 4 2007, 18:39  bodja74 Цитата(Dog Pawlowa @ Sep 4 2007, 21:06) Л... Sep 4 2007, 20:46  defunct Цитата(Dog Pawlowa @ Sep 4 2007, 21:06) Л... Sep 8 2007, 22:21 sensor_ua ЦитатаВисеть в ожидании, пока там не освободится м... Sep 4 2007, 18:44 Dog Pawlowa Цитата(sensor_ua @ Sep 4 2007, 21:44) Дык... Sep 5 2007, 05:03  sensor_ua Цитата(Dog Pawlowa @ Sep 5 2007, 08:03) У... Sep 5 2007, 06:33   Dog Pawlowa Цитата(sensor_ua @ Sep 5 2007, 09:33) Исп... Sep 5 2007, 07:19
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|