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

    

DPL

Свой
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

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

  • Звание
    Частый гость
  • День рождения 11.05.1968

Контакты

  • Сайт
    http://
  • ICQ
    0

Информация

  • Город
    Новочеркасск
  1. Здравствуйте! В соответствии с "MODBUS Messaging on TCP/IP Implementation Guide V1.0b" пытаюсь реализовать сервер (как там рекомендуют- с помощью BSD Sockets). Не совсем понимаю, как сервер должен выделять отдельные запросы из потока входных данных? Предположим, клиент отправил подряд три запроса (три вызова send()). Сервер одним вызовом recv() считал всё в буфер. Как выделять отдельные запросы? Ориентироваться только на поле Length в MBAP? Но как поступить, если клиент прислал запрос несоответствующей длины (допустим, первый из трёх)? Тогда на начало следующего (второго) запроса мы уже не попадём и вместо его MBAP прочитаем ерунду. В упомянутом выше документе сказано, что если MBAP некорректный, то принятые данные следует игнорировать. Получится, что два оставшихся запроса будут проигнорированы сервером. Что-то мне кажется, что так быть не должно. Хотелось бы узнать, решал ли кто-то подобную задачу и каким способом? Заранее благодарю за помощь.
  2. Keil C51 + библиотеки FT800

    Дело не в библиотеках, а в анонимных union, как заметили выше. Кстати, Keil для ARM их тоже не любит. Чтобы исправить ситуацию, в первой строке, выделенной жёлтым, надо между скобкой и точкой с запятой указать произвольный идентификатор, уникальный в пределах описания typedef struct {...} Ft_Gpu_Hal_Config_t. То же самое нужно сделать для второго union (желтым не выделено): Кодtypedef struct {   union {     ....   } AnyName1;   union {     ....   } AnyName2;   ... } Ft_Gpu_Hal_Config_t; В приведённом примере это идентификаторы AnyName1 и AnyName2. Правда в этом случае придётся править и обращения к полям структуры, а это может быть муторно, если таких обращений много. В Keil для ARM можно разрешить анонимные union директивой #pragma anon_unions - тогда описания и обращения править не придётся. Можно ли это сделать для Keil51 - не знаю, проверить не на чем.
  3. Отвечаю поздновато, но, возможно, ответ поможет. Keil вполне корректно моделирует внешнюю память (по крайней мере uVision3, с которым я работал долго), причём как при обращении по 16-разрядным адресам, так и по 8-разрядным. При отладке следует иметь в виду, что если внешняя память подключена к 16-разрядной шине адреса (а Keil считает именно так для классического 8051), то физический адрес будет в любом случае 16-разрядным. Если использовать команды типа movx a,@DPTR, то этот адрес полностью находится в DPTR. Если же используются команды типа movx a,@R0, то младший байт адреса берётся из R0, а старший - из P2 (т.е. текущее содержимое P2). Следовательно, при выполнении команд Кодmov P2,#20h mov r0,#33h movx a,@r0 байт считается из ячейки с адресом 2033h, а если потом сделать так: Кодmov P2,#40h movx a,@r0 то чтение произойдёт уже из ячейки 4033h. Аналогично работает и запись в XRAM. Таким образом, при просмотре ячеек в окне Memory Window нужно указывать адрес с учетом старшего байта, соответствующего текущему содержимому P2. Следует отметить что команды типа movx a,@DPTR не изменяют содержимое P2 (точнее - изменяют лишь на время своего выполнения, а затем восстанавливают). Если в Вашем устройстве старшие разряды адреса не используются, то при симуляции их всё равно придётся учитывать (по крайней мере я не знаю, как объяснить Кейлу, что они не нужны).
  4. Цитата(alexeika007 @ Mar 29 2012, 21:57) а разве нужно указывать размер int_rx_data = *pSPORT1_RX16? В данном случае нужно. Это следует из определений (cdefBF534.h): Код#define pSPORT1_RX         ((volatile unsigned long  *)SPORT1_RX) #define pSPORT1_RX32         ((volatile unsigned long  *)SPORT1_RX) #define pSPORT1_RX16         ((volatile unsigned short *)SPORT1_RX) Видно, что pSPORT1_RX и pSPORT1_RX32 - это одно и то же. Таким образом, операция int_rx_data = *pSPORT1_RX читает 32-разрядный регистр вместо 16-разрядного. Кстати - проблема может быть именно в этом (сейчас не помню, что будет, если SPORT настроен на 16 разрядов, а читаются 32)
  5. Цитата(bookevg @ Nov 23 2009, 16:51) Если переменную хранить во внутренней области памяти ширина, которой 16 бит, то переменная станет 16 битной, т.е. при сохранении старшие 16 бит будут терятся Хм... А где же тогда хранить long long или double ?
  6. Цитата(777777 @ Nov 23 2009, 09:40) У этого компилятора нет команды Go To Definition, как в Visual Studio, поэтому найти определение проблематично. В Студии это, конечно, поудобнее. Как вариант - можно в опциях проекта включить галочку "Generate preprocessed file" - по идее сформируется текстовый файл, в котором, в числе прочего, развёрнуты все include (в VDSP сам не пробовал). В этом файле и поискать, откуда берётся wchar_t.
  7. Насколько я понимаю, тип "wchar_t" не является "встроенным" в компилятор, поэтому крутить настройки компилятора вряд ли поможет. Нужно поискать в заголовочных файлах, от какого базового типа он произошёл: что-то вроде Кодtypedef unsigned int wchar_t; Ну а дальше - зависит от потребностей. Если этот тип нужен только для личного использования, то его описание можно поправить, например так: Кодtypedef uint16_t wchar_t; Если же предполагается вызывать библиотечные функции, использующие этот тип - тогда хуже: они, вероятно, скомпилированы с четырёхбайтной версией wchar_t. Наверное можно попытаться их перекомпилировать.
  8. Немного не в тему, но, возможно, информация пригодится... Цитата(777777 @ Oct 30 2009, 13:15) ...матлаб приводит коэффициенты в диапазон -2...+2, что не влазит в fract16. К сожалению матлаба сейчас под рукой нет, так что не могу подробно расписать что и где. Но совершенно точно, что матлаб (я использовал FDA Tool) умеет приводить коэффициенты к диапазону [-1...+1[. Проверено неоднократно (правда для FIR). Цитата(777777 @ Oct 30 2009, 13:15) Кстати, никто не знает, можно ли в эту функцию подсунуть один и тот же массив и в input и в output? Мне нужно было подсовывать по одному отсчету (т.е. массивы input и output содержали по одному элементу). Так вот, указание одной и той же переменной на вход и на выход работало нормально. Опять же, это делалось для fir_fr16, но, я думаю, способ работы с параметрами у сходных библиотечных функций одинаков. А вообще реализация IIR на ассемблере есть в VDSPшных исходниках (VDSP50\Blackfin\lib\src\libdsp\iir_fr16.asm). Очень удобно взять это за основу (сам так поступил, когда понадобилось iir_fr32).
  9. Насчёт JTAG - есть неплохой вариант EMU-AD от InSys. Стоит в несколько раз дешевле AD-шного. Пользуемся уже несколько лет, особых проблем не замечали. Не знаю, правда, где его взять в Украине - мы заказывали в Мск.
  10. Есть ещё один вариант. Если первый байт LDR-файла, записываемого в AT45xxD, заменить на 0xFF, то флэшка опознаётся загрузчиком не как обычная память с 24-разрядным адресом, а именно как DataFLASH со страницей 528 байтов. За счет этого можно не переключаться в 512-байтный режим. На процесс загрузки такая замена влияния не оказывает (проверял на версии 0.4 BF532 совместно с AT45DB161D).
  11. Цитата(Hulm @ May 18 2007, 15:47) DSEG AT 40H OZU1 SEGMENT DATA RSEG OZU1 R0_0: DS 1 R1_0: DS 1 Первая строка описывает абсолютный сегмент данных с адреса 40. Вторая строка описывает перемещаемый сегмент данных. Третья строка сразу выбирает перемещаемый сегмент, то есть абсолютный никак не используется. Следующие строки выделяют память в перемещаемом сегменте под переменные. Таким образом, реально переменные размещаются в перемещаемом сегменте, а компоновщик пихает его туда, куда считает нужным. Чтобы все было так, как хочется, нужно написать: DSEG AT 40H R0_0: DS 1 R1_0: DS 1
  12. В программе бросаются в глаза 2 момента, которые обычно приводят к неработоспособности. 1. Разрешаются прерывания от ТС0, он запускается, но подпрограмма обработки прерываний не определена. Таким образом, при переполнении таймера управление будет передано неизвестно куда. 2.В процессе выполнения программы встречается команда RET без предварительно выполненной команды CALL. Это приведёт к передаче управления по неизвестному адресу. Возможно, есть и ещё что-то, я смотрел не очень внимательно
  13. Цитата(dxp @ Apr 4 2007, 09:42) Можно еще попробовать завести сигнал фреймовой синхры на внешнее прерывание, при условии, что фремовый сигнал работает в режиме чипселекта (т.е. активен в течение всей последовательности). По окончании этого сигнала передача завершена. Правда, тут надо аппаратную доработку + 1 нога из флагов ввода-вывода. Да, это, пожалуй, будет более надёжное решение в тех случаях, когда приемник фиксирует бит по переднему фронту синхроимпульса, а передатчик снимает TFS по заднему (что, по-моему, логично). При использовании моего метода на малых скоростях обмена следующая посылка может начаться, когда TFS ещё активен, а последний байт уже принят. Правда, досконально я в этих тонкостях не разбирался, на частоте 10МГц всё работает неплохо и группы байтов разделяются TFS-ом.
  14. Цитата(dxp @ Apr 3 2007, 16:22) А если передавать группы с помощью DMA? Т.е. зарядили группу - записали в буфер, запустили DMA, по окончании пересылки DMA контроллер сгенерирует прерывание, после чего можно следующую группу заряжать. К сожалению, это не работает. DMA формирует прерывание по отправке последнего байта в FIFO SPORT, т.е. за несколько байтов до конца. Я нашёл такое решение проблемы - может, пригодится кому... Одновременно с передачей запускаю приём такого же количества байтов, который идёт синхронно с передачей. Принимается, конечно, всякая ерунда, но это не важно. Передача и приём идут через DMA, но прерывание по окончанию обмена формирует именно принимающий канал DMA. Это гарантирует возникновение запроса прерывания после записи последнего принятого байта в память, что несколько позже, чем окончание передачи последнего байта. Как я потом сообразил, что-то похожее AD в некоторых случаях рекомендуют использовать при работе с "нормальным" SPI. Благодарю всех, принявших участие в обсуждении моего вопроса. Цитата(K A A @ Apr 3 2007, 14:38) Я тоже недавно пытался определять момент окончания пересылки данных через SPORT и ничего лучшего не придумал, как тупо ждать по таймеру. Черт дернут прицепить сигма-дельта АЦП с SPI-интерфейсом к SPORTу. Потратил кучу времени, пока все заработало. Я пару раз использовал SPORT вместо SPI - понравилось Во-первых, 2 канала DMA - на прием и передачу. Во-вторых, мне показалось, что контроллер SPORT более тонко настраивается. И в-третьих, это отдельный контроллер , т.е. для совершения обмена с каким-либо устройством не нужно ждать окончания обмена с другим. Из недостатков - только отсутствие нескольких сигналов выбора, так что к SPORT удобно цеплять одно устройство. Тактовые импульсы, как мне показалось, действительно лучше не выключать: на их повторное включение тратится время.
  15. Здравствуйте. Возникла такая проблема: в системе имеется SPI-устройство (CAN-контроллер MCP2515), подключенное к SPORT1 процессора BF532. Байты по SPI должны передаваться от BF к MCP группами: активизировали сигнал выбора - передали несколько байтов - сняли сигнал выбора. Сигнал выбора для MCP формируется при помощи выхода TFS, настроенного таким образом, что между байтами он не переходит в неактивное состояние, а остается активным до окончания передачи последнего байта. Для одной группы байтов всё работает чудесно. Если же передаётся подряд без паузы несколько групп, то TFS, естественно, между группами в неактивное состояние не переходит, что неправильно с точки зрения MCP. Чтобы обеспечить разделение групп байтов сигналом TFS, видится такой способ: перед началом передачи очередной группы дождаться окончания передачи предыдущей. Но вот как это сделать - не соображу. Собственно, вопрос вот в чём: как определить момент окончания передачи последнего байта через SPORT? Бит TXHRE тут не помогает. Другой вопрос: возможно, есть иной способ выделения группы передаваемых байтов сигналом TFS?