|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 2:23 am
|
Страница 1 от 1
|
[ 11 мнения ] |
|
| Автор |
Съобщение |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 CBS setup
http://mbed.org/users/igorsk/programs/DriverLibrary/601ro/docs/lpc17xx__uart_8c_source.html |  |  |  | Код: /*********************************************************************//** 00216 * @brief General UART interrupt handler and router 00217 * @param[in] UARTx Selected UART peripheral, should be UART0..3 00218 * @return None 00219 * 00220 * Note: 00221 * - Handles transmit, receive, and status interrupts for the UART. 00222 * Based on the interrupt status, routes the interrupt to the 00223 * respective call-back to be handled by the user application using 00224 * this driver. 00225 * - If callback is not installed, corresponding interrupt will be disabled 00226 * - All these interrupt source below will be checked: 00227 * - Transmit Holding Register Empty. 00228 * - Received Data Available and Character Time Out. 00229 * - Receive Line Status (not implemented) 00230 * - End of auto-baud interrupt (not implemented) 00231 * - Auto-Baudrate Time-Out interrupt (not implemented) 00232 * - Modem Status interrupt (UART0 Modem functionality) 00233 * - CTS signal transition interrupt (UART0 Modem functionality) 00234 **********************************************************************/ 00235 void UART_GenIntHandler(LPC_UART_TypeDef *UARTx) 00236 { 00237 uint8_t pUart, modemsts; 00238 uint32_t intsrc, tmp, tmp1; 00239 00240 pUart = getUartNum(UARTx); 00241 00242 /* Determine the interrupt source */ 00243 intsrc = UARTx->IIR; 00244 tmp = intsrc & UART_IIR_INTID_MASK; 00245 00246 /* 00247 * In case of using UART1 with full modem, 00248 * interrupt ID = 0 that means modem status interrupt has been detected 00249 */ 00250 if (pUart == 1) { 00251 if (tmp == 0){ 00252 // Check Modem status 00253 modemsts = LPC_UART1->MSR & UART1_MSR_BITMASK; 00254 // Call modem status call-back 00255 if (pfnModemCbs != NULL){ 00256 pfnModemCbs(modemsts); 00257 } 00258 // disable modem status interrupt and CTS status change interrupt 00259 // if its callback is not installed 00260 else { 00261 LPC_UART1->IER &= ~(UART1_IER_MSINT_EN | UART1_IER_CTSINT_EN); 00262 } 00263 } 00264 } 00265 00266 // Receive Line Status 00267 if (tmp == UART_IIR_INTID_RLS){ 00268 // Check line status 00269 tmp1 = UARTx->LSR; 00270 // Mask out the Receive Ready and Transmit Holding empty status 00271 tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \ 00272 | UART_LSR_BI | UART_LSR_RXFE); 00273 // If any error exist 00274 if (tmp1) { 00275 // Call Call-back function with error input value 00276 if (uartCbsDat[pUart].pfnErrCbs != NULL) { 00277 uartCbsDat[pUart].pfnErrCbs(tmp1); 00278 } 00279 // Disable interrupt if its call-back is not install 00280 else { 00281 UARTx->IER &= ~(UART_IER_RLSINT_EN); 00282 } 00283 } 00284 } 00285 00286 // Receive Data Available or Character time-out 00287 if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){ 00288 // Call Rx call back function 00289 if (uartCbsDat[pUart].pfnRxCbs != NULL) { 00290 uartCbsDat[pUart].pfnRxCbs(); 00291 } 00292 // Disable interrupt if its call-back is not install 00293 else { 00294 UARTx->IER &= ~(UART_IER_RBRINT_EN); 00295 } 00296 } 00297 00298 // Transmit Holding Empty 00299 if (tmp == UART_IIR_INTID_THRE){ 00300 // Call Tx call back function 00301 if (uartCbsDat[pUart].pfnTxCbs != NULL) { 00302 uartCbsDat[pUart].pfnTxCbs(); 00303 } 00304 // Disable interrupt if its call-back is not install 00305 else { 00306 UARTx->IER &= ~(UART_IER_THREINT_EN); 00307 } 00308 } 00309 00310 intsrc &= (UART_IIR_ABEO_INT | UART_IIR_ABTO_INT); 00311 // Check if End of auto-baudrate interrupt or Auto baudrate time out 00312 if (intsrc){ 00313 // Clear interrupt pending 00314 UARTx->ACR |= ((intsrc & UART_IIR_ABEO_INT) ? UART_ACR_ABEOINT_CLR : 0) \ 00315 | ((intsrc & UART_IIR_ABTO_INT) ? UART_ACR_ABTOINT_CLR : 0); 00316 if (uartCbsDat[pUart].pfnABCbs != NULL) { 00317 uartCbsDat[pUart].pfnABCbs(intsrc); 00318 } else { 00319 // Disable End of AB interrupt 00320 UARTx->IER &= ~(UART_IER_ABEOINT_EN | UART_IER_ABTOINT_EN); 00321 } 00322 } 00323 } 00324 00325 /** 00326 * @} 00327 */
/*********************************************************************//** 01448 * @brief Setup call-back function for UART interrupt handler for each 01449 * UART peripheral 01450 * @param[in] UARTx Selected UART peripheral, should be UART0..3 01451 * @param[in] CbType Call-back type, should be: 01452 * 0 - Receive Call-back 01453 * 1 - Transmit Call-back 01454 * 2 - Auto Baudrate Callback 01455 * 3 - Error Call-back 01456 * 4 - Modem Status Call-back (UART1 only) 01457 * @param[in] pfnCbs Pointer to Call-back function 01458 * @return None 01459 **********************************************************************/ 01460 void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs) 01461 { 01462 uint8_t pUartNum; 01463 01464 pUartNum = getUartNum(UARTx); 01465 switch(CbType){ 01466 case 0: 01467 uartCbsDat[pUartNum].pfnRxCbs = (fnTxCbs_Type *)pfnCbs; 01468 break; 01469 case 1: 01470 uartCbsDat[pUartNum].pfnTxCbs = (fnRxCbs_Type *)pfnCbs; 01471 break; 01472 case 2: 01473 uartCbsDat[pUartNum].pfnABCbs = (fnABCbs_Type *)pfnCbs; 01474 break; 01475 case 3: 01476 uartCbsDat[pUartNum].pfnErrCbs = (fnErrCbs_Type *)pfnCbs; 01477 break; 01478 case 4: 01479 pfnModemCbs = (fnModemCbs_Type *)pfnCbs; 01480 break; 01481 default: 01482 break; 01483 } 01484 } 01485 01486 /*********************************************************************//**
|  |  |  |  |
Нещо не мога да вържа драйверите към вектора на прекъсване, Когато се опитвам да ползвам подонби драйвери, при влизане в прекъсване , вектора на прекъсването ме праща в някакъв безкраен цикъл даден по умолчание ... Как става в това ГЦЦ.
_________________ Вниманиене съмвишист....ИЙ.
|
| Пон Авг 29, 2011 9:55 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11265 Местоположение: Добрич
|
 Re: CBS setup
Тоя цикъл да не би случайно да е fault exception ? Като викаш функция при ARM най-младшия бит указва дали да се смени режима (thumb/arm).... от тук и "указател към функция" е малко подвеждащ. Ако го ползваш като адрес за данни (както ти май го присвояваш към void*) се взема началния адрес на функцията.... И след това като го кастнеш до указател към функция компилатора няма откъде да знае каква е била функцията (arm или thumb). Всъщност разчита че му подаваш адрес + mode. С две думи или не лъжи GCC с тайпкастове и не му крий типовете... или след като си го излъгал му добавяй 1 за thumb функции...
|
| Пон Авг 29, 2011 10:17 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 Re: CBS setup
Това е драйвер за LPC17xx УАРТ.0.1.2. Предоставен е свободно от NXP. До сега не съм го ползвал, по право почти не съм ползвал такива процесори, освен I2C с полиране на трансфера без прекъсване. Сега ми трябва една температура един ОУ с управляемо усилване, и то на и2с. Температурния датчик ще ми дава температура минимум през 100мс, и ще ми трябват прекъсванията на и2ц, или не мога да измисля трансвер с полиране към повече от 1 слейф без да замотам нещата. В стартъп фаила имам #pragma weak UART_IRQHandler = Default_Handler след това static void Default_Handler(void) { /* Go into an infinite loop. */ while (1) { } } Да .... и сега функцията за обработка на прекъсванията на УАРТ са ми в съвсем друг файл lpc17xx_uart.c Ако направя така: В началото на стартъп фаила extern void UART_GenIntHandler (void); // въпреки че функцията има атрибути, може ли да е void и след това... #pragma weak UART_IRQHandler = UART_GenIntHandler Как да вържа вектора UART_IRQHandler с обработката на прекъсванията UART_GenIntHandler във външен файл
_________________ Вниманиене съмвишист....ИЙ.
|
| Вто Авг 30, 2011 1:03 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11265 Местоположение: Добрич
|
 Re: CBS setup
