![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_pattern.png)
![](https://electronix.ru/forum/uploads/set_resources_23/84c1e40ea0e759e3f1505eb1788ddf3c_default_photo.png)
Axel
Свой-
Постов
552 -
Зарегистрирован
-
Посещение
-
Победитель дней
1
Весь контент Axel
-
Да вроде бы несложно. После каждого вызова new (или malloc) сравнивать выделенный адрес с ранее полученными и запоминать максимальный, а в обработчике посмотреть, что получилось. Или, если есть что-нибудь типа debug_printf (IARом не пользуюсь, поэтому не знаю) - печатать в окне дебагера.
- 64 ответа
-
- hardfault
- hard fault
-
(и ещё 2 )
C тегом:
-
Испортил, но без толку... В моем случае пришлось PLD прилепить. Могу предложить инверсный вариант - клокать генератор контроллером (не получается правильно - делай наоборот ).
-
#pragma once #define USB_XCH_QUEUE_SIZE 0x3000//0xD00 #define USB_QUEUE_CELL_SIZE 64 class CUSB_Queue { public: uint32_t m_Data[uSB_XCH_QUEUE_SIZE >> 2]; volatile uint32_t m_Tail; volatile uint32_t m_Head; public: volatile uint32_t m_NumEntries; CUSB_Queue() : m_Tail(0), m_Head(0), m_NumEntries(0) {}; int32_t Queue_put(uint32_t *data); __attribute__( ( always_inline ) )uint32_t *Queue_puti(void) { uint32_t res = 0; if(m_NumEntries < (USB_XCH_QUEUE_SIZE >> 6)) { res = (uint32_t)m_Data + m_Head; m_Head = (m_Head + USB_QUEUE_CELL_SIZE) % USB_XCH_QUEUE_SIZE; m_NumEntries++; } return (uint32_t *)res; }; volatile int32_t Queue_get(uint32_t *inf); __attribute__( ( always_inline ) )uint32_t *Queue_geti(void) { uint32_t res = 0; if(m_NumEntries) { res = (uint32_t)m_Data + m_Tail; m_Tail = (m_Tail + USB_QUEUE_CELL_SIZE) % USB_XCH_QUEUE_SIZE; m_NumEntries--; } return (uint32_t *)res; }; __attribute__( ( always_inline ) )void Queue_validate(void) { m_NumEntries++; }; void Queue_Clear(void) { m_NumEntries = 0; s_memset(m_Data, 0x05, USB_XCH_QUEUE_SIZE); m_Tail = 0; m_Head = 0; }; }; extern CUSB_Queue USB_TxQueue; extern CUSB_Queue USB_RxQueue; //=========================== #include "usb_queue.h" int32_t CUSB_Queue::Queue_put(uint32_t *inf) { int32_t i = 100000; do { uint32_t *buffer = Queue_puti(); if(buffer) { s_memcpy(buffer, inf, USB_QUEUE_CELL_SIZE); return NO_ERR; } i--; } while(i > 0); return -1; } volatile int32_t CUSB_Queue::Queue_get(uint32_t *inf) { uint32_t *buffer = Queue_geti(); if(buffer) { s_memcpy(inf, buffer, USB_QUEUE_CELL_SIZE); return NO_ERR; } return -1; } CUSB_Queue USB_TxQueue; CUSB_Queue USB_RxQueue; Методы Queue_get и Queue_put - для основчой программы, Queue_geti и Queue_puti - для прерываний.
-
Это может сделать сам буфер, если будет чуток "умнее", напр. очередь (я сделал именно так). Можно попытаться ловить NAKи в прерываниях. Можно дожидаться подтверждения от хоста (с потерей лишних двух ms). Как больше нравится...
-
Да, вобщем, ниоткуда... Просто это близко (с некоторым запасом) к одной из высоких (для COM порта) стандартных скорстей - 250кБод. Вы, естсственно, можете использовать другую. Касательно размера буфера - трудно сказать. Он во многом определяется тем, как прерывание IN endpoint забирает из него данные. Я использую FIFO в виде кольцевого буфера. По поводу потерь данных - попробуйте просмотреть обмен каким-нибудь сниффером (напр. Bus Hound). Многое может прясниться...
-
Значение CDC_IN_FRAME_INTERVAL определяет частоту попыток драйвера передать блок данных хосту и (соответственно) размер этого блока. Значение APP_RX_DATA_SIZE определяется махимальным количеством байт, поступающих в драйвер (изнутри) за один usb-шный квант (1ms). Для 256кБод это 320 байт = CDC_IN_FRAME_INTERVAL * 64. Естественно, для исключения потерь при передаче, размер передаваемого пакета должен быть кратен величине (CDC_IN_FRAME_INTERVAL * 64). Это уже под Вашу ответственность. Я использовал этот код для своего, более простого bulk драйвера, передаю пакеты с размером, кратным 512 байт и, соответственно, использую значение CDC_IN_FRAME_INTERVAL, равное 8.
-
Если я правильно понял вопрос, то: можно в функции USBD_OTG_ISR_Handler() в обработке прерывания SOF фиксировать подключение, а в обработке SUSPEND - отключение (я так делаю). Работает вполне устойчиво.
-
А может проблема с другой стороны? Попробуйте поставить какой-нибудь сниффер (напр. Bus Hound) и посмотреть - не передается или не принимается..
-
Как знаете... Хотите код посмотреть - без проблем. Только если "ST-библиотеки - ужас+вынос_мозга", то вряд ли на этом этапе это поможет Вам построить свой велосипед...
-
Контроллеры из "ООЧЕНЬ давно" похожи на современные как велосипед на трактор... Вам стоит начать "от печки" - почитать про Cortex-ы вообще. Там, например, Вы сразу найдете ответы на заданные Вами вопросы. Я, кстати, тоже "велосипедист", CMSIS не использую, но ST-шные примеры, ввиду многократно обсуждавшегося качества их доки - элемент необходимый. Мне, например, они помогли написать простенькое и устойчивое Bulk-устройство, читаемое (мною) гораздо легче, чем код от ST.
-
Буду весьма признателен - у меня с первого раза криво полетело, а время поджимает...
-
Перегрузить регистр Port Mode. Там для этих пинов после сброса двойки записаны (т.е. альтернативные функции).
-
Я сейчас в процессе... Использую "в развитие" LPC1778. По первому впечатлению - все путем. Из недостатков (субъективно) - отсутствие Double или Quad SPI и нормального (в смысле питча) BGA. встроенную графику не пользую - у меня дисплей на параллельной шине. Сейчас строю USB bulk device. Отсутствие FIFO у портов - традиционно для ST. I2C - неоправданно замороченный. АЦП, ЦАП - в порядке, таймеры тоже. TNkernel встала без проблем.
-
Динамическая подгрузка функции
Axel ответил VolnovodT00 тема в ARM
Про "загрузчик процессора" не очень понятно. Что касаемо кода функций - для таких ситуаций GNU компиляторы (а может и другие) имеют опцию -PIC (position independent code). Сразу оговорюсь - сам я этим не пользовался. -
Ну да, у меня так же... Пока действительно, кроме выравнивания идей нет.
-
Да собственно ничего кроме настроек регистра FLASHCFG и парметра частоты при вызове функций IAP драйвера
-
Вполне себе работает. У меня таким образом организован кольцевой буфер из двух 32к секторов (контроллер LPC1778, блоки по 256 байт). Может у Вас чего не так с таймингом?
-
Ищу порт Tn-Kernel для CM0
Axel ответил megajohn тема в Операционные системы
У меня есть авторский вариант. Тестировался на LPC11. TNKernel_CortexM0.zip -
У меня похожая ситуация: внутри вектора таймера разрешается внешнее прерывание. Отличия: вся инициализация выполняется в теле основной программы, а в вектор (таймера) включен только короткий фрагмент: EXTI->PR = (1 << 1); // clear ext. int. flag __ISB(); __DSB(); EXTI->IMR |= (1 << 1); // enable rising edge int. Срeда - CrossWorks. Пока работает...
-
Реле создает помехи по питанию
Axel ответил toweroff тема в Схемотехника
Так не вопрос... На массовку вылизывается каждый фрагмент платы и жгутов, каждый резистор... А оптроны - если надо, чтобы заработало с листа, при не очень известном финальном дизайне устройства. Ну и PLC как правило, "предпочитают" без них не обходиться. -
Реле создает помехи по питанию
Axel ответил toweroff тема в Схемотехника
Я тоже, но абсолютно сознательно. И стараюсь, если бюджет позволяет, с изоляцией киловольт на 5 - чтоб емкости поменьше. Согласен с тем (практически уверен), что проблемы ТС лезут из контактов (через их емкисть с обмоткой). А если еще и провода там длинные... -
Делюсь: typedef void (*pFunction)(uint32_t app_start); void JumpToApp (uint32_t app_start) { pFunction jump_to_app = (pFunction)(*(volatile uint32_t *) (app_start + 4)); LPC_SC->CCLKSEL = 0x01; // set sysclk (12MHz) as clock source LPC_SC->PLL0CON = 0; // disable PLL LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED = 0x55; SCB->VTOR = (uint32_t)app_start; // Change the Vector Table to the APP_CODE_START __ASM volatile ("MSR psp, %0" : : "r" (*(volatile uint32_t *)app_start)); // Load new stack pointer address jump_to_app(app_start); // Jump to application code }
-
При условии постоянной плотности объекта...
-
Нужна помощь по OSD!
Axel ответил barmaley79 тема в В помощь начинающему
Думаю Вам и дальше стоит оставаться вдали от этого форума. Вряд ли Вы найдете здесь помощь (и понимание).