📄 chantest.c
字号:
/* Test harness for channels layer * * Copyright (c) 1995, Advanced RISC Machines Limited. * All Rights Reserved. * * $Revision: 1.1 $ * $Author: rivimey $ * $Date: 1999/03/11 11:53:32 $ *//* * Simulates devices layer and buffers layer */#include <ctype.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifndef TRUE#define FALSE 0#define TRUE ( ! (FALSE))#endif#include "channels.h"#include "devclnt.h"#include "devdriv.h"#include "support.h"#include "serlock.h"/* simulation of buffers */#define DEF_BUFF_SIZE 256#define MAX_BUFF_SIZE 1024#define NUM_SMALL 3typedef unsigned char small_buff[DEF_BUFF_SIZE];static small_buff small[NUM_SMALL];static unsigned char large[MAX_BUFF_SIZE];static int small_used[NUM_SMALL];static int large_used;/* return the default and maximum buffer sizes supported */void Angel_BufferQuerySizes(unsigned int *default_size, unsigned int *max_size){ printf("BQS > Called - returning %u, %u\n", DEF_BUFF_SIZE, MAX_BUFF_SIZE); *default_size = DEF_BUFF_SIZE; *max_size = MAX_BUFF_SIZE;}/* allocate a buffer that is at least req_size bytes long *//* return NULL if unable to fulfil request */p_Buffer Angel_BufferAlloc(unsigned int req_size){ int i; printf("BALL> Called for %u byte buffer\n", req_size); if (req_size <= DEF_BUFF_SIZE) { for (i = 0; i < NUM_SMALL; ++i) { if (!small_used[i]) { printf("BALL> Returning small buffer %u [%08x]\n", i, (unsigned)small[i]); small_used[i] = TRUE; return small[i]; } } printf("BALL> All small buffers in use, returning NULL\n"); return NULL; } else if (req_size <= MAX_BUFF_SIZE) { if (large_used) { printf("BALL> Large buffer in use, returning NULL\n"); return NULL; } else { printf("BALL> Returning large buffer %08x\n", (unsigned)large); large_used = TRUE; return large; } } else { printf("BALL> Request too large, returning NULL\n"); return NULL; }}/* release a buffer back to the free pool */void Angel_BufferRelease(p_Buffer buffer){ int i; printf("BREL> Called with pointer %08x\n", (unsigned)buffer); for (i = 0; i < NUM_SMALL; ++i) { if (buffer == small[i] && small_used[i]) { printf("BREL> Freeing small buffer %d\n", i); small_used[i] = FALSE; return; } } if (buffer == large && large_used) { printf("BREL> Freeing large buffer\n"); large_used = FALSE; } else { printf("BREL> ERROR! attempt to release unused or non-existent!!\n"); exit(2); }}/* simulation of devices */static DevWrite_CB_Fn dev_write_cb_fn[DI_NUM_DEVICES];static struct{ p_Buffer buff; unsigned length; void *cb_data;}dev_write[DI_NUM_DEVICES];static int trigger_read[DI_NUM_DEVICES];static struct{ DevRead_CB_Fn callback; void *cb_data; DevGetBuff_Fn get_buff; void *getb_data; p_Buffer buff; unsigned length;}dev_read[DI_NUM_DEVICES];void Angel_Yield(void){ angel_DeviceYield();}void angel_DeviceYield(void){ static unsigned count = 0; int i; if (++count % 20 == 0) { printf("\nDYIE> Yielding:\n"); for (i = 0; i < DI_NUM_DEVICES; ++i) { if (dev_write_cb_fn[i] != NULL) { printf("DYIE> Doing dev_write callback %d\n", i); dev_write_cb_fn[i] (dev_write[i].buff, (void *)dev_write[i].length, DS_DONE, dev_write[i].cb_data); dev_write_cb_fn[i] = NULL; printf("DYIE> Done dev_write callback %d\n", i); } if (trigger_read[i] && dev_read[i].callback != NULL) { printf("DYIE> Doing dev_read callback %d\n", i); dev_read[i].callback(dev_read[i].buff, (void *)dev_read[i].length, DS_DONE, dev_read[i].cb_data); dev_read[i].buff = NULL; trigger_read[i] = NULL; printf("DYIE> Done dev_read callback %d\n", i); } } } else { printf("Y"); fflush(stdout); }}DevError angel_DeviceWrite(DeviceID devID, p_Buffer buff, unsigned length, DevWrite_CB_Fn callback, void *cb_data, DevChanID chanID){ unsigned i; if (dev_write_cb_fn[devID] != NULL) { printf("DWRI> BUSY!\n"); return DE_BUSY; } else { printf("DWRI> DevID %u, buff %08x, len %u, DevChanID %u\nDWRI> Cont: ", devID, (unsigned)buff, length, chanID); for (i = 0; i < length; ++i) printf("%02x ", buff[i]); for (i = 0; i < length; ++i) printf("%c", isprint(buff[i]) ? buff[i] : '.'); printf("\n"); dev_write_cb_fn[devID] = callback; dev_write[devID].buff = buff; dev_write[devID].length = length; dev_write[devID].cb_data = cb_data; return DE_OKAY; }}DevError angel_DeviceRegisterRead(DeviceID devID, DevRead_CB_Fn callback, void *cb_data, DevGetBuff_Fn get_buff, void *getb_data, DevChanID chanID){ printf("DREA> DevID %u, DevChanID %u\n", devID, chanID); if (dev_read[devID].callback != NULL) { printf("DREA> BUSY!\n"); return DE_BUSY; } else { dev_read[devID].callback = callback; dev_read[devID].cb_data = cb_data; dev_read[devID].get_buff = get_buff; dev_read[devID].getb_data = getb_data; dev_read[devID].buff = NULL; dev_read[devID].length = 0; return DE_OKAY; }}static void setup_read(DeviceID devid, ChannelID chanid, const char *data){ p_Buffer buff; if (dev_read[devid].buff != NULL) { printf("SURE> ERROR buffer already attached\n"); exit(4); } buff = angel_ChannelAllocBuffer(strlen(data) + 1); strcpy(buff, data); buff[-4] = chanid; buff[-3] = 0; buff[-2] = 0; buff[-1] = 0; dev_read[devid].buff = buff - 4; dev_read[devid].length = strlen(data) + 1 + 4; trigger_read[devid] = TRUE;}void LogError(char *format,...){ va_list args; va_start(args, format); printf("DERR> "); vprintf(format, args); va_end(args); exit(3);}void LogWarning(char *format,...){ va_list args; va_start(args, format); printf("DWAR> "); vprintf(format, args); va_end(args);}static int inSVC = FALSE;void Angel_EnterSVC(void){ if (inSVC) { printf("AESV> already in SVC!\n"); exit(5); } else { printf("AESV> Entering SVC\n"); inSVC = TRUE; }}void Angel_ExitToUSR(void){ if (!inSVC) { printf("AETU> not in SVC!\n"); exit(5); } else { printf("AETU> Exiting to USR\n"); inSVC = FALSE; }}/* channel return code descriptions */static char *ret_code[] ={ "okay", "ABANDONED", "DEV_ERROR", "BUSY"};/* callback for async read */static void test_read_cb(DeviceID devid, ChannelID chanid, p_Buffer buff, unsigned len, void *cb_data){ unsigned i; int *done = (int *)cb_data; printf("TRCB> devid %u, chanid %u, buffer %08x, length %u, data %s\n" "TRCB> = ", devid, chanid, (unsigned)buff, len, *done ? "T" : "F"); for (i = 0; i < len; ++i) printf("%02x ", buff[i]); for (i = 0; i < len; ++i) printf("%c", isprint(buff[i]) ? buff[i] : '.'); printf("\n"); angel_ChannelReleaseBuffer(buff); *done = TRUE;}/* callback for async send */static void test_send_cb(ChannelID chanid, void *cb_data){ int *done = (int *)cb_data; printf("TSCB> chanid %u, data %s\n", chanid, *done ? "T" : "F"); *done = TRUE;}void main(void){ p_Buffer my_buffer; unsigned default_size = 0; unsigned max_size = 0; const char my_name[] = "Michael Gray"; ChanError result; volatile int read_done = FALSE; volatile int read_all_done = FALSE; volatile int send_done = FALSE; p_Buffer read_buffer; unsigned read_length; printf("MAIN> Starting!!\n"); /* intialise */ angel_InitialiseChannels(); printf("MAIN> Intialised\n"); /* find out sizes */ angel_ChannelQuerySizes(&default_size, &max_size); printf("MAIN> default = %u, max = %u\n", default_size, max_size); /* get a default buffer */ my_buffer = angel_ChannelAllocBuffer(default_size); if (my_buffer == NULL) { printf("MAIN> ERROR got null buffer\n"); exit(1); } /* bung some stuff in and send it */ strcpy(my_buffer, my_name); result = angel_ChannelSend(DE_DEFAULT_ACTIVE, CI_TTDCC, my_buffer, strlen(my_name) + 1); printf("MAIN> Back from first send: %s\n", ret_code[result]); /* register a read on all devices */ result = angel_ChannelReadAll(CI_HBOOT, test_read_cb, (void *)(&read_all_done)); printf("MAIN> Registered read-all callback\n"); /* register a read */ result = angel_ChannelReadAsync(DE_DEFAULT_ACTIVE, CI_HUDBG, test_read_cb, (void *)(&read_done)); printf("MAIN> Registered read callback\n"); setup_read(DI_SERIAL, CI_HUDBG, "Inbound on HUDBG"); setup_read(DI_SER_PAR, CI_HBOOT, "Inbound BOOT message!!"); while (!read_done && !read_all_done) Angel_Yield(); read_all_done = FALSE; setup_read(DI_SERIAL, CI_HBOOT, "Inbound BOOT message two, diff dev!!"); while (!read_all_done) Angel_Yield(); read_done = FALSE; setup_read(DI_SERIAL, CI_HUDBG, "Inbound two on HUDBG"); while (!read_done) Angel_Yield(); setup_read(DI_SERIAL, CI_HADP, "HADP for blocking read"); result = angel_ChannelRead(DE_DEFAULT_ACTIVE, CI_HADP, &read_buffer, &read_length); printf("MAIN> Blocking read done, len %u, data >%s<\n", read_length, read_buffer); angel_ChannelReleaseBuffer(read_buffer); /* get a large buffer */ my_buffer = angel_ChannelAllocBuffer(max_size); if (my_buffer == NULL) { printf("MAIN> ERROR got null buffer\n"); exit(1); } /* bung some stuff in and send it */ strcpy(my_buffer, my_name); strcat(my_buffer, "blether blather"); result = angel_ChannelSendAsync(DE_DEFAULT_ACTIVE, CI_CLIB, my_buffer, strlen(my_name) * 2 + 1, test_send_cb, (void *)(&send_done)); printf("MAIN> Back from async send: %s\n", ret_code[result]); /* get a default buffer */ my_buffer = angel_ChannelAllocBuffer(default_size); if (my_buffer == NULL) { printf("MAIN> ERROR got null buffer\n"); exit(1); } /* bung some stuff in and send it */ strcpy(my_buffer, my_name); strcat(my_buffer, my_name); result = angel_ChannelSend(DE_DEFAULT_ACTIVE, CI_TTDCC, my_buffer, strlen(my_name) * 2 + 1); printf("MAIN> Back from second send: %s\n", ret_code[result]); while (!send_done) Angel_Yield(); printf("MAIN> DONE!!!\n"); exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -