CART Driver Implementation

Verified

Added on  2019/09/16

|14
|2981
|845
Homework Assignment
AI Summary
This document presents the C code for a CART driver, which manages file operations on a simulated storage system. The code includes functions for powering on and off the system, opening, closing, reading, writing, and seeking within files. It also handles low-level interactions with the CART hardware through opcodes and register manipulation. The driver uses a structure to maintain file metadata and manages file access using file descriptors. The implementation includes error handling and logging for debugging purposes. This code is a practical example of how to interface with hardware and manage file systems in an embedded environment.
Document Page
/////////////////////////////////////////////////////////////////////////
///////
//
// File : cart_driver.c
// Description : This is the implementation of the standardized IO functions
// for used to access the CART storage system.
//
// Author : [Ishaank Chaudhary]
// Last Modified : [10/24/2016]
//
// Includes
#include <stdlib.h>
// Project Includes
#include "cart_driver.h"
#include "cart_controller.h"
#include "cmpsc311_log.h"
#include "cmpsc311_util.h"
//
// Implementation
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_poweron
// Description : Startup up the CART interface, initialize filesystem
//
// Inputs : none
// Outputs : 0 if successful, -1 if failure
struct { //structure
char file_name[CART_MAX_PATH_LENGTH];
int file_status;//file status
int file_desc;//file descriptor
int length;
int pos;
int counter;
}s[CART_MAX_TOTAL_FILES];
static uint64_t oregstate,regstate, ky1,ky2,rt1,ct1,fm1;
static int files;
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_poweron
// Description : turn on the CART interface,
//
// Inputs : none
// Outputs : 0 if successful, -1 if failure
int32_t cart_poweron(void) {
CartXferRegister regstate;
if ((regstate = create_cart_opcode(CART_OP_INITMS, 0, 0, 0, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on power on.");
return(-1);
}
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power on");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power on");
return(-1);
}
for(int i = 0; i < CART_MAX_CARTRIDGES; i++){
if ((regstate= create_cart_opcode(CART_OP_LDCART, 0, 0, i, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on power on");
return(-1);
}
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
on");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
on");
return(-1);
}
if ((regstate= create_cart_opcode(CART_OP_BZERO, 0, 0, 0, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on power on");
return(-1);
}
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
Document Page
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
on" );
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
on");
return(-1);
}
}
for(int j=0; j<CART_MAX_TOTAL_FILES;j++)
{
strncpy(s[j].file_name,"\0",CART_MAX_PATH_LENGTH);
s[j].pos=0;
s[j].length=0;
s[j].file_status =0;
}
// Return successfully
return(0);
}
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_poweroff
// Description : Shut down the CART interface, close all files
//
// Inputs : none
// Outputs : 0 if successful, -1 if failure
int32_t cart_poweroff(void) {
for(int i =0;i<CART_MAX_CARTRIDGES; i++)
{
s[i].file_status =0;
}
if ((regstate= create_cart_opcode(CART_OP_POWOFF, 0, 0, 0, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on power off.");
return(-1);
}
Document Page
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
off");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on power
off");
return(-1);
}
// Return successfully
return(0);
}
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_open
// Description : This function opens the file and returns a file handle
//
// Inputs : path - filename of the file to open
// Outputs : file handle if successful, -1 if failure
int16_t cart_open(char *path)
{
int i;
for(i =0; i<files; i++)
{
if(strncmp(s[i].file_name,path,CART_MAX_PATH_LENGTH))
{
if(s[i].file_status ==0)
{
logMessage(LOG_ERROR_LEVEL, "FILE open failed: fail
on cart open.");
return -1;
}
else
{
s[i].file_status = 1;
s[i].pos =0;
return (i);
}
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
}
}
if(files < CART_MAX_TOTAL_FILES)
{
strncpy(s[files].file_name,path,CART_MAX_PATH_LENGTH);
s[files].pos = 0;
s[files].length = 0;
s[files].counter = 0;
s[files].file_status = 1;
files++;
}
else
{
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on cart
open.");
return -1;
}
return (--files);
}
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_close
// Description : This function closes the file
//
// Inputs : fd - the file descriptor
// Outputs : 0 if successful, -1 if failure
int16_t cart_close(int16_t fd)
{
if(fd >= 0 || fd <= CART_MAX_TOTAL_FILES)
{
if(s[fd].file_status == 0)
{
logMessage(LOG_ERROR_LEVEL, "FILE close failed: file
not open");
Document Page
return(-1);
}
else
{
s[fd].file_status =0;
}
}
else
{
logMessage(LOG_ERROR_LEVEL, "FILE close failed:
invalid file descriptor");
return(-1);
}
// Return successfully
return (0);
}
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_read
// Description : Reads "count" bytes from the file handle "fh" into the
// buffer "buf"
//
// Inputs : fd - filename of the file to read from
// buf - pointer to buffer to read into
// count - number of bytes to read
// Outputs : bytes read if successful, -1 if failure
int32_t cart_read(int16_t fd, void *buf, int32_t count)
{
int frame_number,cart_number;
char ar[count];
char tbuf[count];
uint64_t frame_position,total_read;
if(fd < CART_MAX_TOTAL_FILES && fd >=0)
Document Page
{
if(s[fd].length <= count + s[fd].pos)
{
if(s[fd].file_status ==1)
{
count = s[fd].length - s[fd].pos;
}
cart_number = (s[fd].pos / (CART_CARTRIDGE_SIZE *
CART_FRAME_SIZE));
frame_number = (s[fd].pos / CART_FRAME_SIZE);
frame_position = (s[fd].pos % CART_FRAME_SIZE);
//load cart
if ((regstate= create_cart_opcode(CART_OP_LDCART, 0, 0,
cart_number, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on
LDCART");
return(-1);
}
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
LDCART");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
LDCART");
return(-1);
}
while(count!=0)
{
if ((regstate= create_cart_opcode(CART_OP_RDFRME,0, 0, 0,
frame_number)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed:
fail on read");
return(-1);
}
oregstate = cart_io_bus(regstate, ar);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1,
&fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed:
failed: fail on read.");
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed:
failed: fail on read");
return(-1);
}
if((CART_FRAME_SIZE - frame_position) >= count)
{
memcpy(&ar[total_read], &tbuf[frame_position],
count);
total_read = total_read + count;
count = 0;
}
else
{
memcpy(&ar[total_read], &tbuf[frame_position],
(CART_FRAME_SIZE-frame_position));
total_read = total_read + (CART_FRAME_SIZE-
frame_position);
count = count - (CART_FRAME_SIZE-frame_position);
}
if (frame_number == (CART_CARTRIDGE_SIZE -1))
{
if(cart_number == (CART_MAX_CARTRIDGES -1))
{
logMessage(LOG_ERROR_LEVEL, "CART driver
failed: failed: fail on read");
return(-1);
}
else
{
frame_position =0;
frame_number =0;
cart_number++;
if ((regstate=
create_cart_opcode(CART_OP_LDCART,0, 0, cart_number, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver
failed: fail on read");
return(-1);
}
Document Page
oregstate = cart_io_bus(regstate, ar);
if (extract_cart_regstate(oregstate, &ky1, &ky2,
&rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver
failed: failed: fail on read.");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver
failed: failed: fail on read");
return(-1);
}
}
}
else
{
frame_position = 0;
frame_number++;
}
}
s[fd].pos = total_read + s[fd].pos;
memcpy(buf,ar,total_read);
return (total_read); // Return successfully
}
}
return -1; //return unsuccessful
}
/////////////////////////////////////////////////////////////////////////
///////
//
Document Page
// Function : cart_write
// Description : Writes "count" bytes to the file handle "fh" from the
// buffer "buf"
//
// Inputs : fd - filename of the file to write to
// buf - pointer to buffer to write from
// count - number of bytes to write
// Outputs : bytes written if successful, -1 if failure
int32_t cart_write(int16_t fd, void *buf, int32_t count)
{
int i=0,tot_write = 0;
int frame_number,cart_number,write_number;
char wr[CART_FRAME_SIZE];
char tbuf[count];
if(0<= fd && fd < CART_MAX_TOTAL_FILES)
{
cart_number = s[i].pos /
(CART_FRAME_SIZE*CART_CARTRIDGE_SIZE);
frame_number = s[i].pos / CART_FRAME_SIZE;
write_number= s[i].pos%CART_FRAME_SIZE;
//load cart
if ((regstate= create_cart_opcode(CART_OP_LDCART, 0, 0,
cart_number, 0)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on
LDCART.");
return(-1);
}
oregstate = cart_io_bus(regstate, NULL);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
LDCART.");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
LDCART.");
return(-1);
}
memcpy(tbuf,(char*)buf,count);
while(count !=0)
{
if(count < CART_FRAME_SIZE || write_number != 0)
{
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
if ((regstate= create_cart_opcode(CART_OP_RDFRME,0, 0, 0,
frame_number)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on
write.");
return(-1);
}
oregstate = cart_io_bus(regstate, wr);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1,
&fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed:
fail on write");
return(-1);
}
if (rt1){
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed:
fail on write.");
return(-1);
}
}
if(count <= (CART_FRAME_SIZE-write_number)) {
memcpy(&wr[write_number],&tbuf[tot_write], count);
tot_write = tot_write + count;
count = 0;
}
else
{
memcpy(&wr[write_number],&tbuf[tot_write],
(CART_FRAME_SIZE-write_number));
tot_write = tot_write + (CART_FRAME_SIZE-write_number);
count = count - (CART_FRAME_SIZE-write_number);
}
if ((regstate= create_cart_opcode(CART_OP_WRFRME,0, 0, 0,
frame_number)) == -1) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: fail on write.");
return(-1);
}
oregstate = cart_io_bus(regstate, wr);
if (extract_cart_regstate(oregstate, &ky1, &ky2, &rt1, &ct1, &fm1)) {
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
write.");
return(-1);
}
if (rt1){
Document Page
logMessage(LOG_ERROR_LEVEL, "CART driver failed: failed: fail on
write.");
return(-1);
}
if (frame_number < CART_CARTRIDGE_SIZE)
{
frame_number++;
write_number = 0;
}
}
s[i].length = s[i].length + tot_write;
// Return successfully
return (tot_write);
}
return -1;//retrun failure
}
/////////////////////////////////////////////////////////////////////////
///////
//
// Function : cart_seek
// Description : Seek to specific point in the file
//
// Inputs : fd - filename of the file to write to
// loc - offfset of file in relation to beginning of file
// Outputs : 0 if successful, -1 if failure
int32_t cart_seek(int16_t fd, uint32_t loc)
{
if(0 <= fd && fd < CART_MAX_TOTAL_FILES)
{
if(s[fd].length > loc)
{
if(s[fd].file_status == 1)
{
if(s[fd].file_desc == fd)
{
s[loc].pos=loc;
return 0; // Return successfully
}
}
chevron_up_icon
1 out of 14
circle_padding
hide_on_mobile
zoom_out_icon
[object Object]