досега не съм се занимавал с LPC а да почна аз едва ли ще ползвам техен код. Така че не мога а и не искам да вниквам какво правят те и какво правиш ти...
Това, което мога да помогна е принципни въпроси свързани с АРМ архитектурата и GCC. Единия проблем ти го казах с указателите към функции и тайпкастовете. А другото нещо е WEAK атрибута - той може да се слага към произволен ликерски символ (функиция, глобална променлива и т.н.) Няма отношение към типа на нещото. Има отношение към линкването (свързването). Нормално при линкване ако се появят две дефиниции на нещо от един и същ тип се получава грешка. Но ако едно от нещата е WEAK няма да има грешка, то ще се игнорира и вместо него ще линкне и ползва другото нещо.
Идеята е не само да няма грешки, чрез WEAK може да се портва чужд код, без да се налага да пипаш из чуждите сорсове. Примерно (не знам дали е така при теб) може да имаш готов стартъп файл, в който има някакъв хендлър на UART. Може да го използваш тоя код така както си е и по подразбиране ще се ползва тоя хендлър в него. Но ако не те кефи и ако тоя хендлър е с WEAK атрибут ти може някъде другаде в твоя проект да направиш функция със същото име и тип, но без weak. При линкване ще се ползва твоята функция, а wеак-функциията ще изчезне. Забележи, че така може да подменяш функции, без да пипаш чуждите сорс файлове. Така ако утре излезе нова версия на чуждия файл - само си го копираш, без да се притесняваш че ще изгубиш твоите редакции...
|
| Вто Авг 30, 2011 1:59 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 Re: CBS setup
С клизма ... проблема замазах така. extern void UART_StdIntHandler(void); //Указах му че има външна #pragma weak UART_IRQHandler = UART_Handler в същия файл с нова функция викам extern-а която ми трябва static void UART_Handler(void) { void UART_StdIntHandler(void); }  една дивотия се замазва с две други ...
_________________ Вниманиене съмвишист....ИЙ.
|
| Вто Авг 30, 2011 2:42 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11265 Местоположение: Добрич
|
 Re: CBS setup
