owl
Свой-
Постов
90 -
Зарегистрирован
-
Посещение
-
Всем здравствуйте. Немного повторюсь по теме. Теже симптомы, но на STM32F429.(Обращение к внешней SDRAM, используемой для памяти дисплея и внешней памяти вызывает дерганье экрана) Существует ли доступ к управлению приоритетам AHB для STM?
-
На счет того, что всегда не хватает - вы абсолютно правы. С модбасом, к сожалению, не работал. Появилась пара мыслей об универсальном драйвере под RTOS. Доведу до ума покажу.
-
Может быть, я действительно что-то не понимаю, но в общем случае при приеме данных с UART, нам не известна длинна входящей посылки. Поэтому только 2 выхода: поллинг, событие(семафор) приема байта. Подход к драйверу может быть и ничего. Но тогда уже стоит брать пример с драйвера RTE_DRIVER UART от KEIL для STM32F1X. Там все гораздо интереснее, хотя все равно - есть ошибки.
-
Есть 2 простых варианта. Это настраивать буфер на прием 1 байта. Настраивать буфер с "запасом" и делать поллинг принимаемых данных. - По приему некоторого числа, делать инициализацию заново. Что одно, что второе - костыли. Все это вызывает удивление. Например вот это: #if (USE_RTOS == 1) /* Reserved for future use */ #error “USE_RTOS should be 0 in the current HAL release” #else #define __HAL_LOCK(__HANDLE__) \ do{ \ if((__HANDLE__)->Lock == HAL_LOCKED) \ { \ return HAL_BUSY; \ } \ else \ { \ (__HANDLE__)->Lock = HAL_LOCKED; \ } \ }while (0) #define __HAL_UNLOCK(__HANDLE__) \ do{ \ (__HANDLE__)->Lock = HAL_UNLOCKED; \ }while (0)
-
Всем доброго дня. Скачал самую свежую версию куба. В описаниях было много сказано о ее совместимости с FREERTOS. Интерсовал механизм приема-передачи данных по УАРТу в HAL драйвере. Возможности выставления флагов(событий) для RTOS. Как вариант буферы приема данных и т.п. и т.д. То,что увидел, очень сильно озадачило. Приемник HAL драйвера UART фактически неработоспсобен для общего применения???? Остальные драйверы пока не "копал", но если там сохранен такой же подход как и в УАРТе, то зачем все это надо было STm? Подрыгать ногами в демо проекте? Чем был плох CMSIS?
-
MQX RTOS
owl опубликовал тема в Операционные системы
Скачал Mqx от Freescale. Немного поизучал. Под рукой не было родных freescale процов. Перепилил под STM32F107. Ядро заработало. А вот уровень IO - драйвера вызывают вопросы. До этого большой практики в RTOS не было. Самый главные из вопросов почему именно так сложно. Ведь у все таки работаем с однокристаллкой. Иногда ножку надо дернуть и побыстрее. Почему не используется CMSIS? Или это не стандарт для АРМов? По хорошему напрашивается еще один подуровень - согласования. А вообще понравилось. Очень много "вкусных" вещей. Быстродействие для моего случая пока не проверял. -
Обновление прошивки в МК
owl ответил owl тема в Программирование
Криптование прошивок пока не предуматривается. Вопрос каким образом хранится ID железа? Загрузчик в МК имеет какую то версию и ID - или тип прибора . Т.е. - это по сути ID железа? Загрузчик верхнего уровня - читает этот ID. - т.е. знает тип железа и модификацию загручика. Остается записать файл основной программы. Причем сам файл по себе должен нести информацию о допустимости записи в тот или иной прибор. Выбор типа файла как правило bin или hex???? - Т.е. должны иметь служебные поля, позволяющие верхнему загрузчику по файлу определить тип железа для которого он предназначен. (ID, номер билда и т.п.) И версии поддерживаемого железа???? Также возникает вопрос о функционале загручика нижнего уровня. Его роль в защите от записи неправильной версии прошивки сводится лишь к выдаче собственного ID? И уже загрузчик верхнего уровня принимает решение о продолжении работы. Т.е. имеем набор загрузчиков под каждую уникальную версию железа. Или как вариант - служебное поле во флеше загручика - но это лишние операции при начальном программировании загрузчика. Т.е. программа верхнего уровня "парсила" заливаемую прошивку? (Как вариант искала текстовое описание устройства в прошивке) Ну и разумеется заменила более ранюю версию у клиента? -
Обновление прошивки в МК
owl опубликовал тема в Программирование
Мысли в слух. Кто чего может прделожить интересного. Имеем однокристалльный МК - как частность АРМ. Программа МК содержит самописный загрузчик и собственно основную программу. Собсвенно сами интересности: 1. Куча разнообразного железа, имеющего по сути дела одинаковый загрузчик. 2. Куча версий основных программ предназначенных для разных версий изделий, которые могут быть несовместимы с железом. (Более поздняя версия железа не подходит для старой прошивки и наоборот) Ну и как следствие проблемы: Залита не та версия программы - не в ту железку. Если на своем рабочем месте - это легко исправимо. Загрузчик - защищает сам себя от перезаписи и все легко можно откатить. А если где-то удаленно? И это делает человек очень далекий от железа и приборов перепрошивается много? А если после выпуска прибора прошло пару лет? Т.е. система должна быть дубовой и надежной)))) Дорогие форумчане, что можете предложить? Проблема ведь типовая? -
Ссылка на компоненты от Wurth Electronics Inc
owl опубликовал тема в Библиотеки компонентов
http://www.we-online.de/web/en/electronic_..._Center_PBS.php -
На просторах интернета наткнулся на статью по приведенной выше проблеме.(Объединение земель для ЮСБ) http://uk.farnell.com/images/en/ede/pdf/usb_dev_mistake.pdf - страница 7. Если ссылка уже была - просьба сильно не пинать)))). Думаю, что проблема до сих пор актуальна для многих здесь присутствующих.
-
Всем доброго дня. Возникла нужда в схеме зарядки литиевых АКБ. Необходимо заряжать 2 банки. По "религиозным" причинам схема должна быть линейной. Присмотрел BQ2057W. Сразу возник дурацкий вопрос, как подключить нагрузку к этой микросхеме? Т.е. есть питание - заряжаем АКБ и питаем схему, нет питания - работаем от АКБ. Может быть посоветуете что нибудь еще?
-
Пример как есть: настройка на прием 1 и 3го майлбокса #define RECIEVE_MAILBOX_NUMBER_1 1 #define RECIEVE_MAILBOX_NUMBER_3 3 #define TRANSMIT_MAILBOX_NUMBER 2 __ramfunc void init_can_reception(struct can_cmd_s *p_can, Uint32 id) { //AT91PS_CAN base_can; CanTransfer canTransfer1; AT91PS_CAN_MB CAN_Mailbox; CAN_Mailbox = AT91C_BASE_CAN0_MB0; CAN_Mailbox = (AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox + RECIEVE_MAILBOX_NUMBER_1)); CAN_Mailbox->CAN_MB_MCR = 0x0; CAN_Mailbox->CAN_MB_MMR = 0x00; CAN_Mailbox->CAN_MB_MAM = AT91C_CAN_MIDvA & ((~id) << (18)); CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << (18)); CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_RX; CAN_Mailbox = AT91C_BASE_CAN0_MB0; CAN_Mailbox = (AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox + RECIEVE_MAILBOX_NUMBER_3)); CAN_Mailbox->CAN_MB_MCR = 0x0; CAN_Mailbox->CAN_MB_MMR = 0x00; CAN_Mailbox->CAN_MB_MAM = AT91C_CAN_MIDvA & ((~id) << (18)); CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << (18)); p_can->accepted_id = AT91C_CAN_MIDvA & (id << (18)); CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_RX; AT91C_BASE_CAN0->CAN_IER = (1 << RECIEVE_MAILBOX_NUMBER_3); AT91C_BASE_CAN0->CAN_IER = (1 << RECIEVE_MAILBOX_NUMBER_1); } //Начало передачи по кан: if ((p_can->trans_state != CAN_SENDING) && (flag)) { res = read_can_data(p_can, &hi, &low, &id); if (res != 0) { CAN_Mailbox = AT91C_BASE_CAN0_MB0; CAN_Mailbox = (AT91PS_CAN_MB) ((unsigned int)(CAN_Mailbox + TRANSMIT_MAILBOX_NUMBER)); status = disable_can_interrupt(); can_msr = CAN_Mailbox->CAN_MB_MSR; if ((AT91C_CAN_MRDY & can_msr) != 0) { // dbg_send_str("Error busy"); enable_can_interrupt(status); return 1; } CAN_Mailbox->CAN_MB_MCR = 0x0; CAN_Mailbox->CAN_MB_MMR = 0x00; CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << 18); // ID 11 CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR; CAN_Mailbox->CAN_MB_MDL = low; CAN_Mailbox->CAN_MB_MDH = hi; CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MTCR | (AT91C_CAN_MDLC & (res << 16)); // Mailbox Data Length Code p_can->trans_state = CAN_SENDING; enable_can_interrupt(status | (1 << TRANSMIT_MAILBOX_NUMBER)); } return 0; } Обработчик прерывания: __ramfunc void CAN_Handler(void) { AT91PS_CAN_MB CAN_Mailbox; unsigned int status; unsigned int can_msr; unsigned int message_mode; unsigned int numMailbox; int res; int low, hi; unsigned short id; status = (AT91C_BASE_CAN0->CAN_SR); status &= (AT91C_BASE_CAN0->CAN_IMR); if (status & AT91C_CAN_WAKEUP) { AT91C_BASE_CAN0->CAN_IDR = AT91C_CAN_WAKEUP; pCAN0Transfer->test_can = AT91C_TEST_OK; pCAN0Transfer->state = CAN_IDLE; } /* if(status & AT91C_CAN_WARN){ can_cmd.error |= ERROR_CAN_WARN; AT91C_BASE_CAN0->CAN_IDR = AT91C_CAN_WARN; // (CAN) Form Error } */ // Mailbox event ? if ((status & 0x0000FFFF) != 0) { for (numMailbox = 1; numMailbox < 4; numMailbox++) { CAN_Mailbox = (AT91PS_CAN_MB) ((unsigned int)(AT91C_BASE_CAN0_MB0 + numMailbox)); can_msr = CAN_Mailbox->CAN_MB_MSR; if ((AT91C_CAN_MMI & can_msr) == AT91C_CAN_MMI) { // test_error_cntr++; can_cmd.error |= ERROR_CAN_MMI; if (numMailbox == RECIEVE_MAILBOX_NUMBER_3) { can_cmd.error |= ERROR_CAN_OVER_MAILBOX_3; } if (numMailbox == RECIEVE_MAILBOX_NUMBER_1) { can_cmd.error |= ERROR_CAN_OVER_MAILBOX_1; } } if ((AT91C_CAN_MABT & can_msr) == AT91C_CAN_MABT) { CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MACR; // test_error_cntr++; // can_cmd.error |= ERROR_CAN_ABT; } if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MRDY) { message_mode = (CAN_Mailbox->CAN_MB_MMR >> 24) & 0x7; if (message_mode == 0) { // test_error_cntr++; can_cmd.error |= ERROR_CAN_MODE; } else if ((message_mode == CAN_MOT_RECEPT) || (message_mode == CAN_MOT_RECEPT_OW)) { low = CAN_Mailbox->CAN_MB_MDL; hi = CAN_Mailbox->CAN_MB_MDH; dispatch_can_data(&can_cmd, hi, low, (can_msr >> 16) & 0xF, (CAN_Mailbox-> CAN_MB_MID & AT91C_CAN_MIDvA) >> 18); AT91C_BASE_CAN0->CAN_IER = 1 << numMailbox; // test_all_recv += (can_msr>>16)&0xF; CAN_Mailbox->CAN_MB_MMR = 0x0; CAN_Mailbox->CAN_MB_MID = can_cmd.accepted_id; CAN_Mailbox->CAN_MB_MMR = AT91C_CAN_MOT_RX; CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MTCR; if (numMailbox == RECIEVE_MAILBOX_NUMBER_3) { // test_error_cntr++; can_cmd.error |= ERROR_CAN_OVER_MAILBOX; } } else if (message_mode == CAN_MOT_TRANSMIT) { can_cmd.trans_state = CAN_IDLE; can_msr = CAN_Mailbox->CAN_MB_MSR; /* if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MABT) { CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MABT; } */ if ((AT91C_CAN_MRDY & can_msr) == AT91C_CAN_MRDY) { CAN_Mailbox->CAN_MB_MCR = 0x0; CAN_Mailbox->CAN_MB_MMR = 0x0; res=0; res = read_can_data(&can_cmd, &hi, &low, &id); if (res) { CAN_Mailbox->CAN_MB_MID = AT91C_CAN_MIDvA & (id << 18); // ID 11 CAN_Mailbox-> CAN_MB_MMR = AT91C_CAN_MOT_TX | AT91C_CAN_PRIOR; CAN_Mailbox-> CAN_MB_MDL = low; CAN_Mailbox-> CAN_MB_MDH = hi; // Mailbox Data Length Code CAN_Mailbox->CAN_MB_MCR = AT91C_CAN_MTCR | (AT91C_CAN_MDLC & (res << 16)); AT91C_BASE_CAN0->CAN_IER = 1 << numMailbox; //??????? can_cmd.trans_state = CAN_SENDING; } } else { can_cmd.error |= ERROR_CAN_MRDY; } } } } } if ((status & 0xFFCF0000) != 0) { CAN_ErrorHandling(status, 0); } }
-
ISA+ПЛИС
owl ответил Сергей СС тема в Интерфейсы
Автор книги: Ю.В.Новиков, О.А.Калашников, С.Э.Гуляев Разработка устройств сопряжения для персонального компьютера типа IBM PC Посмотрите эту книгу, в свое время она мне здорово помогла. Использовал CPLD от Xilinx XC95144(XL) -
//------------------------------------------------------------------------------ /// baudrate calcul /// \param base_CAN CAN base address /// \param baudrate Baudrate value (kB/s) /// allowed values: 1000, 800, 500, 250, 125, 50, 25, 10 /// \return return 1 in success, otherwise return 0 //------------------------------------------------------------------------------ unsigned char CAN_BaudRateCalculate(AT91PS_CAN base_CAN, unsigned int baudrate) { unsigned int BRP; unsigned int PROPAG; unsigned int PHASE1; unsigned int PHASE2; unsigned int SJW; unsigned int t1t2; unsigned char TimeQuanta; base_CAN->CAN_BR = 0; if (baudrate == 1000) { TimeQuanta = 8; } else { TimeQuanta = 16; } BRP = (BOARD_MCK / (baudrate * 1000 * TimeQuanta)) - 1; //TRACE_DEBUG("BRP = 0x%X\n\r", BRP); // timing Delay: // Delay Bus Driver: 50 ns // Delay Receiver: 30 ns // Delay Bus Line (20m): 110 ns if ((TimeQuanta * baudrate * 2 * (50 + 30 + 110) / 1000000) >= 1) { PROPAG = (TimeQuanta * baudrate * 2 * (50 + 30 + 110) / 1000000) - 1; } else { PROPAG = 0; } //TRACE_DEBUG("PROPAG = 0x%X\n\r", PROPAG); t1t2 = TimeQuanta - 1 - (PROPAG + 1); //TRACE_DEBUG("t1t2 = 0x%X\n\r", t1t2); if ((t1t2 & 0x01) == 0x01) { // ODD //TRACE_DEBUG("ODD\n\r"); PHASE1 = ((t1t2 - 1) / 2) - 1; PHASE2 = PHASE1 + 1; } else { // EVEN //TRACE_DEBUG("EVEN\n\r"); PHASE1 = (t1t2 / 2) - 1; PHASE2 = PHASE1; } //TRACE_DEBUG("PHASE1 = 0x%X\n\r", PHASE1); //TRACE_DEBUG("PHASE2 = 0x%X\n\r", PHASE2); if (1 > (4 / (PHASE1 + 1))) { //TRACE_DEBUG("4*Tcsc\n\r"); SJW = 3; } else { //TRACE_DEBUG("Tphs1\n\r"); SJW = PHASE1; } //TRACE_DEBUG("SJW = 0x%X\n\r", SJW); // Verif if (BRP == 0) { TRACE_DEBUG("BRP = 0 is not authorized\n\r"); return 0; } if ((PROPAG + PHASE1 + PHASE2) != (TimeQuanta - 4)) { TRACE_DEBUG("Pb (PROPAG + PHASE1 + PHASE2) = %d\n\r"); TRACE_DEBUG("with TimeQuanta-4 = %d\n\r"); return 0; } base_CAN->CAN_BR = (AT91C_CAN_PHASE2 & (PHASE2 << 0)) + (AT91C_CAN_PHASE1 & (PHASE1 << 4)) + (AT91C_CAN_PROPAG & (PROPAG << 8)) + (AT91C_CAN_SYNC & (SJW << 12)) + (AT91C_CAN_BRP & (BRP << 16)) + (AT91C_CAN_SMP & (0 << 24)); return 1; } Функция настройки частоты CAN как есть. Автоопределение скорости не пробовал, подсказать ничем не могу. Для работы с CAN вам потребуется минимум 2 устройства!!! Частота CAN должна быть достаточно точно выбрана для обоих.