Адреса устройств (на примере контроллера UART) описаны в addrs.h
Код
#define UART_BASE (0xF400)
В uart.h описана структура регистров контроллера:
Код
#ifndef _UART_H_
#define _UART_H_
#include <stdint.h>
#include "addrs.h"
/// Структура регистра состояния контроллера UART.
struct uart_status_s
{
uint8_t txrdy : 1; ///< Буфер передачи пуст.
uint8_t rxrdy : 1; ///< Буфер приёма заполнен.
uint8_t parity_err : 1; ///< Ошибка чётности.
uint8_t overflow : 1; ///< Переполнение буфера приёма.
uint8_t framing_err : 1; ///< Ошибка кадра.
uint8_t : 3; ///< Резерв.
};
/// Объединение для работы с контроллером UART.
union uart_status
{
struct uart_status_s bits; ///< Побитовое обращение.
uint8_t all; ///< Обращение к регистру целиком.
};
/// Структура контроллера UART.
struct uart_reg_s
{
uint8_t txd; ///< Передающий регистр.
uint8_t rsvd0[3]; ///< Резерв.
uint8_t rxd; ///< Приёмный регистр.
uint8_t rsvd1[11]; ///< Резерв.
union uart_status status; ///< Регистр состояния.
};
extern volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
#endif /* _UART_H_ */
#define _UART_H_
#include <stdint.h>
#include "addrs.h"
/// Структура регистра состояния контроллера UART.
struct uart_status_s
{
uint8_t txrdy : 1; ///< Буфер передачи пуст.
uint8_t rxrdy : 1; ///< Буфер приёма заполнен.
uint8_t parity_err : 1; ///< Ошибка чётности.
uint8_t overflow : 1; ///< Переполнение буфера приёма.
uint8_t framing_err : 1; ///< Ошибка кадра.
uint8_t : 3; ///< Резерв.
};
/// Объединение для работы с контроллером UART.
union uart_status
{
struct uart_status_s bits; ///< Побитовое обращение.
uint8_t all; ///< Обращение к регистру целиком.
};
/// Структура контроллера UART.
struct uart_reg_s
{
uint8_t txd; ///< Передающий регистр.
uint8_t rsvd0[3]; ///< Резерв.
uint8_t rxd; ///< Приёмный регистр.
uint8_t rsvd1[11]; ///< Резерв.
union uart_status status; ///< Регистр состояния.
};
extern volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
#endif /* _UART_H_ */
В globals.c объявлено
Код
#include "addrs.h"
#include "uart.h"
...
volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
#include "uart.h"
...
volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
В дальнейшем в .c делаю #include "uart.h" и при обращении к регистрам контроллера пишу UART_REG.status.bits.txrdy или UART_REG.txd, что удобно, поскольку не приходится возиться с масками и вручную просчитывать адреса.
Использую Eclipse, при такой записи в uart.h он не видит структуру регистра и не выдаёт подсказок при написании .c файлов, при этом проект компилируется нормально. Если в uart.h написать extern volatile struct uart_reg_s UART_REG (без __xdata __at), то в Eclipse всё ОК, но ругается компилятор:
Цитата
.\src\globals.c:6: error 91: extern definition for 'UART_REG' mismatches with declaration.
Вопрос в том, как сделать, чтобы Eclipse выводил подсказку для структуры регистра и не ругался компилятор?
UPD: Вариант:
Код
#ifndef SDCC
extern volatile struct uart_reg_s UART_REG;
#else
extern volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
#endif
extern volatile struct uart_reg_s UART_REG;
#else
extern volatile __xdata __at (UART_BASE) struct uart_reg_s UART_REG;
#endif
мне кажется не очень элегантным.