Estou tentando descobrir como usar a função printf para imprimir na porta serial.
Minha configuração atual é o código gerado pelo STM32CubeMX e o SystemWorkbench32 com a placa de descoberta STM32F407 .
Vejo em stdio.h que o protótipo printf é definido como:
int _EXFUN(printf, (const char *__restrict, ...)
_ATTRIBUTE ((__format__ (__printf__, 1, 2))));
O que isso significa? Onde está o local exato desta definição de função? Qual seria o ponto geral de descobrir como usar esse tipo de função para produzir?
microcontroller
c
stm32
stm32f4
stm32cubemx
user505160
fonte
fonte
_write()
função é o que eu fiz. Detalhes na minha resposta abaixo.Respostas:
Eu obtive o primeiro método desta página trabalhando no meu STM32F072.
http://www.openstm32.org/forumthread1055
Como afirmado lá,
Usei o STM32CubeMX para configurar o USART1 (
huart1
) como uma porta serial. Como eu só queriaprintf()
, só precisava preencher a_write()
função, que fiz da seguinte maneira. Isso é convencionalmente contido emsyscalls.c
.fonte
_EXFUN é uma macro, provavelmente contendo algumas diretivas interessantes que informam ao compilador que ele deve verificar se a string de formato é compatível com printf e garantir que os argumentos para printf correspondam à string de formato.
Para aprender a usar o printf, sugiro a página de manual e um pouco mais de pesquisa. Escreva alguns programas C simples que usem printf e execute-os no seu computador antes de tentar fazer a transição para o micro.
A questão interessante será "para onde vai o texto impresso?". Em um sistema unix, ele vai para a "saída padrão", mas um microcontrolador não tem tal coisa. As bibliotecas de depuração do CMSIS podem enviar texto printf para a porta de depuração semi-hospedada do braço, ou seja, na sua sessão gdb ou openocd, mas não tenho idéia do que o SystemWorkbench32 fará.
Se você não estiver trabalhando em um depurador, pode fazer mais sentido usar o sprintf para formatar as sequências que você deseja imprimir e depois enviá-las por uma porta serial ou para qualquer monitor que possa estar conectado.
Cuidado: printf e seu código relacionado são muito grandes. Provavelmente isso não importa muito em um 32F407, mas é um problema real em dispositivos com pouco flash.
fonte
__cdecl
para evitar erros. Pelo menos em newlib / cygwin, _EXFUN é usado apenas para definir__cdecl
.A resposta de @ AdamHaun é tudo que você precisa,
sprintf()
é fácil criar uma string e enviá-la. Mas se você realmente quer umaprintf()
função própria, então Funções de Argumento Variável (va_list) é o caminho.Com
va_list
uma função de impressão personalizada, é semelhante ao seguinte:Exemplo de uso:
Observe que, embora esta solução ofereça uma função conveniente para uso, mas é mais lenta que o envio de dados brutos ou o uso uniforme
sprintf()
. Com altos datarates, acho que não será suficiente.Outra opção, e provavelmente a melhor opção, é usar o depurador SW-ST-Link junto com o utilitário ST-Link. E use Printf via visualizador SWO , aqui está o manual do ST-Link Utility , parte relevante começa na página 31.
fonte
printf () é (geralmente) parte da biblioteca padrão C. Se sua versão da biblioteca vier com código-fonte, você poderá encontrar uma implementação lá.
Provavelmente seria mais fácil usar sprintf () para gerar uma string e, em seguida, use outra função para enviar a string pela porta serial. Dessa forma, toda a formatação difícil é feita para você e você não precisa invadir a biblioteca padrão.
fonte
Para aqueles que lutam, adicione o seguinte a syscalls.c:
Conecte-se à sua porta COM via massa e você deve ser bom.
fonte
Se você deseja uma abordagem diferente e não deseja sobrescrever funções ou declarar a sua, pode simplesmente usar
snprintf
para arquivar o mesmo objetivo. Mas não é tão elegante.fonte