верно правиш дивотии  Значи в стартъп файла ти предполагам имаш векторна таблица, в която за uart-a вектора е UART_IRQHandler Тъй като не се знае дали тоя стартъп код ще се ползва с uart или без, хората са ти сложили: Тая прагма създава weak символ UART_IRQHandler който сочи към Default_Handler, така стартъп файла ще може да се компилира при всякакви обстоятелства. Има си вектор, има си и хендлът (дефаулта).... От тук нататък най-логичното е ти да сложиш още сорс файл в който да има нормален/истински UART_IRQHandler без атрибути и без прагми. При свързване линкера ще види че имаш един нормален символ UART_IRQHandler и един weak. И навсякъде ще замести с нормалния. Ти обаче правиш втори weak UART_IRQHandler, който сочи към UART_Handler..... Що?? Искаш да объркаш линкера и да се чуди кой от двата weak-а да ползва?
|
| Вто Авг 30, 2011 4:17 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 Re: CBS setup
Малко бях зает но успях да си направя, комуникацията. miro_atc , благодаря ти много. Не знам но ми харесват тези драйвери, притеснителното за мен е че са написани много професионално и трябваше да седна да разгледам много добре кода. Не е като CVAVR , CCS или микроелектроника.  Отне ми 10-ки часове разучаване.
_________________ Вниманиене съмвишист....ИЙ.
|
| Пет Сеп 02, 2011 10:53 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 Re: CBS setup
 Искам да питам още нещо! Как наи-добре да си организирам достъпа до Read/Write array в предварително дефинирана в опциите на компилатора област.
_________________ Вниманиене съмвишист....ИЙ.
|
| Съб Сеп 03, 2011 1:49 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11265 Местоположение: Добрич
|
 Re: CBS setup
ммм... не съм убеден, че разбирам какво се опитваш да направиш По принцип имаш препроцесор (CPP), компилатор (GCC) и линкер (LD). Това са три различни неща, всяко работи с различни понятия и си имат различни опции, макар че може да работиш само с GCC и да го накараш то индиректно да извиква останалите. В последния случай опциите наистина са на едно място, но въпреки всичко е добре да знаеш коя опция за кого де отнася. Сега опции за дефиниране на array не знам да има. Не че знам всичко де, но мисля че няма такова животно  Има опция (-D) с която може да дефинираш символ - просто символ. Това е опция на препроцесора, т.е. може да имаш #ifdef примерно с тоя символ. Но пак подчертавам, че това няма връзка с типове и масиви на компилатора. Идеята на препроцесорните символи е по-скоро да си конфигурираш кода, примерно ако еди кой си символ е дефиниран да се компилира еди какво си... опс... всъщност ти говориш за "област", която е дефинира в опциите на компилатора.. Е па такова животно хептен няма  Не знам за области... има "секции", но секциите не се дефинират в компилатора. На ниво компилация не е нужно и не се дефинират секции. Може само да кажеш кой обект в коя секция да бъде. Това става в сорса, не чрез опции. Виж на линкера май може да му дефинираш секции чрез опции, макар че по-разумно е да се ползва скрипт файл. Но хайде първо кажи за какво иде реч, че да не гадая и да не обяснявам неща дето може и да не те интересуват....
|
| Съб Сеп 03, 2011 5:24 pm |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 672
|
 Re: CBS setup
Нещо съм в грешка  Конфигурацийте са били за IROM IRAM1 Интересуваше ме използването на In-Application Programming (IAP) за дефиниране на FRAM и записване на променливи в определена област от вътрешния flash (10к цикъла) или някъде го четох ЕЕПРОМ емулиране. Въпреки че навсякъде не го препоръчват. Има го в един линкерски скрипт но за LPC2106.
_________________ Вниманиене съмвишист....ИЙ.
|
| Съб Сеп 03, 2011 6:03 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11265 Местоположение: Добрич
|
 Re: CBS setup
Това са съвсем основни неща дето е добре да се научат още преди да седнеш да работиш с GCC Значи компилаторът прави от сорс файл т.н. обектен файл. Подаваш му един сорс файл (само един) и той "компилира" като резултатът от компилацията е списък с обекти, дето се записват в обектния файл. Обектите могат да са някакви глобални променливи, може да са финкции (код). Но важното в случая е компилаторът изобщо, ама изобщо не се интересува дали тия обекти ще разполагат в ROM, RAM, в EXE-файл, DLL, BIN или някакъв друг файл. Може и никъде да не се разполагат, ако не се ползват.... Но това се решава на един малко по-късен етап, наречен линкване... Само да кажа, че компилаторът задава секция за всеки обект. Има няколко секции по подразбиране - за код (.text), за read only (.rodata, .init, .fini) данни и за read-write данни с инициализация (.data) и без инициализация (.bss). Секциите по подразбиране леко варират според версията на компилатора, езика Ц и Ц++ и т.н. И другото което зависи от компилатора е дали всички обекти от даден тип да са в една секция, или за всеки да се прави отделна секция (виж -ffunction-sections -fdata-sections). Това последното е важно, понеже оптимизацията е на ниво секция. Ако нищо от дадена секция не се ползва се разкарва цялата секция, иначе остава цялата. Така че ако искаш неизползваните променливи и функции да се оптимизират, по-добре всеки обект да си е в отделна секция... Сега линкерът.... На него му даваш списък с обектни файлове (и/или библиотеки) и му казваш какво да ти скалъпи от тях. За целта му се задават и някакви правила (обикновено линкер скрипт), чрез които му казваш "вземи тия обекти от тия файлове (входни секции) и ги сложи еди къде си (изходни секции)". Едва при попълването на изходните секции се получават "някакви" адреси. Казвам някакви щото зависи какво точно се скалъпва, иначе адресите са малко виртуални. Секцията може да се разполага на един адрес в bin-файла (или каквото там се генерира) а пък после при зареждане в таргета да е на друг адрес. Тъй... да се върнем на проблема.. Значиш имаш някакви FRAM, EPROM или каквито там памети искаш.... Тия памети са ти на опреден адрес и с определн размер и най-добре в линкерския скрипт да ги опишеш: После си описваш секциите: Забележи първата изходно секция my_text_section - в нея казвам да се сложат всички обекти от всички файлове (*) и входна секция ExceptionVectors. После цялата изходна секция се разполага в rom дето по-горе го дефинирахме... За подробности в синтаксиса може да прочетеш ръководството на LD  Te по тоя начин може да си правиш всякакви секции и да си ги разполагаш където и както си искаш... Остана само как в сорса да кажеш коя променлива/функция в коя секция да отиде (ако не искаш да е в секция по подразбиране): В случая масивчето ще отиде в моята секцийка ExceptionVectors, а тя пък ще отиде в началото на rom-а ... Така може от група сорсове да генерираш един, два или повече изходни файлове с каквото съдържание искаш. Имаш контрол върху всичко, ограничен си само от фантазията и знанията си  Ех, има и малко подводни камъни... но то къде ли ги няма 
|
| Съб Сеп 03, 2011 7:15 pm |
|
|
|
Страница 1 от 1
|
[ 11 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 1 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|