Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <metal/sys.h>
- #include <metal/device.h>
- #include <metal/io.h>
- #include <metal/alloc.h>
- #define BUS_NAME "generic"
- #define SHM_DEV_NAME "3e800000.shm"
- #define SHM_BASE_ADDR 0x3E800000
- /* Each I/O region can contain multiple pages.
- * In baremetal system, the memory mapping is flat, there is no
- * virtual memory.
- * We can assume there is only one page in the whole baremetal system.
- */
- #define DEFAULT_PAGE_SHIFT (-1UL)
- #define DEFAULT_PAGE_MASK (-1UL)
- // This stuff will eventually live in its own header
- typedef struct {
- uint8_t status;
- uint8_t value;
- } msgblock;
- const int MSGBUF_LEN = 10;
- const int LED_GPIO_BASE = 0x80000000;
- int main(int argc, char* argv[])
- {
- uint32_t* leds = (uint32_t*)LED_GPIO_BASE;
- *leds = 0x55;
- struct metal_init_params metal_param = METAL_INIT_DEFAULTS;
- metal_init(&metal_param);
- // Shared memory device
- struct metal_device dev = {
- .name = SHM_DEV_NAME,
- .bus = NULL,
- .num_regions = 1,
- .regions = {
- {
- .virt = (void *)SHM_BASE_ADDR,
- .physmap = (metal_phys_addr_t*)SHM_BASE_ADDR,
- .size = 0x800000,
- .page_shift = DEFAULT_PAGE_SHIFT,
- .page_mask = DEFAULT_PAGE_MASK,
- .mem_flags = NORM_SHARED_NCACHE |
- PRIV_RW_USER_RW,
- .ops = {NULL},
- }
- },
- .node = {NULL},
- .irq_num = 0,
- .irq_info = NULL,
- };
- // This isn't needed in the new version
- metal_bus_register(&metal_generic_bus);
- int err = metal_register_generic_device(&dev);
- if(err){
- print("Failed to register device\n");
- }
- struct metal_device* shm_dev;
- err = metal_device_open(BUS_NAME, SHM_DEV_NAME, &shm_dev);
- if(err){
- print("Failed to open device\n");
- }
- // Now get the I/O region
- struct metal_io_region *io = NULL;
- io = metal_device_io_region(shm_dev, 0);
- if(!io){
- print("Failed to get I/O region\n");
- }
- int msgcount = 0;
- union {
- msgblock msg;
- uint16_t raw;
- } message;
- while(1){
- Xil_DCacheInvalidateRange((uint32_t)SHM_BASE_ADDR, 0x100);
- // Get a message from the queue
- message.raw = metal_io_read16(io, msgcount*sizeof(msgblock));
- // If the message is valid, set the LEDs accordingly
- // Otherwise, just keep spinning
- if(message.msg.status == 0x01){
- *leds = message.msg.value;
- metal_io_write16(io, msgcount*sizeof(msgblock), 0); // Clear this message
- msgcount = (msgcount + 1) % MSGBUF_LEN;
- }
- sleep(1);
- }
- metal_device_close(shm_dev);
- metal_finish();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement