{"id":640,"date":"2015-06-10T06:26:40","date_gmt":"2015-06-10T06:26:40","guid":{"rendered":"https:\/\/ibex.tech\/c\/?p=640"},"modified":"2022-02-17T10:13:11","modified_gmt":"2022-02-17T10:13:11","slug":"rolling-memory-buffer","status":"publish","type":"post","link":"https:\/\/ibex.tech\/c\/c\/memory\/rolling-memory-buffer","title":{"rendered":"Rolling memory buffer"},"content":{"rendered":"<h4>\nExample Of Non Irq Function Fills Buffers and IRQ Function Empties Buffers<br \/>\n<\/h4>\n<p>\nThis implemenation is based on the function sending the data being an irq which sends bits of the data irq&nbsp;calls and the function filling the data buffers being non irq and ensuring the operation is irq safe.\n<\/p>\n<pre>\r\n<code>\r\n#define FILE_DATA_NUM_OF_BUFFERS\t\t4\r\n#define\tFILE_DATA_BUFFER_LENGTH\t\t\t512\r\n\r\nint file_data_next_buffer_to_fill = 0;\r\nvolatile int file_data_sending_buffer = 0;\r\nvolatile int file_data_sending_buffer_byte = 0;\r\nBYTE file_data_buffers[FILE_DATA_NUM_OF_BUFFERS][FILE_DATA_BUFFER_LENGTH];\r\n \r\n\r\n\t\/\/----- START THE SENDING PROCESS -----\r\n\tfile_data_next_buffer_to_fill = 0;\r\n\tfile_data_sending_buffer = FILE_DATA_NUM_OF_BUFFERS - 1;\r\n\tfile_data_sending_buffer_byte = FILE_DATA_BUFFER_LENGTH;\r\n\t\r\n\t\r\n\t\/\/----- THE DATA COLLECTION FUNCTION FILLING THE BUFFER -----\r\n\t\/\/It wants to fill the next_buffer_to_fill with new data and on to ultimately meet file_data_sending_buffer\r\n\tDISABLE_INT;\r\n\tif (file_data_next_buffer_to_fill != file_data_sending_buffer)\r\n\t{\r\n\t\t\/\/----- THERE IS AT LEAST 1 BUFFER WAITING TO BE FILLED -----\r\n\t\tp_buffer = &amp;file_data_buffers[file_data_next_buffer_to_fill][0];\r\n\t\t\r\n\t\t\r\n\t\tfile_data_next_buffer_to_fill++;\r\n\t\tif (file_data_next_buffer_to_fill &gt;= FILE_DATA_NUM_OF_BUFFERS)\r\n\t\t\tfile_data_next_buffer_to_fill = 0;\r\n\t}\r\n\tENABLE_INT;\r\n\t\r\n\t\r\n\t\/\/----- THE IRQ SENDING THE DATA -----\r\n\t\/\/It wants to move the sending_buffer on to ultimately meet the next_buffer_to_fill\r\n\twhile (#)\r\n\t{\r\n\t\tif (file_data_sending_buffer_byte &gt;= FILE_DATA_BUFFER_LENGTH)\r\n\t\t{\r\n\t\t\tfile_data_sending_buffer_byte = 0;\r\n\t\t\tfile_data_sending_buffer++;\r\n\t\t\tif (file_data_sending_buffer &gt;= FILE_DATA_NUM_OF_BUFFERS)\r\n\t\t\t\tfile_data_sending_buffer = 0;\r\n\r\n\t\t\tif(file_data_sending_buffer == file_data_next_buffer_to_fill)\r\n\t\t\t{\r\n\t\t\t\t\/\/Disable the irq as there&#39;s no data available to send yet\r\n\t\t\t\t\t\/\/...\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t\/\/Get next block of bytes and send them\r\n\t\tp_buffer = &amp;file_data_buffers[file_data_sending_buffer][file_data_sending_buffer_byte];\r\n\t\t\t\/\/...\r\n\t\tfile_data_sending_buffer_byte += 32;\t\t\/\/&lt;&lt;&lt;How ever many bytes just got sent\r\n\t}\r\n<\/code><\/pre>\n<h4>\nExample With Buffer Overwrite If Data Not Sent In Time<br \/>\n<\/h4>\n<p>\nThis implemenation is based on the function sending the data being an irq which copies all of the data to send in a single irq&nbsp;call and the function filling the data buffers being non irq and ensuring the operation is irq safe.\n<\/p>\n<p>\nIf the sending function isn&#39;t called in time oldest data is overwritten with new data.\n<\/p>\n<pre>\r\n<code>\r\n#define LIVE_READINGS_NUM_OF_BUFFERS\t\t6\r\n#define\tLIVE_READINGS_BUFFER_LENGTH\t\t\t100\r\n\r\nint live_readings_next_buffer = 0;\t\t\t\t\t\/\/The next buffer to load with data\r\nvolatile int live_readings_last_buffer = 0;\t\t\t\/\/The last (oldest) buffer waiting to be sent\r\nBYTE live_reading_buffers[LIVE_READINGS_NUM_OF_BUFFERS][LIVE_READINGS_BUFFER_LENGTH];\r\n<\/code><\/pre>\n<p>\n&nbsp;\n<\/p>\n<pre>\r\n<code>\r\n\t\/\/----- THE IRQ SENDING THE DATA -----\r\n\t\/\/It wants to move the last_buffer on to ultimately meet the next_buffer\r\n\tif (live_readings_next_buffer == live_readings_last_buffer)\r\n\t{\r\n\t\t\/\/Nothing to send\r\n\t}\r\n\telse\r\n\t{\r\n\t\t\/\/Send last_buffer and then increment last_buffer\r\n\t\t\/\/Send it (or copy it before leaving the irq)\r\n\t\tp_buffer = &amp;live_reading_buffers[live_readings_last_buffer][0];\r\n\t\t\/\/Read the buffer data here...\r\n\r\n\t\tlive_readings_last_buffer++;\r\n\t\tif (live_readings_last_buffer &gt;= LIVE_READINGS_NUM_OF_BUFFERS)\r\n\t\t\tlive_readings_last_buffer = 0;\r\n\t}\r\n\r\n\t\r\n\t\/\/----- THE DATA COLLECTION FUNCTION FILLING THE BUFFER -----\r\n\t\/\/It wants to fill the buffer with new data, discarding the oldest data if necessary\r\n\t\/\/It fills next_buffer and then increments next_buffer\r\n\t\/\/If there is data waiting to be sent it does the same, but increments last_buffer if it = next_buffer  (there will always be 1 unused buffer when data is waiting)\r\n\tDISABLE_INT;\r\n\tp_buffer = &amp;live_reading_buffers[live_readings_next_buffer][0];\r\n\t\/\/Load the buffer here...\r\n\r\n\tlive_readings_next_buffer++;\r\n\tif (live_readings_next_buffer &gt;= LIVE_READINGS_NUM_OF_BUFFERS)\r\n\t\tlive_readings_next_buffer = 0;\r\n\r\n\tif (live_readings_next_buffer == live_readings_last_buffer)\r\n\t{\r\n\t\t\/\/We are overwriting the last buffer as its not been sent in time\r\n\t\tlive_readings_last_buffer++;\r\n\t\tif (live_readings_last_buffer &gt;= LIVE_READINGS_NUM_OF_BUFFERS)\r\n\t\t\tlive_readings_last_buffer = 0;\r\n\t}\r\n\tENABLE_INT;\r\n<\/code><\/pre>\n<p>\n&nbsp;\n<\/p>\n<p>\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Example Of Non Irq Function Fills Buffers and IRQ Function Empties Buffers This implemenation is based on the function sending the data being an irq which sends bits of the data irq&nbsp;calls and the function filling the data buffers being non irq and ensuring the operation is irq safe. #define FILE_DATA_NUM_OF_BUFFERS 4 #define FILE_DATA_BUFFER_LENGTH 512 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-640","post","type-post","status-publish","format-standard","hentry","category-memory"],"_links":{"self":[{"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/posts\/640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/comments?post=640"}],"version-history":[{"count":11,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/posts\/640\/revisions"}],"predecessor-version":[{"id":691,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/posts\/640\/revisions\/691"}],"wp:attachment":[{"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/media?parent=640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/categories?post=640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibex.tech\/c\/wp-json\/wp\/v2\/tags?post=640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}