Перехватить USART ISR, не прибегая к взлому ядра

Рива
Чт 16 февраля 2017 г., 17:16
Я работаю над кодом (который в конечном итоге может стать библиотекой), чтобы реализовать протокол освещения DMX512 на Maple Mini.

За исключением нескольких проблем с прорезыванием зубов, доказательство концепции TX -код написан и работает, поэтому я сейчас концентрируюсь на коде RX и нажимал на заглушку, где вы не можете перехватить/заменить векторы прерывания USART, определенные в USART_F1.C без редактирования файла и удаления определений (ы) для USART, который вы хотите контролировать.
Кленовые документы сказали где -нибудь, что их следует сделать __weak, чтобы их можно было заменить без необходимости взломать основные файлы, но этого никогда не произошло, и у меня нет реального представления, как это сделать.
Только что предшествует USART_F1.C Определение с __weak работает нормально, если я пишу код прерывания, чтобы справиться с ним, но если у вас нет собственного кода прерывания, я бы ожидал/надеялся, что исходное определение будет преобладать, но это не так и не блокирует MCU. waitTone (frequency, duration){ tone(frequency, duration); delay(duration); }

victor_pv
Чт 16 февраля 2017 г. 18:11
Рива написал:Я работаю над кодом (который в конечном итоге может стать библиотекой), чтобы реализовать протокол освещения DMX512 на Maple Mini.

За исключением нескольких проблем с прорезыванием зубов, доказательство концепции TX -код написан и работает, поэтому я сейчас концентрируюсь на коде RX и нажимал на заглушку, где вы не можете перехватить/заменить векторы прерывания USART, определенные в USART_F1.C без редактирования файла и удаления определений (ы) для USART, который вы хотите контролировать.
Кленовые документы сказали где -нибудь, что их следует сделать __weak, чтобы их можно было заменить без необходимости взломать основные файлы, но этого никогда не произошло, и у меня нет реального представления, как это сделать.
Только что предшествует USART_F1.C Определение с __weak работает нормально, если я пишу код прерывания, чтобы справиться с ним, но если у вас нет собственного кода прерывания, я бы ожидал/надеялся, что исходное определение будет преобладать, но это не так и не блокирует MCU. tone(tonePin, 200); delay(duration);

Рива
Пт 17 февраля 2017 г. 9:29
victor_pv написал: Вам нужно полностью заменить обработчик IRQ USART, или вам просто нужно добавить к обработчику?
Во втором случае, возможно, вы могли бы изменить ядро, чтобы позволить ему прикрепить дополнительную функцию, которую можно было бы вызвать до или после обработчика ядра, аналогично прерываниям DMA, где есть обработчик, который сделает несколько вещей, а затем вызвано Пользователь определил обработчик, если он был прикреплен.
В идеале я хочу заменить обработчик по умолчанию, но использование крюка может быть опцией, если код IRQ по умолчанию может быть сказано для обработки/игнорирования в зависимости от кода возврата крюка.
Для первого случая я бы подумал, что __weak должен работать, но, поскольку символы (__irq_usart1 и т. Д.) Уже слабы в таблице прерываний, возможно, это делает __weak не работать нормально в функции?
__weak работает нормально до тех пор, пока я определяю обработчики IRQ, но если я не определю его, я бы ожидал, что вместо этого будет использоваться по умолчанию, но кажется, что по умолчанию не связан, поэтому любой код, который использует последовательный, просто блокируется.

Был еще один способ объявить эти символы слабыми, которые я применил в прошлом году на что -то (не полностью помню, для чего это было, но я думаю, что был связан с PIN_MAP в RAM, который мы решили по -другому), вы можете видеть В истории этого файла, как он использовал SleedRef.
Это все, что нужно немного продвинуть для моих навыков C ++, поскольку, несмотря на чтение здесь Я не мудрый, в чем разница между слабым & SleedRef.

Вы можете проверить, чтобы заменить этот файл на версию, в которой использовались SleedRefs, и посмотреть, работает ли в этом случае параметр __weak в функции, как и ожидалось.
Попробую и сообщит.

РЕДАКТИРОВАТЬ:
Я проверял, когда и почему мы проверили слабые. Я не читаю всю историю, но это было связано с некоторыми ошибками, когда -Wall был удален из параметров линкера.
В одном из сообщений Рик связан с этим файлом:
https: // github.com/leaflabs/libmaple/bl ... разрывы.текст
Который содержит этот абзац: ВАЖНО: Функция, которую вы определяете. C ++ Имя
Черьев путает линкеров, и он не найдет вашу функцию. Так
Если вы пишете свой обработчик IRQ в файле C ++, вам нужно определить
это так:

