|
|
  |
Atmel SAM3U4, Различные вопросы |
|
|
|
Jan 7 2012, 22:56
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(sonycman @ Jan 8 2012, 00:00)  Понятно, тогда большого смысла для меня тут нет, имеется только J-Link. IMHO тогда точно лучше всего IAR использовать, отладчик там хороший! и поддержка JLINK хорошая. Да и компилер в целом один из лучших, ну бывают иногда задвиги с оптимизацией, но обычно в следующих версиях лечится. А критические функции можно и другим компилером компилить, линкуется сейчас все без проблем. Кстати в новых версиях IAR уже GNU asm макросы есть. А отладчик в RV4.1 - КМВ который это же монстр просто
|
|
|
|
|
Jan 8 2012, 11:22
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Надо бы запустить USB HS. Посмотрел пример на базе атмеловской библиотеки - вроде работает, и неплохие скорости даже без включения High Speed режима карты памяти. Но как-то у них всё монструозно, библиотека какая-то, терпеть всё это не могу, буду писать свой код для MSD, за основу возьму костяк MSD от STM32.
Первое впечатление от атмеловского HS USB контроллера очень хорошее, и расписано всё довольно подробно, и интерфейс довольно удобный.
Интересно реализован доступ к банкам памяти под эндпоинты - в виде 64 килобайтового логического адресного пространства для каждой точки. Самой двухпортовой памяти для точек, конечно, меньше, около 4 килобайт, получается просто ремап этой памяти на 64 кб регионы.
Но каким именно образом записывать\считывать эту память? В тексте память эндпоинтов называют как FIFO - значит ли это, что можно устанавливать указатель на любое слово 64 кб региона и при этом будет считываться слово из хвоста FIFO \ записываться слово на вершину FIFO? Или нужно точно позиционировать указатель на нужный банк внутри региона?
|
|
|
|
|
Jan 17 2012, 10:35
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Ну что же, запустил USB HS и MSD, основываясь на атмельских библиотечных примерах, идущих с Кейл. Перепахал и адаптировал под себя код, поражающий своей монструозностью и количеством файлов - из 100500 надо бы, чтобы было всего несколько. Библиотека, кстати, по крайней мере её часть, касаемая USB и MSD, отличается весьма неплохим качеством и структурированностью, не то, что было в аналогичной ситуации у STM32. Скорости MSD получились хорошие - на SDHC карту 4GB 4 класса чтение около 14.9 MB/s и запись 11.5 MB/s. Максимально приблизился к практическому потолку этой карточки  Блин, после USB FS это как самолёт истребитель рядом с телегой с деревянными колёсами И при этом HS трансивер встроенный! Молодцы, Атмел!
|
|
|
|
|
Jan 20 2012, 10:33
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE ЗЫ: не могу удержаться, вот ещё небольшое сравнение. Такой совсем простенький цикл, и результат его компиляции при макс. настройках оптимизации: Отвечу тут (дабы у новичков не плодить оффтопа). Накопали Вы в интернетах обычный для интернетов говнокод. Миллионы локальных переменных в стеке. Если бы это было написано вменяемо (c оглядкой ограниченное количество регистровых переменных), то и было бы все красиво: CODE void foo(int gb, int *buf) { int es; int i; if (gb < 6) { es = 6 - gb; for (i = 0; i < 32; i++) buf[i] >>= es; } } CODE SECTION `.text`:CODE:NOROOT(1) THUMB // 25 void foo(int gb, int *buf) // 26 { // 27 int es; // 28 int i; // 29 if (gb < 6) foo: CMP R0,#+6 BGE.N ??foo_0 // 30 { // 31 es = 6 - gb; RSB R0,R0,#+6 // 32 for (i = 0; i < 32; i++) buf[i] >>= es; MOVS R2,#+4 ??foo_1: LDR R3,[R1, #+0] ASRS R3,R3,R0 STR R3,[R1, #+0] LDR R3,[R1, #+4] ASRS R3,R3,R0 STR R3,[R1, #+4] LDR R3,[R1, #+8] ASRS R3,R3,R0 STR R3,[R1, #+8] LDR R3,[R1, #+12] ASRS R3,R3,R0 STR R3,[R1, #+12] LDR R3,[R1, #+16] ASRS R3,R3,R0 STR R3,[R1, #+16] LDR R3,[R1, #+20] ASRS R3,R3,R0 STR R3,[R1, #+20] LDR R3,[R1, #+24] ASRS R3,R3,R0 STR R3,[R1, #+24] LDR R3,[R1, #+28] ASRS R3,R3,R0 STR R3,[R1, #+28] ADDS R1,R1,#+32 SUBS R2,R2,#+1 BNE.N ??foo_1 // 33 } // 34 } ??foo_0: BX LR ;; return
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 20 2012, 10:37
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(Rst7 @ Jan 20 2012, 14:33)  Отвечу тут (дабы у новичков не плодить оффтопа). Накопали Вы в интернетах обычный для интернетов говнокод. Миллионы локальных переменных в стеке. Если бы это было написано вменяемо (c оглядкой ограниченное количество регистровых переменных), то и было бы все красиво: Я понял, что такой код получился в контексте функции, у которой много локальных переменных. Однако внутри цикла величина сдвига является константой, и непонятно, почему компилер не понял этого простого факта и решил подгружать эту величину каждый раз, в один и тот же регистр, который никак после этого не модифицируется... Явный прокол, которого нет у RV.
|
|
|
|
|
Jan 20 2012, 11:16
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE Явный прокол, которого нет у RV. Там зато есть другие. Компиляторы, которые пытаются решить все за человека часто несут фигню. Вообще для любого компилятора есть глубокий смысл делать следующее. Вот пример некрасивого (но обычного) кода: CODE int es;
void foo(int gb, int *buf) { int i; if (gb < 6) { es = 6 - gb; for (i = 0; i < 32; i++) buf[i] >>= es; } } Кодегенерация в IAR CODE SECTION `.bss`:DATA:REORDER:NOROOT(2) // 26 int es; es: DS8 4 // 27
SECTION `.text`:CODE:NOROOT(1) THUMB // 28 void foo(int gb, int *buf) // 29 { // 30 int i; // 31 if (gb < 6) foo: CMP R0,#+6 BGE.N ??foo_0 // 32 { // 33 es = 6 - gb; LDR.N R2,??DataTable1 RSB R0,R0,#+6 STR R0,[R2, #+0] // 34 for (i = 0; i < 32; i++) buf[i] >>= es; MOVS R0,#+32 ??foo_1: LDR R3,[R1, #+0] LDR R12,[R2, #+0] ASR R3,R3,R12 STR R3,[R1], #+4 SUBS R0,R0,#+1 BNE.N ??foo_1 // 35 } // 36 } ??foo_0: BX LR ;; return // 37
Loop unrolling отключил, чтобы не загромождать листинг. Как видите, постоянно читается переменная из ОЗУ. Если бы переменная es была в стеке, было бы то же самое - это Вы сами видели. Правильный код выглядит так: CODE void foo_goot(int gb, int *buf) { int i; if (gb < 6) { int t =es = 6 - gb; for (i = 0; i < 32; i++) buf[i] >>= t; } } CODE // 38 void foo_goot(int gb, int *buf) // 39 { // 40 int i; // 41 if (gb < 6) foo_goot: CMP R0,#+6 BGE.N ??foo_goot_0 // 42 { // 43 int t =es = 6 - gb; RSB R0,R0,#+6 LDR.N R2,??DataTable1 STR R0,[R2, #+0] // 44 for (i = 0; i < 32; i++) buf[i] >>= t; MOVS R2,#+32 ??foo_goot_1: LDR R3,[R1, #+0] ASRS R3,R3,R0 STR R3,[R1], #+4 SUBS R2,R2,#+1 BNE.N ??foo_goot_1 // 45 } // 46 } ??foo_goot_0: BX LR ;; return
В этом смысле IAR мне куда больше нравится, т.к. я имею возможность рассказать ему какую именно переменную я бы хотел видеть регистровой. А другие компиляторы пытаются всегда решить за человека и помочь им способа нет. Очень зря забили на ключевое слово register, я считаю. Мой опыт говорит вот что. TCP-стек, который я делал, представляет из себя единственную функцию (это обработчик прерываний). Так вот только IAR нормально раскладывает все по регистрам (все локальные переменные туда помещаются) и стек не используется. Другие компиляторы не справляются - начинается откладывание локальных переменных в стек и, естественно, полный ахтунг в коде.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 31 2012, 15:42
|
Частый гость
 
Группа: Участник
Сообщений: 121
Регистрация: 8-11-05
Пользователь №: 10 577

|
Народ, кто писал в этой теме по поводу "батарейного отсека" для SAM3U отзовитесь плиз!
Напоролись на траблу, что если плата на основе сабжа лежит с неделю на столе без питания, после подачи последнего впадает в ступор! Решили отказаться от литиевой батарейки на ноге VDDBU, а запитать её собственно с VDDIO. Тут другая проблема: теперь плата ресетится долго, порядка 2х секунд, как будто при каждом подключении питания происходит внешний ресет по NRSTB. При наличии же литиевой батарейки плата ресетился по подаче питания очень быстро.
Это как то можно забороть?
В мануале написано:
"VDDBU must be supplied before or at the same time than VDDIO and VDDCORE". Если запитывать VDDBU раньше чем остальные ноги требующие питаня, то получится "быстрый" ресет? Или "медленный старт" - это фича камня, и жизнь прожита зря?
Сообщение отредактировал kostyan - Jan 31 2012, 15:54
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|