LusoRobótica - Robótica em Português
Software => C/C++ => Tópico iniciado por: LuísR.A. em 08 de Abril de 2015, 19:01
-
Ora boas tardes a todos.
Tou aqui com um problema par ao qual não encontro solução e estava com esperança que me ajudassem.
Estou a fazer uma biblioteca em C, bem, mais umas funções para ser facil use um modulo UART com DMA.
Tenho tudo num library.c e library.h.
Depois no main.c tenho uma variavel local, char a[100] que, apesar de o endereço começar bem atrás, acaba por ir para cima das variáveis globais dentro de library.c
Alguem me pode dizer o que estou a fazer mal? Possivelmente o compilador está a gerir mal a tabela "a" por ser tão grande?
-
Ora boas tardes a todos.
Tou aqui com um problema par ao qual não encontro solução e estava com esperança que me ajudassem.
Estou a fazer uma biblioteca em C, bem, mais umas funções para ser facil use um modulo UART com DMA.
Tenho tudo num library.c e library.h.
Depois no main.c tenho uma variavel local, char a[100] que, apesar de o endereço começar bem atrás, acaba por ir para cima das variáveis globais dentro de library.c
Alguem me pode dizer o que estou a fazer mal? Possivelmente o compilador está a gerir mal a tabela "a" por ser tão grande?
So' estou a ver isso acontecer se a RAM não for suficiente.
-
256KB :/ Por isso duvido
Até mesmo pelo que está no código mas vou ver melhor
-
Nope. O .map diz que sobra 254816 bytes e sei que as locais não ultrapassam isso :/
So' estou a ver isso acontecer se a RAM não for suficiente.
Afinal era mesmo isso. Lembrei-me que se calhar há um limite na stack e havia mesmo! Tava só para 512 bytes :p
Alterei e parece estar bem. Obrigado, não me teria lembrado que podia ser falta de RAM!
Com isto já levei cá tanta porrada desse tipo de cenas.
-
Posta o código..
Mas se isso é um buffer circular devia ser uma potência de 2, os bounds check são optimizados para AND's e pouco mais.
-
Era na verdade só uma string C para testes.
Isso depois passava para um buffer (ainda não circular mas têm 1024 bytes) e depois enviava. Mas vá foi mesmo estupidês minha ;D
-
Qual é a solução então?
-
O problema era o tamanho da stack definido pelo compilador. Estava definido para um máximo de 512 bytes.
Aumentei e deu tudo bem :D
-
Isso das stacks é coisa que me continua a fazer extrema confusão..
Se cresce do topo da ram para baixo, porque é que é preciso definir um tamanho, e melhor, se é "pequena" dá barraca.
-
Cuidado com os push's e os pop's da stack ahahah ;D
-
Define-se tamanho para isso não ir por ai abaixo e começar a editar registos ou funções na RAM (nem me lembro se isso é acima ou abaixo ;D
-
Define-se o tamanho para o compilador saber até onde pode ir o segmento de dados (ou outros).
-
Achei foi bué estranho ter tipo 512 bytes por default tendo 256KB.
Oh well, é da forma que aprendia mais cedo :D
Estranho foi uma cena... As variáveis globais não deviam tar fora da stack? Eram variáveis declaradas fora de qualquer função num ficheiro à parte.
-
Achei foi bué estranho ter tipo 512 bytes por default tendo 256KB.
Oh well, é da forma que aprendia mais cedo :D
Estranho foi uma cena... As variáveis globais não deviam tar fora da stack? Eram variáveis declaradas fora de qualquer função num ficheiro à parte.
Boas,
256KB de RAM ? Qual é o MCU ?
Depois no main.c tenho uma variavel local, char a[100] que, apesar de o endereço começar bem atrás, acaba por ir para cima das variáveis globais dentro de library.c
Suponho que quando dizes "main.c" seja fora da função "main", pelo que de CERTEZA que
é uma val global (ainda que _normalmente_ somente visível dentro de main.c), logo não
tem que ser alocado no stack ... deve haver ai qualquer outra confusão.
Posta o source ... promete-mos não copiar nada ;)
Abraços,
PA
-
Isso das stacks é coisa que me continua a fazer extrema confusão..
Se cresce do topo da ram para baixo, porque é que é preciso definir um tamanho, e melhor, se é "pequena" dá barraca.
Boas,
o "stack" e o "heap" têm que ser quantificados pelo simples facto de que compilador (e/ou
assemblador) necessita dessa informação par evitar corromper os mesmos com os outros
segmentos.
Geralmente este controlo é feito durante a fase de "compile time", mas existem compiladores
que podem gerar código de forma a que esse mesmo controlo seja feita durante a execução
do programa. No que toca ao heap isso é SEMPRE feito em run time.
Abraços,
PA
-
Posta o source ... promete-mos não copiar nada ;)
Fala por ti, eu não prometo nada, lol.
-
Posta o source ... promete-mos não copiar nada ;)
Abraços,
PA
Não pode ser infelizmente :p
Tive a ver o .map e parece-me que aquilo saiu foi fora da stack mesmo.
-
Só assim por acaso, acham que um interrupt de 2,8uS é demasiado grande? :p
Sei que é relativo à frequência com que é chamado o quão aceitavel é o tempo mas queria ter uma ideia. Neste caso duvido que aconteça mais de 2 vezes a cada 5ms.
Tive a ver o disassemble e parece ser o máximo de tempo que decorre.
Nos testes tenho 8 iguais a acontecer e dá na boa mas tou preocupado num código mais real. Mas não me apetece ir alterar 8 handlers se não for preciso. 8 é o extremo, já viram o que é
-
Sei que é relativo à frequência com que é chamado o quão aceitavel é o tempo (...)
Não, não é. Nada a ver. Depende do contexto, da aplicação. Lembro-me de uma aplicação em que tinha interrupções a ocupar mais de 95% do CPU.
-
Deixa-me cá meter colherada 8)
Se estás a passar um array e o stack rebenta, não o estás a passar como parâmetro de uma função?
Nesse caso cria uma cópia em stack, e daí o problema.
Também depende da linguagem que estás a usar, mas não podes passar só um pointer/apontador?
-
O C passa arrays para funções sempre como apontadores, nunca faz cópia. ;)
-
Ao se escrever um código, principalmente em assemby, deve-se referir o inicio de onde a memória está livre, a partir desse ponto podem-se criar variáveis, constantes, etc... num local apropriado desta memória livre, em C essa preocupação passa um pouco ao lado, daí se reservar espaços através de stacks.
Fazer debug ajuda um pouco, ou até mesmo uma simulação no programa antes de se passar para o micro, assim é possível ver se alguma variável está a passar do limite.
Em último caso pode-se criar uma interface série com o PC para receber as informações de cada instrução e monitorizar a sua execução. Mais fácil é mudar o estado de um bit de uma porta caso se suspeite de alguma operação.
-
Isso do debug é uma das razões porque gosto bué das launchpads em vez do arduino. Há bué boards que vêm com um debuger pelas vantagens que tra?. Acho mesmo que agora o arduino é dos poucos que foge à regra. Mas penso que o programador/debugger dos atmega é dos mais baratos.