extern "c" void __irq_sdio (void) {
// и т. д.
}
Может, тогда я делаю это неправильно, так как у меня есть for ( int i=0;i<6;i++){ pinMode(leds[i], OUTPUT); digitalWrite(leds[i], LOW); }; pinMode(pOut,OUTPUT); pinMode(pPiezzo,OUTPUT); digitalWrite(pOut,LOW); digitalWrite(pPiezzo,LOW); // }}} // {{{ =========================== Make light show ============================================= tone(pPiezzo,440,600); // beep :) for (int i=0;i<63;i++){ Show(i); delay(10);}; tone(pPiezzo,660,600); // beep :) for ( int i=0;i<6;i++){ digitalWrite(leds[i], HIGH); delay(100); }; tone(pPiezzo,880,600); // beep :) for ( int i=0;i<6;i++){ digitalWrite(leds[i], LOW); delay(100); }; tone(pPiezzo,880,600); // beep :) for (int i=0;i<63;i++){ Show(i); delay(10);}; tone(pPiezzo,440,20); delay(20); // }}} // {{{ go serious

Рива
Пт 17 февраля 2017 г. 11:07
@victor_pv прибегает к фразу, чтобы я молодо.
Вы можете проверить, чтобы заменить этот файл на версию, в которой использовались SleedRefs, и посмотреть, работает ли в этом случае параметр __weak в функции, как и ожидалось.
Попробую и сообщит.
Изменение .установить на .ShandeRef для обработчиков USART в ISRS.S -файл и добавление __weak к обработчикам прерываний в USART_F1.C означает, что я, кажется, могу перехватывать IRQ по умолчанию в коде, и если я не перехватываю, то исходный код все еще работает.
Это то, что стоит рассмотреть для основного изменения? С учетом более тщательного тестирования.

victor_pv
Пт 17 февраля 2017 г. 12:27
Рива написал:@victor_pv прибегает к фразу, чтобы я молодо.
Вы можете проверить, чтобы заменить этот файл на версию, в которой использовались SleedRefs, и посмотреть, работает ли в этом случае параметр __weak в функции, как и ожидалось.
Попробую и сообщит.
Изменение .установить на .ShandeRef для обработчиков USART в ISRS.S -файл и добавление __weak к обработчикам прерываний в USART_F1.C означает, что я, кажется, могу перехватывать IRQ по умолчанию в коде, и если я не перехватываю, то исходный код все еще работает.
Это то, что стоит рассмотреть для основного изменения? С учетом более тщательного тестирования.

victor_pv
Пт 17 февраля 2017 г., 17:11
Рива написал:@victor_pv прибегает к фразу, чтобы я молодо.
Вы можете проверить, чтобы заменить этот файл на версию, в которой использовались SleedRefs, и посмотреть, работает ли в этом случае параметр __weak в функции, как и ожидалось.
Попробую и сообщит.
Изменение .установить на .ShandeRef для обработчиков USART в ISRS.S -файл и добавление __weak к обработчикам прерываний в USART_F1.C означает, что я, кажется, могу перехватывать IRQ по умолчанию в коде, и если я не перехватываю, то исходный код все еще работает.
Это то, что стоит рассмотреть для основного изменения? С учетом более тщательного тестирования.

Rogerclark
Сб 18 февраля 2017 г. 1:13
Если мы сможем выяснить, есть ли какие -либо недостатки, чтобы превратить их в слабые ссылки, я буду рад принять пиар, чтобы изменить это.

Но нам нужно было бы очень уверено, что это не сломает что -то ;-)

victor_pv
Сб 18 февраля 2017 г., 4:03
Rogerclark написал:Если мы сможем выяснить, есть ли какие -либо недостатки, чтобы превратить их в слабые ссылки, я буду рад принять пиар, чтобы изменить это.

Но нам нужно было бы очень уверено, что это не сломает что -то ;-)

Rogerclark
Сб 18 февраля 2017 г. 6:15 утра
Привет, Виктор

Я не предлагаю обширных тестирования, но в прошлом мы были пойманы, меняя вещи в прошлом, что имело непреднамеренные последствия.

