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

DPL

Свой
  • Постов

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

  • Посещение

Репутация

0 Обычный

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

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

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array

Посетители профиля

1 932 просмотра профиля
  1. Здравствуйте! В соответствии с "MODBUS Messaging on TCP/IP Implementation Guide V1.0b" пытаюсь реализовать сервер (как там рекомендуют- с помощью BSD Sockets). Не совсем понимаю, как сервер должен выделять отдельные запросы из потока входных данных? Предположим, клиент отправил подряд три запроса (три вызова send()). Сервер одним вызовом recv() считал всё в буфер. Как выделять отдельные запросы? Ориентироваться только на поле Length в MBAP? Но как поступить, если клиент прислал запрос несоответствующей длины (допустим, первый из трёх)? Тогда на начало следующего (второго) запроса мы уже не попадём и вместо его MBAP прочитаем ерунду. В упомянутом выше документе сказано, что если MBAP некорректный, то принятые данные следует игнорировать. Получится, что два оставшихся запроса будут проигнорированы сервером. Что-то мне кажется, что так быть не должно. Хотелось бы узнать, решал ли кто-то подобную задачу и каким способом? Заранее благодарю за помощь.
  2. Дело не в библиотеках, а в анонимных 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. В данном случае нужно. Это следует из определений (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. Хм... А где же тогда хранить long long или double ? :)
  6. В Студии это, конечно, поудобнее. Как вариант - можно в опциях проекта включить галочку "Generate preprocessed file" - по идее сформируется текстовый файл, в котором, в числе прочего, развёрнуты все include (в VDSP сам не пробовал). В этом файле и поискать, откуда берётся wchar_t.
  7. Насколько я понимаю, тип "wchar_t" не является "встроенным" в компилятор, поэтому крутить настройки компилятора вряд ли поможет. Нужно поискать в заголовочных файлах, от какого базового типа он произошёл: что-то вроде typedef unsigned int wchar_t; Ну а дальше - зависит от потребностей. Если этот тип нужен только для личного использования, то его описание можно поправить, например так: typedef uint16_t wchar_t; Если же предполагается вызывать библиотечные функции, использующие этот тип - тогда хуже: они, вероятно, скомпилированы с четырёхбайтной версией wchar_t. Наверное можно попытаться их перекомпилировать.
  8. Немного не в тему, но, возможно, информация пригодится... К сожалению матлаба сейчас под рукой нет, так что не могу подробно расписать что и где. Но совершенно точно, что матлаб (я использовал FDA Tool) умеет приводить коэффициенты к диапазону [-1...+1[. Проверено неоднократно :) (правда для FIR). Мне нужно было подсовывать по одному отсчету (т.е. массивы 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. Первая строка описывает абсолютный сегмент данных с адреса 40. Вторая строка описывает перемещаемый сегмент данных. Третья строка сразу выбирает перемещаемый сегмент, то есть абсолютный никак не используется. Следующие строки выделяют память в перемещаемом сегменте под переменные. Таким образом, реально переменные размещаются в перемещаемом сегменте, а компоновщик пихает его туда, куда считает нужным. Чтобы все было так, как хочется, нужно написать: DSEG AT 40H R0_0: DS 1 R1_0: DS 1
  12. В программе бросаются в глаза 2 момента, которые обычно приводят к неработоспособности. 1. Разрешаются прерывания от ТС0, он запускается, но подпрограмма обработки прерываний не определена. Таким образом, при переполнении таймера управление будет передано неизвестно куда. 2.В процессе выполнения программы встречается команда RET без предварительно выполненной команды CALL. Это приведёт к передаче управления по неизвестному адресу. Возможно, есть и ещё что-то, я смотрел не очень внимательно
  13. Да, это, пожалуй, будет более надёжное решение в тех случаях, когда приемник фиксирует бит по переднему фронту синхроимпульса, а передатчик снимает TFS по заднему (что, по-моему, логично). При использовании моего метода на малых скоростях обмена следующая посылка может начаться, когда TFS ещё активен, а последний байт уже принят. Правда, досконально я в этих тонкостях не разбирался, на частоте 10МГц всё работает неплохо и группы байтов разделяются TFS-ом.
  14. К сожалению, это не работает. DMA формирует прерывание по отправке последнего байта в FIFO SPORT, т.е. за несколько байтов до конца. Я нашёл такое решение проблемы - может, пригодится кому... Одновременно с передачей запускаю приём такого же количества байтов, который идёт синхронно с передачей. Принимается, конечно, всякая ерунда, но это не важно. Передача и приём идут через DMA, но прерывание по окончанию обмена формирует именно принимающий канал DMA. Это гарантирует возникновение запроса прерывания после записи последнего принятого байта в память, что несколько позже, чем окончание передачи последнего байта. Как я потом сообразил, что-то похожее AD в некоторых случаях рекомендуют использовать при работе с "нормальным" SPI. Благодарю всех, принявших участие в обсуждении моего вопроса. Я пару раз использовал SPORT вместо SPI - понравилось :) Во-первых, 2 канала DMA - на прием и передачу. Во-вторых, мне показалось, что контроллер SPORT более тонко настраивается. И в-третьих, это отдельный контроллер :), т.е. для совершения обмена с каким-либо устройством не нужно ждать окончания обмена с другим. Из недостатков - только отсутствие нескольких сигналов выбора, так что к SPORT удобно цеплять одно устройство. Тактовые импульсы, как мне показалось, действительно лучше не выключать: на их повторное включение тратится время.
  15. Здравствуйте. Возникла такая проблема: в системе имеется SPI-устройство (CAN-контроллер MCP2515), подключенное к SPORT1 процессора BF532. Байты по SPI должны передаваться от BF к MCP группами: активизировали сигнал выбора - передали несколько байтов - сняли сигнал выбора. Сигнал выбора для MCP формируется при помощи выхода TFS, настроенного таким образом, что между байтами он не переходит в неактивное состояние, а остается активным до окончания передачи последнего байта. Для одной группы байтов всё работает чудесно. Если же передаётся подряд без паузы несколько групп, то TFS, естественно, между группами в неактивное состояние не переходит, что неправильно с точки зрения MCP. Чтобы обеспечить разделение групп байтов сигналом TFS, видится такой способ: перед началом передачи очередной группы дождаться окончания передачи предыдущей. Но вот как это сделать - не соображу. Собственно, вопрос вот в чём: как определить момент окончания передачи последнего байта через SPORT? Бит TXHRE тут не помогает. Другой вопрос: возможно, есть иной способ выделения группы передаваемых байтов сигналом TFS?
×
×
  • Создать...