I need to map peripheral memory addresses to access the hardware in linux. To make things a bit more generic (aka complicated...) I created a following function:
template<typename Tp>
static Tp* getPeripheralPtr(unsigned address)
{
static constexpr auto deleter = [](Tp* ptr){ munmap(ptr, sizeof(Tp); };
static std::unique_ptr<Tp> ptr(nullptr, deleter);
if (!ptr)
{
/* mmap logic */
ptr.reset(reinterpret_cast<Tp*>(virtaddr));
}
return ptr.get();
}
where Tp is a structure representing the registers.
This worked pretty well, although later in the process, I realized I can have multiple controllers, for example PWM0, PWM1 with the same register layout, just with an offset. So I rewrote the function:
template<typename Tp, size_t nControllers = 1, size_t offset = 0>
static Tp* getPeripheralPtr(unsigned address, int idx = 0)
{
static Storage<Tp, nControllers> storage;
if (!storage.ptr[idx])
{
/* mmap magic */
}
return storage.ptr[idx].get();
}
I needed a way to initialize N std::unique_ptr instances so I created a helper Storage class:
template<typename Tp, std::size_t N>
class Storage
{
static constexpr auto deleter = [](Tp* ptr) { munmap(ptr, sizeof(Tp)); };
template<size_t ... indices>
explicit Storage(std::index_sequence<indices...> const&)
: ptr{{((void)indices, ptr_type(nullptr, deleter))...}}
{
}
public:
using ptr_type = std::unique_ptr<Tp, decltype(deleter)>;
ptr_type ptr[N];
Storage() : Storage(std::make_index_sequence<N>{}) {}
};
But it gives me an error when nControllers > 1 about no matching constructor for initialization of 'Storage<int, 2>::ptr_type'. Can you please point me in a right direction?
With this:
ptr{{((void)indices, ptr_type(nullptr, deleter))...}}
You need a type within an initializer_list
constructor. And obviously, you couldn't use just a raw C-array. If you remove one braces level you could use it with raw C-array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.