Racemaniac
Сб 18 февраля 2017 г. 6:34
victor_pv написал:Rogerclark написал:Если мы сможем выяснить, есть ли какие -либо недостатки, чтобы превратить их в слабые ссылки, я буду рад принять пиар, чтобы изменить это.

Но нам нужно было бы очень уверено, что это не сломает что -то ;-)

Рива
Сб 18 февраля 2017 г. 9:51
@victor_pv

Это версия, которую я сделал // PDP-8 emulator // -jcw, 2016-08-29 // Modded for STM32duino by Pito 11/2016 // . you need the Serial.printf() hack, hopefully it printfs Octals :) // http://www.stm32duino.com/viewtopic.php?f=18&t=1014#p12014 // . place "focal.h" file to this pdp8.ino sketch for compilation (focal.h attached) // . Serial1 used here // . set Serial to 9600 (I do here with 115k2 but it is too fast, it seems) // No warranties of any kind.. #include typedef unsigned short Word; int errno, EIO; int rxData = -1; int txReady (void) { return 1; } void txSend (char ch) { while (!txReady()) // not strictly needed for emulation, only for printf ; Serial1.print(ch); } const unsigned char program[] = { #include "focal.h" }; #define MEMSIZE 4096 Word pc, mem[MEMSIZE]; static Word mask(Word w) { return w & 07777; } static Word lmask(Word w) { return w & 017777; } static Word opAddr (int ir) { Word a = ir & 0177; if (ir & 0200) a |= (pc - 1) & 07600; if (ir & 0400) { if ((a & 07770) == 010) mem[a] = mask(mem[a] + 1); a = mem[a]; } return a; } static int loader (const unsigned char* ptr) { Word addr = 0; Serial1.printf("LOAD"); Word b; for (;;) { // read next word b = *ptr++; if (b & 0200) // skip run-in continue; b = (b << 6) | *ptr++; // look for run-out, to ignore word before it as being a checksum int c = *ptr; if (c & 0200) break; // process one word if (b & 010000) { if (addr != 0) Serial1.printf("-%04o", addr - 1); addr = mask(b); Serial1.printf(" %04o", addr); } else mem[addr++] = b; } Serial1.printf("-%04o CHECK %04o\n", mask(addr - 1), mask(b)); return addr; } void run () { if (loader(program) == 0) return; pc = 0200; Word sr = 0; Word ac = 0, mq = 0; int iena = 0; for (;;) { iena >>= 1; // delayed interrupt enabling, relies on sign extension static short counter; // HACK: every 1024 ops, we fake an interrupt if ((iena & 1) && (++counter & 0x03FF) == 0) { mem[0] = pc; pc = 1; iena = 0; } int ir = mem[pc]; //if (argc >= 5) // Serial1.printf("PC %04o IR %04o\r\n", pc, ir); pc = mask(pc + 1); switch ((ir >> 9) & 07) { case 0: // AND ac &= mem[opAddr(ir)] | 010000; break; case 1: // TAD ac = lmask(ac + mem[opAddr(ir)]); break; case 2: { // ISZ Word t = opAddr(ir); mem[t] = mask(mem[t] + 1); if (mem[t] == 0) pc = mask(pc + 1); break; } case 3: // DCA mem[opAddr(ir)] = mask(ac); ac &= 010000; break; case 4: { // JMS Word t = opAddr(ir); mem[t] = pc; pc = mask(t + 1); break; } case 5: // JMP pc = opAddr(ir); break; case 6: // IOT switch ((ir >> 3) & 077) { case 00: switch (ir) { case 06001: iena = ~1; break; // delays one cycle case 06002: iena = 0; break; default: Serial1.printf("IOT %04o AC=%04o\r\n", ir, ac); } break; case 03: // keyboard if (Serial1.available() > 0) rxData = Serial1.read(); if ((ir & 01) && rxData >= 0) // skip if ready pc = mask(pc + 1); if (ir & 04) { // read byte int b = rxData & 0xFF; rxData = -1; ac = (ac & 010000) | b; } break; case 04: // teleprinter if ((ir & 01) && txReady()) // skip if ready pc = mask(pc + 1); if (ir & 04) // send byte txSend(ac & 0177); // strip off parity if (ir & 02) // clear flag ac &= 010000; break; default: //Serial1.printf("IOT %04o AC=%04o\r\n", ir, ac); break; } break; case 7: // OPR if ((ir & 0400) == 0) { // group 1 if (ir & 0200) // CLA ac &= 010000; if (ir & 0100) // CLL ac &= 07777; if (ir & 040) // CMA ac ^= 07777; if (ir & 020) // CML ac ^= 010000; if (ir & 01) // IAC ac = lmask(ac + 1); switch (ir & 016) { case 012: // RTR ac = lmask((ac >> 1) | (ac << 12)); // fall through case 010: // RAR ac = lmask((ac >> 1) | (ac << 12)); break; case 06: // RTL ac = lmask((ac >> 12) | (ac << 1)); // fall through case 04: // RAL ac = lmask((ac >> 12) | (ac << 1)); break; case 02: // BSW ac = (ac & 010000) | ((ac >> 6) & 077) | ((ac << 6) & 07700); break; } } else if ((ir & 01) == 0) { // group 2 // SMA, SPA, SZA, SNA, SNL, SZL int s = ((ir & 0100) && (ac & 04000)) || ((ir & 040) && (ac & 07777) == 0) || ((ir & 020) && (ac & 010000) != 0) ? 0 : 010; if (s == (ir & 010)) pc = mask(pc + 1); if (ir & 0200) // CLA ac &= 010000; if (ir & 04) // OSR ac |= sr; if (ir & 02) { // HLT Serial1.printf("\r\nHALT %04o", mask(ac)); return; } } else { // group 3 Word t = mq; if (ir & 0200) // CLA ac &= 010000; if (ir & 020) { // MQL mq = ac & 07777; ac &= 010000; } if (ir & 0100) ac |= t; } break; } } } void setup() { // put your setup code here, to run once: Serial1.begin(115200); run(); } void loop() { // put your main code here, to run repeatedly: }

Рива
Сб 18 февраля 2017 г. 10:03
Rogerclark написал:Если мы сможем выяснить, есть ли какие -либо недостатки, чтобы превратить их в слабые ссылки, я буду рад принять пиар, чтобы изменить это.

Но нам нужно было бы очень уверено, что это не сломает что -то ;-)

victor_pv
Сб 18 февраля 2017 г. 13:53
Реданьяк написал:victor_pv написал:Rogerclark написал:Если мы сможем выяснить, есть ли какие -либо недостатки, чтобы превратить их в слабые ссылки, я буду рад принять пиар, чтобы изменить это.

Но нам нужно было бы очень уверено, что это не сломает что -то ;-)

Рик Кимбалл
Сб 18 февраля 2017 г. 14:11
victor_pv написал:В прошлый раз, когда мы попробовали это, мы вернулись из -за некоторых проблем, но не ясно, были ли проблемы, связанные с этим изменением, или с удалением -стенком, так что стоит проверить, но нам нужно проверить его с таким же количеством разных периферийные устройства как можно более.

Рива
Сб 18 февраля 2017 г. 16:27
victor_pv написал:Реданьяк написал:victor_pv написал: Я на самом деле не использую его, я использую обычное ядро, но, кажется, работает для проблемы, с которой сталкивалась Рива.
Вы используете его для всех обработчиков IRQ или в каких случаях?

victor_pv
Сб 18 февраля 2017 г., 19:40
Рик Кимбалл написал:victor_pv написал:В прошлый раз, когда мы попробовали это, мы вернулись из -за некоторых проблем, но не ясно, были ли проблемы, связанные с этим изменением, или с удалением -стенком, так что стоит проверить, но нам нужно проверить его с таким же количеством разных периферийные устройства как можно более.

Mrburnette
Солнце 19 февраля 2017 г. 16:31
Теперь с добавлением SleedRef также я могу начать все 3 USARTS и иметь только код прерывания USART для USART2, и MCU продолжает работать. Также нормальный эскиз без какого -либо кода прерывания USART работает нормально. Я был активен здесь, в дни BOBC Andvbobc, и у меня был ряд автономных разговоров о C ++ и проблемы с тем, как Arduino Arackited.

В Riva есть обходной путь, я бы предположил, что довольно подробное резюме этого успеха будет помещено в вики и что ядро ​​остается как есть. Arduino никогда не будет таким гибким, как Pure C ++, и большинство пользователей просто довольны Arduino за его автоматическое прототипирование и простоту использования. Большинство из нас знают, что у Arduino есть ограничения. Я полагаю, что более безопасный подход заключается в документировании, как обойти ограничения и избежать массовой инженерной переделки в сердечнике.

Луча

iwdg_init () и iwdg_feed ()